[flang-commits] [flang] [flang] Classify MOVE_ALLOC with noncoarray FROM as SIMPLE (PR #224923)
Šárka Holendová via flang-commits
flang-commits at lists.llvm.org
Sun Oct 11 17:32:09 PDT 2026
https://github.com/mlir-maiden updated https://github.com/llvm/llvm-project/pull/224923
>From dd05cd8925f9141d084381a7ff484c5db2975eb0 Mon Sep 17 00:00:00 2001
From: Sarka Holendova <sarka.holendova at gmail.com>
Date: Sun, 20 Sep 2026 08:08:02 -0400
Subject: [PATCH 1/4] [flang] Classify MOVE_ALLOC with noncoarray FROM as
SIMPLE
F2023 16.1(5) classifies MOVE_ALLOC as SIMPLE when its FROM argument is
not a coarray. Implement this conditional classification.
---
flang/lib/Evaluate/intrinsics.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 88874f7ef08e8..39565e2fb2d60 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2876,8 +2876,10 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
}
if (call.isSubroutineCall) {
if (intrinsicClass == IntrinsicClass::pureSubroutine /* MOVE_ALLOC */) {
- // TODO: set Attr::Simple for MOVE_ALLOC when FROM is not a coarray
- // (F2023)
+ // F2023 16.1(5): MOVE_ALLOC with noncoarray FROM is SIMPLE
+ if (!IsCoarray(*rearranged[0])) {
+ attrs.set(characteristics::Procedure::Attr::Simple);
+ }
attrs.set(characteristics::Procedure::Attr::Pure);
} else if (intrinsicClass == IntrinsicClass::simpleSubroutine ||
intrinsicClass == IntrinsicClass::simpleElementalSubroutine) {
>From f57092f80cc8409f0a09e717e9792aae5d29765c Mon Sep 17 00:00:00 2001
From: Sarka Holendova <sarka.holendova at gmail.com>
Date: Fri, 9 Oct 2026 14:56:50 -0700
Subject: [PATCH 2/4] [flang] Update MOVE_ALLOC SIMPLE classification status in
F202X.md
---
flang/docs/F202X.md | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/flang/docs/F202X.md b/flang/docs/F202X.md
index 7d0cf26dbaa2c..160f6f85c5e19 100644
--- a/flang/docs/F202X.md
+++ b/flang/docs/F202X.md
@@ -175,8 +175,14 @@ This makes `SIMPLE` a lower-priority feature.
- `PURE` procedures do not satisfy `SIMPLE` requirements
- `SIMPLE`/`IMPURE` conflicts are diagnosed
- Use-associated `SIMPLE` procedures are correctly recognized
-- Additional `SIMPLE` semantic constraints remain to be implemented
-- Intrinsic procedures are not yet marked as `SIMPLE` (planned as follow-up work)
+- Additional `SIMPLE` semantic constraints remain to be implemented (see #221457)
+- F2023 16.1 p2: All standard intrinsic functions are classified as `SIMPLE`
+- F2023 16.1 p5: `MVBITS`, `SPLIT`, and both forms of `TOKENIZE` are classified
+ as `SIMPLE` intrinsic subroutines
+- F2023 16.1 p5: Conditional `SIMPLE` classification of `MOVE_ALLOC` is
+ implemented when `FROM` is not a coarray
+- Intrinsic module procedures are not yet classified as `SIMPLE`
+- Lowering does not yet propagate the `SIMPLE` attribute to FIR procedure attributes (see #222360)
#### Conditional expressions and actual arguments
>From 0f907dba77a8b0e29eb462ced067bbec949bb4dc Mon Sep 17 00:00:00 2001
From: Sarka Holendova <sarka.holendova at gmail.com>
Date: Fri, 9 Oct 2026 16:21:52 -0700
Subject: [PATCH 3/4] [flang] Correct MOVE_ALLOC PURE classification and add
regression tests
---
flang/lib/Evaluate/intrinsics.cpp | 5 +++--
flang/test/Semantics/doconcurrent01.f90 | 2 ++
flang/test/Semantics/move_alloc_pure.f90 | 13 +++++++++++++
3 files changed, 18 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Semantics/move_alloc_pure.f90
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 39565e2fb2d60..77035f98c5ff1 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2876,11 +2876,12 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
}
if (call.isSubroutineCall) {
if (intrinsicClass == IntrinsicClass::pureSubroutine /* MOVE_ALLOC */) {
- // F2023 16.1(5): MOVE_ALLOC with noncoarray FROM is SIMPLE
+ // F2023 16.9.147 p2: MOVE_ALLOC is simple if and only if FROM is not a
+ // coarray
if (!IsCoarray(*rearranged[0])) {
attrs.set(characteristics::Procedure::Attr::Simple);
+ attrs.set(characteristics::Procedure::Attr::Pure);
}
- attrs.set(characteristics::Procedure::Attr::Pure);
} else if (intrinsicClass == IntrinsicClass::simpleSubroutine ||
intrinsicClass == IntrinsicClass::simpleElementalSubroutine) {
attrs.set(characteristics::Procedure::Attr::Simple);
diff --git a/flang/test/Semantics/doconcurrent01.f90 b/flang/test/Semantics/doconcurrent01.f90
index 827c533795920..55f3cf30bf8f0 100644
--- a/flang/test/Semantics/doconcurrent01.f90
+++ b/flang/test/Semantics/doconcurrent01.f90
@@ -181,11 +181,13 @@ subroutine s6()
do concurrent (i = 1:10)
!ERROR: An image control statement is not allowed in DO CONCURRENT
+!ERROR: Impure procedure 'move_alloc' may not be referenced in DO CONCURRENT
call move_alloc(ca, cb)
end do
do concurrent (i = 1:10)
!ERROR: An image control statement is not allowed in DO CONCURRENT
+!ERROR: Impure procedure 'move_alloc' may not be referenced in DO CONCURRENT
call move_alloc(pvar%type1_field%coarray_type0_field, qvar%type1_field%coarray_type0_field)
end do
end subroutine s6
diff --git a/flang/test/Semantics/move_alloc_pure.f90 b/flang/test/Semantics/move_alloc_pure.f90
new file mode 100644
index 0000000000000..db7e9bbec82f3
--- /dev/null
+++ b/flang/test/Semantics/move_alloc_pure.f90
@@ -0,0 +1,13 @@
+! RUN: %python %S/test_errors.py %s %flang_fc1 -fcoarray
+pure subroutine coarray_from(f, t)
+ integer, allocatable, intent(inout) :: f(:)[:], t(:)[:]
+ !ERROR: Procedure 'move_alloc' referenced in pure subprogram 'coarray_from' must be pure too
+ !ERROR: An image control statement may not appear in a pure subprogram
+ call move_alloc(f, t)
+end subroutine
+
+pure subroutine noncoarray_from(f, t)
+ integer, allocatable, intent(inout) :: f(:)
+ integer, allocatable, intent(out) :: t(:)
+ call move_alloc(f, t)
+end subroutine
>From 7eade160248ed18e49c444db104cfeb426298340 Mon Sep 17 00:00:00 2001
From: Sarka Holendova <sarka.holendova at gmail.com>
Date: Sun, 11 Oct 2026 17:23:52 -0700
Subject: [PATCH 4/4] [flang] Address MOVE_ALLOC review nits
---
flang/docs/F202X.md | 4 ++--
flang/lib/Evaluate/intrinsics.cpp | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/flang/docs/F202X.md b/flang/docs/F202X.md
index 160f6f85c5e19..6c36e86d1d649 100644
--- a/flang/docs/F202X.md
+++ b/flang/docs/F202X.md
@@ -179,8 +179,8 @@ This makes `SIMPLE` a lower-priority feature.
- F2023 16.1 p2: All standard intrinsic functions are classified as `SIMPLE`
- F2023 16.1 p5: `MVBITS`, `SPLIT`, and both forms of `TOKENIZE` are classified
as `SIMPLE` intrinsic subroutines
-- F2023 16.1 p5: Conditional `SIMPLE` classification of `MOVE_ALLOC` is
- implemented when `FROM` is not a coarray
+- F2023 16.1 p5: `MOVE_ALLOC` is classified as `SIMPLE` when `FROM` is
+ not a coarray
- Intrinsic module procedures are not yet classified as `SIMPLE`
- Lowering does not yet propagate the `SIMPLE` attribute to FIR procedure attributes (see #222360)
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index 77035f98c5ff1..a0fe12d750087 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -2878,6 +2878,7 @@ std::optional<SpecificCall> IntrinsicInterface::Match(
if (intrinsicClass == IntrinsicClass::pureSubroutine /* MOVE_ALLOC */) {
// F2023 16.9.147 p2: MOVE_ALLOC is simple if and only if FROM is not a
// coarray
+ // F2023 16.1 p5: No other standard intrinsic subroutine is pure or simple
if (!IsCoarray(*rearranged[0])) {
attrs.set(characteristics::Procedure::Attr::Simple);
attrs.set(characteristics::Procedure::Attr::Pure);
More information about the flang-commits
mailing list