[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