[flang-commits] [flang] e47f8de - [flang] Fixed FIR AA's getSource() for box loads inside acc.compute_region. (#199157)
via flang-commits
flang-commits at lists.llvm.org
Fri May 22 13:07:37 PDT 2026
Author: Slava Zakharin
Date: 2026-05-22T13:07:32-07:00
New Revision: e47f8de5a2da5df2da84b804b2bdac5b54bfdbc5
URL: https://github.com/llvm/llvm-project/commit/e47f8de5a2da5df2da84b804b2bdac5b54bfdbc5
DIFF: https://github.com/llvm/llvm-project/commit/e47f8de5a2da5df2da84b804b2bdac5b54bfdbc5.diff
LOG: [flang] Fixed FIR AA's getSource() for box loads inside acc.compute_region. (#199157)
This patch fixes a regression caused by #198635: when we call getSource()
for a `fir.load` of a box we have to handle the input value that might be
a `BlockArgument` and pass-through it.
Added:
Modified:
flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
flang/test/Analysis/AliasAnalysis/alias-analysis-acc.mlir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
index 79ced7685bc3a..5e92ed5f42665 100644
--- a/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
+++ b/flang/lib/Optimizer/Analysis/AliasAnalysis.cpp
@@ -976,8 +976,35 @@ ModRefResult AliasAnalysis::getModRef(mlir::Region ®ion,
return result;
}
+/// Walk through any pass-through block-arg<->operand links the analysis
+/// understands, replacing \p v with the corresponding operand at each step,
+/// and return the resulting value. A "pass-through block argument" is one
+/// that does not introduce a new value relative to its corresponding operand
+/// from the standpoint of memory addressing, so walking past it is safe for
+/// alias analysis.
+///
+/// Currently the only handled pass-through link is the
+/// operand<->block-argument mapping of an acc.compute_region.
+static mlir::Value walkBlockArgPassThroughs(mlir::Value v) {
+ while (v) {
+ mlir::Value operand = mlir::acc::getACCOperandForBlockArg(v);
+ if (!operand)
+ break;
+ v = operand;
+ }
+ return v;
+}
+
AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
bool getLastInstantiationPoint) {
+ // If v is a pass-through block argument (see walkBlockArgPassThroughs),
+ // continue from the underlying operand so the tracking loop below has a
+ // defining op to chew on. Without this, a recursive query like the one in
+ // the fir.load (box) branch below would immediately return
+ // SourceKind::Unknown (no defining op and not a function dummy argument),
+ // which then forces SourceKind::Indirect for box loads from such block args
+ // and pessimizes alias analysis.
+ v = walkBlockArgPassThroughs(v);
auto *defOp = v.getDefiningOp();
SourceKind type{SourceKind::Unknown};
mlir::Type ty;
@@ -1414,10 +1441,11 @@ AliasAnalysis::Source AliasAnalysis::getSource(mlir::Value v,
return *accSourceReturn;
if (!breakFromLoop && v) {
- // If we have reached a BlockArgument, try to pass through it
- // for some OpenACC operations.
- if (mlir::Value accOperand = mlir::acc::getACCOperandForBlockArg(v)) {
- v = accOperand;
+ // If we have reached a pass-through block argument, walk past it so
+ // the next loop iteration sees the underlying defining op.
+ mlir::Value newV = walkBlockArgPassThroughs(v);
+ if (newV != v) {
+ v = newV;
defOp = v.getDefiningOp();
}
}
diff --git a/flang/test/Analysis/AliasAnalysis/alias-analysis-acc.mlir b/flang/test/Analysis/AliasAnalysis/alias-analysis-acc.mlir
index 863b404f4bd1f..00971e6263c7a 100644
--- a/flang/test/Analysis/AliasAnalysis/alias-analysis-acc.mlir
+++ b/flang/test/Analysis/AliasAnalysis/alias-analysis-acc.mlir
@@ -563,3 +563,29 @@ func.func @test_acc_routine__0(%arg0: !fir.ref<f32> {fir.bindc_name = "a"}, %arg
} {origin = "acc.routine"}
return
}
+
+// -----
+
+// Test that a fir.load of a box descriptor through an acc.compute_region
+// block argument still resolves to its dummy-argument source. Without the
+// pass-through, the recursive getSource() on the memref of the load would
+// return SourceKind::Unknown for the block argument, forcing the load itself
+// to be classified as SourceKind::Indirect and pessimizing alias analysis
+// to MayAlias for two unrelated allocatable dummy arguments.
+// CHECK-LABEL: Testing : "test_acc_compute_region_box_load"
+// CHECK-DAG: load_x#0 <-> load_y#0: NoAlias
+func.func @test_acc_compute_region_box_load(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {fir.bindc_name = "y"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %dx = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtestEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %dy = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtestEy"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %cx = acc.copyin varPtr(%dx : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {dataClause = #acc<data_clause acc_copy>, implicit = true, name = "x"}
+ %cy = acc.copyin varPtr(%dy : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {dataClause = #acc<data_clause acc_copy>, implicit = true, name = "y"}
+ acc.kernel_environment dataOperands(%cx, %cy : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+ acc.compute_region ins(%arg2 = %cx, %arg3 = %cy) : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
+ %lx = fir.load %arg2 {test.ptr = "load_x"} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %ly = fir.load %arg3 {test.ptr = "load_y"} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ acc.yield
+ } {origin = "acc.kernels"}
+ }
+ return
+}
More information about the flang-commits
mailing list