[flang-commits] [flang] [flang] Reclassify MVBITS, SPLIT, and TOKENIZE as SIMPLE (PR #205024)

via flang-commits flang-commits at lists.llvm.org
Sun Jun 21 19:36:20 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-semantics

Author: Šárka Holendová (mlir-maiden)

<details>
<summary>Changes</summary>

F2023 makes MVBITS a simple elemental subroutine and SPLIT/TOKENIZE simple subroutines.

This change:
- adds `simpleSubroutine` and `simpleElementalSubroutine` to `IntrinsicClass`,
- reclassifies the MVBITS, SPLIT, and TOKENIZE intrinsic table entries,
- propagates `SIMPLE` through intrinsic resolution and procedure characteristics.

MOVE_ALLOC is not included in this change.

---
Full diff: https://github.com/llvm/llvm-project/pull/205024.diff


4 Files Affected:

- (modified) flang/include/flang/Evaluate/intrinsics.h (+2-1) 
- (modified) flang/lib/Evaluate/intrinsics.cpp (+11-7) 
- (modified) flang/lib/Semantics/resolve-names.cpp (+7) 
- (added) flang/test/Semantics/simple-intrinsics.f90 (+49) 


``````````diff
diff --git a/flang/include/flang/Evaluate/intrinsics.h b/flang/include/flang/Evaluate/intrinsics.h
index 0d6c513606c19..dfc44d1e45da9 100644
--- a/flang/include/flang/Evaluate/intrinsics.h
+++ b/flang/include/flang/Evaluate/intrinsics.h
@@ -63,7 +63,8 @@ struct SpecificIntrinsicFunctionInterface : public characteristics::Procedure {
 // Generic intrinsic classes from table 16.1
 ENUM_CLASS(IntrinsicClass, atomicSubroutine, collectiveSubroutine,
     elementalFunction, elementalSubroutine, inquiryFunction, pureSubroutine,
-    impureFunction, impureSubroutine, transformationalFunction, noClass)
+    simpleSubroutine, simpleElementalSubroutine, impureFunction,
+    impureSubroutine, transformationalFunction, noClass)
 
 class IntrinsicProcTable {
 private:
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index bc0026746c05c..356e08a512951 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -1708,7 +1708,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
             {"to", SameIntOrUnsigned, Rank::elemental, Optionality::required,
                 common::Intent::Out},
             {"topos", AnyInt}},
-        {}, Rank::elemental, IntrinsicClass::elementalSubroutine},
+        {}, Rank::elemental, IntrinsicClass::simpleElementalSubroutine},
     {"random_init",
         {{"repeatable", AnyLogical, Rank::scalar},
             {"image_distinct", AnyLogical, Rank::scalar}},
@@ -1770,7 +1770,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
                 common::Intent::InOut},
             {"back", AnyLogical, Rank::scalar, Optionality::optional,
                 common::Intent::In}},
-        {}, Rank::elemental, IntrinsicClass::pureSubroutine},
+        {}, Rank::elemental, IntrinsicClass::simpleSubroutine},
     {"tokenize",
         {{"string", SameCharNoLen, Rank::scalar, Optionality::required,
              common::Intent::In},
@@ -1780,7 +1780,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
                 common::Intent::Out},
             {"separator", SameCharNoLen, Rank::vector, Optionality::optional,
                 common::Intent::Out}},
-        {}, Rank::elemental, IntrinsicClass::pureSubroutine},
+        {}, Rank::elemental, IntrinsicClass::simpleSubroutine},
     {"tokenize",
         {{"string", SameCharNoLen, Rank::scalar, Optionality::required,
              common::Intent::In},
@@ -1790,7 +1790,7 @@ static const IntrinsicInterface intrinsicSubroutine[]{
                 common::Intent::Out},
             {"last", AnyInt, Rank::vector, Optionality::required,
                 common::Intent::Out}},
-        {}, Rank::elemental, IntrinsicClass::pureSubroutine},
+        {}, Rank::elemental, IntrinsicClass::simpleSubroutine},
     {"unlink",
         {{"path", DefaultChar, Rank::scalar, Optionality::required,
              common::Intent::In},
@@ -2876,10 +2876,14 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
   if (elementalRank > 0) {
     attrs.set(characteristics::Procedure::Attr::Elemental);
   }
-  // TODO: Mark intrinsic procedures that are SIMPLE per F2023
   if (call.isSubroutineCall) {
-    if (intrinsicClass == IntrinsicClass::pureSubroutine /* MOVE_ALLOC */ ||
-        intrinsicClass == IntrinsicClass::elementalSubroutine /* MVBITS */) {
+    if (intrinsicClass == IntrinsicClass::pureSubroutine /* MOVE_ALLOC */) {
+      // TODO: set Attr::Simple for MOVE_ALLOC when FROM is not a coarray
+      // (F2023)
+      attrs.set(characteristics::Procedure::Attr::Pure);
+    } else if (intrinsicClass == IntrinsicClass::simpleSubroutine ||
+        intrinsicClass == IntrinsicClass::simpleElementalSubroutine) {
+      attrs.set(characteristics::Procedure::Attr::Simple);
       attrs.set(characteristics::Procedure::Attr::Pure);
     }
     return SpecificCall{
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 6d2d0bf24b194..f7cff0b3af046 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -3471,6 +3471,13 @@ void ScopeHandler::AcquireIntrinsicProcedureFlags(Symbol &symbol) {
     SetExplicitAttr(symbol, Attr::ELEMENTAL);
     SetExplicitAttr(symbol, Attr::PURE);
     break;
+  case evaluate::IntrinsicClass::simpleElementalSubroutine:
+    SetExplicitAttr(symbol, Attr::ELEMENTAL);
+    SetExplicitAttr(symbol, Attr::SIMPLE);
+    break;
+  case evaluate::IntrinsicClass::simpleSubroutine:
+    SetExplicitAttr(symbol, Attr::SIMPLE);
+    break;
   case evaluate::IntrinsicClass::impureSubroutine:
     break;
   default:
diff --git a/flang/test/Semantics/simple-intrinsics.f90 b/flang/test/Semantics/simple-intrinsics.f90
new file mode 100644
index 0000000000000..c5f02017f130e
--- /dev/null
+++ b/flang/test/Semantics/simple-intrinsics.f90
@@ -0,0 +1,49 @@
+! RUN: %python %S/test_symbols.py %s %flang_fc1
+! Fortran 2023 classifies MVBITS, SPLIT, and TOKENIZE as SIMPLE
+! intrinsic subroutines. Verify that their symbols resolve with the
+! SIMPLE attribute. MVBITS is also ELEMENTAL.
+
+!DEF: /expect_simple_intrinsics (Subroutine) Subprogram
+!DEF: /expect_simple_intrinsics/string INTENT(IN) ObjectEntity CHARACTER(*,1)
+!DEF: /expect_simple_intrinsics/set INTENT(IN) ObjectEntity CHARACTER(*,1)
+!DEF: /expect_simple_intrinsics/from INTENT(IN) ObjectEntity INTEGER(4)
+!DEF: /expect_simple_intrinsics/to INTENT(INOUT) ObjectEntity INTEGER(4)
+subroutine expect_simple_intrinsics (string, set, from, to)
+ !REF: /expect_simple_intrinsics/string
+ !REF: /expect_simple_intrinsics/set
+ character(len=*), intent(in) :: string, set
+ !REF: /expect_simple_intrinsics/from
+ integer, intent(in) :: from
+ !REF: /expect_simple_intrinsics/to
+ integer, intent(inout) :: to
+ !DEF: /expect_simple_intrinsics/pos ObjectEntity INTEGER(4)
+ integer pos
+ !DEF: /expect_simple_intrinsics/tokens ALLOCATABLE ObjectEntity CHARACTER(:,1)
+ character(len=:), allocatable :: tokens(:)
+ !DEF: /expect_simple_intrinsics/first ALLOCATABLE ObjectEntity INTEGER(4)
+ !DEF: /expect_simple_intrinsics/last ALLOCATABLE ObjectEntity INTEGER(4)
+ integer, allocatable :: first(:), last(:)
+ !REF: /expect_simple_intrinsics/pos
+ pos = 1
+ !DEF: /expect_simple_intrinsics/split INTRINSIC, SIMPLE (Subroutine) ProcEntity
+ !REF: /expect_simple_intrinsics/string
+ !REF: /expect_simple_intrinsics/set
+ !REF: /expect_simple_intrinsics/pos
+ call split(string, set, pos)
+ !DEF: /expect_simple_intrinsics/tokenize INTRINSIC, SIMPLE (Subroutine) ProcEntity
+ !REF: /expect_simple_intrinsics/string
+ !REF: /expect_simple_intrinsics/set
+ !REF: /expect_simple_intrinsics/tokens
+ call tokenize(string, set, tokens)
+ !REF: /expect_simple_intrinsics/tokenize
+ !REF: /expect_simple_intrinsics/string
+ !REF: /expect_simple_intrinsics/set
+ !REF: /expect_simple_intrinsics/first
+ !REF: /expect_simple_intrinsics/last
+ call tokenize(string, set, first, last)
+ !DEF: /expect_simple_intrinsics/mvbits ELEMENTAL, INTRINSIC, SIMPLE (Subroutine) ProcEntity
+ !REF: /expect_simple_intrinsics/from
+ !REF: /expect_simple_intrinsics/to
+ call mvbits(from, 0, 1, to, 2)
+end subroutine
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/205024


More information about the flang-commits mailing list