[flang-commits] [flang] [flang][openacc] Prevent SimplifyArrayCoorOp from folding rebox used by ACC data entry ops (PR #187616)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Thu Mar 19 18:09:29 PDT 2026


https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/187616

>From 1749e35c463bb7585e34280d991d580615aa3dc9 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 19 Mar 2026 17:51:47 -0700
Subject: [PATCH 1/2] [flang][openacc] Prevent SimplifyArrayCoorOp from folding
 rebox used by ACC data entry ops

---
 flang/lib/Optimizer/Dialect/FIROps.cpp        |  8 ++++
 .../Fir/array-coor-canonicalization-acc.fir   | 45 +++++++++++++++++++
 2 files changed, 53 insertions(+)
 create mode 100644 flang/test/Fir/array-coor-canonicalization-acc.fir

diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 0543a624034ca..0f14355fcdeae 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -560,6 +560,14 @@ struct SimplifyArrayCoorOp : public mlir::OpRewritePattern<fir::ArrayCoorOp> {
         return mlir::failure();
     } else if (auto reboxOp = mlir::dyn_cast_or_null<fir::ReboxOp>(
                    memref.getDefiningOp())) {
+      // Don't pull in rebox when it is referenced by an ACC data clause.
+      // The data legalization pipeline relies on the rebox result being the
+      // copyin var; folding through it would leave the rebox source as an
+      // unhandled live-in inside the compute region.
+      if (llvm::any_of(memref.getUsers(), [](mlir::Operation *u) {
+            return mlir::isa<ACC_DATA_ENTRY_OPS>(u);
+          }))
+        return mlir::failure();
       boxedMemref = reboxOp.getBox();
       boxedShape = reboxOp.getShape();
       // Avoid pulling in rebox that performs reshaping.
diff --git a/flang/test/Fir/array-coor-canonicalization-acc.fir b/flang/test/Fir/array-coor-canonicalization-acc.fir
new file mode 100644
index 0000000000000..46017355b32fa
--- /dev/null
+++ b/flang/test/Fir/array-coor-canonicalization-acc.fir
@@ -0,0 +1,45 @@
+// RUN: fir-opt --canonicalize --split-input-file %s | FileCheck %s
+
+// Verify that fir.rebox is NOT folded into fir.array_coor when the rebox
+// result is used by an acc.copyin. The data legalization pipeline depends on
+// the copyin's var (the rebox result) matching the value used inside compute
+// regions; folding would break this chain and produce an illegal live-in.
+// CHECK-LABEL:   func.func @test_acc_copyin_preserves_rebox(
+// CHECK-SAME:        %[[BOX:.*]]: !fir.box<!fir.array<?xf32>>,
+// CHECK-SAME:        %[[VAL:.*]]: f32) {
+// CHECK:           %[[C1:.*]] = arith.constant 1 : index
+// CHECK:           %[[REBOX:.*]] = fir.rebox %[[BOX]]
+// CHECK:           %[[COPYIN:.*]] = acc.copyin var(%[[REBOX]]
+// CHECK:           acc.parallel dataOperands(%[[COPYIN]] :
+// CHECK:             %[[COOR:.*]] = fir.array_coor %[[REBOX]] %[[C1]]
+// CHECK:             fir.store %[[VAL]] to %[[COOR]]
+// CHECK:             acc.yield
+// CHECK:           }
+// CHECK:           acc.copyout accVar(%[[COPYIN]]
+func.func @test_acc_copyin_preserves_rebox(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {
+  %c1 = arith.constant 1 : index
+  %0 = fir.rebox %arg0 : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>>
+  %1 = acc.copyin var(%0 : !fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>> {dataClause = #acc<data_clause acc_copy>, name = "array"}
+  acc.parallel dataOperands(%1 : !fir.box<!fir.array<?xf32>>) {
+    %2 = fir.array_coor %0 %c1 : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+    fir.store %arg1 to %2 : !fir.ref<f32>
+    acc.yield
+  } attributes {defaultAttr = #acc<defaultvalue none>}
+  acc.copyout accPtr(%1 : !fir.box<!fir.array<?xf32>>) to varPtr(%0 : !fir.box<!fir.array<?xf32>>) {dataClause = #acc<data_clause acc_copy>, name = "array"}
+  return
+}
+
+// -----
+
+// Same scenario but without acc.copyin: rebox SHOULD be folded normally.
+// CHECK-LABEL:   func.func @test_no_acc_folds_rebox(
+// CHECK-SAME:        %[[BOX:.*]]: !fir.box<!fir.array<?xf32>>) -> !fir.ref<f32> {
+// CHECK:           %[[C1:.*]] = arith.constant 1 : index
+// CHECK:           %[[COOR:.*]] = fir.array_coor %[[BOX]] %[[C1]]
+// CHECK:           return %[[COOR]] : !fir.ref<f32>
+func.func @test_no_acc_folds_rebox(%arg0: !fir.box<!fir.array<?xf32>>) -> !fir.ref<f32> {
+  %c1 = arith.constant 1 : index
+  %0 = fir.rebox %arg0 : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>>
+  %2 = fir.array_coor %0 %c1 : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+  return %2 : !fir.ref<f32>
+}

>From 09a948277ae5a436d74e3edf63484b2395f3d4cf Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 19 Mar 2026 18:08:52 -0700
Subject: [PATCH 2/2] Make sure to only guard array_coord inside acc region

---
 flang/lib/Optimizer/Dialect/FIROps.cpp             | 6 ++++--
 flang/test/Fir/array-coor-canonicalization-acc.fir | 9 ++++++---
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 0f14355fcdeae..978120963c514 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -560,11 +560,13 @@ struct SimplifyArrayCoorOp : public mlir::OpRewritePattern<fir::ArrayCoorOp> {
         return mlir::failure();
     } else if (auto reboxOp = mlir::dyn_cast_or_null<fir::ReboxOp>(
                    memref.getDefiningOp())) {
-      // Don't pull in rebox when it is referenced by an ACC data clause.
+      // Don't pull in rebox when the array_coor is inside an ACC construct
+      // and the rebox result is referenced by an ACC data clause.
       // The data legalization pipeline relies on the rebox result being the
       // copyin var; folding through it would leave the rebox source as an
       // unhandled live-in inside the compute region.
-      if (llvm::any_of(memref.getUsers(), [](mlir::Operation *u) {
+      if (op->getParentOfType<ACC_COMPUTE_AND_DATA_CONSTRUCT_OPS>() &&
+          llvm::any_of(memref.getUsers(), [](mlir::Operation *u) {
             return mlir::isa<ACC_DATA_ENTRY_OPS>(u);
           }))
         return mlir::failure();
diff --git a/flang/test/Fir/array-coor-canonicalization-acc.fir b/flang/test/Fir/array-coor-canonicalization-acc.fir
index 46017355b32fa..5f6b8310a5ab9 100644
--- a/flang/test/Fir/array-coor-canonicalization-acc.fir
+++ b/flang/test/Fir/array-coor-canonicalization-acc.fir
@@ -6,7 +6,7 @@
 // regions; folding would break this chain and produce an illegal live-in.
 // CHECK-LABEL:   func.func @test_acc_copyin_preserves_rebox(
 // CHECK-SAME:        %[[BOX:.*]]: !fir.box<!fir.array<?xf32>>,
-// CHECK-SAME:        %[[VAL:.*]]: f32) {
+// CHECK-SAME:        %[[VAL:.*]]: f32) -> !fir.ref<f32> {
 // CHECK:           %[[C1:.*]] = arith.constant 1 : index
 // CHECK:           %[[REBOX:.*]] = fir.rebox %[[BOX]]
 // CHECK:           %[[COPYIN:.*]] = acc.copyin var(%[[REBOX]]
@@ -16,7 +16,9 @@
 // CHECK:             acc.yield
 // CHECK:           }
 // CHECK:           acc.copyout accVar(%[[COPYIN]]
-func.func @test_acc_copyin_preserves_rebox(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) {
+// CHECK:           %[[COOR_OUT:.*]] = fir.array_coor %[[BOX]] %[[C1]]
+// CHECK:           return %[[COOR_OUT]] : !fir.ref<f32>
+func.func @test_acc_copyin_preserves_rebox(%arg0: !fir.box<!fir.array<?xf32>>, %arg1: f32) -> !fir.ref<f32> {
   %c1 = arith.constant 1 : index
   %0 = fir.rebox %arg0 : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>>
   %1 = acc.copyin var(%0 : !fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.array<?xf32>> {dataClause = #acc<data_clause acc_copy>, name = "array"}
@@ -26,7 +28,8 @@ func.func @test_acc_copyin_preserves_rebox(%arg0: !fir.box<!fir.array<?xf32>>, %
     acc.yield
   } attributes {defaultAttr = #acc<defaultvalue none>}
   acc.copyout accPtr(%1 : !fir.box<!fir.array<?xf32>>) to varPtr(%0 : !fir.box<!fir.array<?xf32>>) {dataClause = #acc<data_clause acc_copy>, name = "array"}
-  return
+  %3 = fir.array_coor %0 %c1 : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+  return %3 : !fir.ref<f32>
 }
 
 // -----



More information about the flang-commits mailing list