[flang-commits] [flang] Reland "[flang][openacc] Prevent SimplifyArrayCoorOp from folding reb… (PR #187626)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Thu Mar 19 20:13:37 PDT 2026
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/187626
…ox used by ACC data entry ops (#187616)"
The SimplifyArrayCoorOp canonicalization pattern folds fir.rebox into fir.array_coor by replacing the rebox result with its source. When the rebox result is the variable of an acc.copyin (or other data entry op), this folding breaks the chain that LegalizeDataValuesInRegion relies on to replace host values with device pointers inside compute regions. With default(none), ACCImplicitData cannot recover the mapping, leaving the rebox source as an illegal live-in in the offload region.
This is causing illegal live-ins at higher optimization levels.
Guard the folding so it bails out when any user of the rebox is an ACC_DATA_ENTRY_OPS.
The buildbots failure were cuased by a missing dependency
>From 4ba0a4c6926b7b79c7975113332344d01acfea7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?=
=?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?=
=?UTF-8?q?=E3=83=B3=29?= <clementval at gmail.com>
Date: Thu, 19 Mar 2026 18:23:26 -0700
Subject: [PATCH] Reland "[flang][openacc] Prevent SimplifyArrayCoorOp from
folding rebox used by ACC data entry ops (#187616)"
The SimplifyArrayCoorOp canonicalization pattern folds fir.rebox into
fir.array_coor by replacing the rebox result with its source. When the
rebox result is the variable of an acc.copyin (or other data entry op),
this folding breaks the chain that LegalizeDataValuesInRegion relies on
to replace host values with device pointers inside compute regions.
With default(none), ACCImplicitData cannot recover the mapping, leaving
the rebox source as an illegal live-in in the offload region.
This is causing illegal live-ins at higher optimization levels.
Guard the folding so it bails out when any user of the rebox is an
ACC_DATA_ENTRY_OPS.
The buildbots failure were cuased by a missing dependency
---
flang/lib/Optimizer/Dialect/CMakeLists.txt | 1 +
flang/lib/Optimizer/Dialect/FIROps.cpp | 10 ++++
.../Fir/array-coor-canonicalization-acc.fir | 48 +++++++++++++++++++
3 files changed, 59 insertions(+)
create mode 100644 flang/test/Fir/array-coor-canonicalization-acc.fir
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt
index f81989a541990..32d66e2d4fc6e 100644
--- a/flang/lib/Optimizer/Dialect/CMakeLists.txt
+++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt
@@ -36,6 +36,7 @@ add_flang_library(FIRDialect
MLIR_LIBS
MLIRArithDialect
+ MLIROpenACCDialect
MLIRBuiltinToLLVMIRTranslation
MLIROpenMPToLLVM
MLIRLLVMToLLVMIRTranslation
diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 0543a624034ca..978120963c514 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -560,6 +560,16 @@ 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 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 (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();
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..5f6b8310a5ab9
--- /dev/null
+++ b/flang/test/Fir/array-coor-canonicalization-acc.fir
@@ -0,0 +1,48 @@
+// 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) -> !fir.ref<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]]
+// 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"}
+ 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"}
+ %3 = fir.array_coor %0 %c1 : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+ return %3 : !fir.ref<f32>
+}
+
+// -----
+
+// 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>
+}
More information about the flang-commits
mailing list