[flang-commits] [flang] 208b4db - [flang][optimize] Use ArraySectionAnalyzer to better handle aliasing sections (#180595)
via flang-commits
flang-commits at lists.llvm.org
Wed Feb 11 07:59:42 PST 2026
Author: Delaram Talaashrafi
Date: 2026-02-11T07:59:38-08:00
New Revision: 208b4dbf122465db894bc0d62f73e802834b170e
URL: https://github.com/llvm/llvm-project/commit/208b4dbf122465db894bc0d62f73e802834b170e
DIFF: https://github.com/llvm/llvm-project/commit/208b4dbf122465db894bc0d62f73e802834b170e.diff
LOG: [flang][optimize] Use ArraySectionAnalyzer to better handle aliasing sections (#180595)
When alias analysis reports potential aliasing between LHS and RHS when
inlining `hlfir.assign`, use `ArraySectionAnalyzer` to determine if the
sections are disjoint or identical, which is safe for element-wise
assignment.
Co-authored-by: Delaram Talaashrafi <dtalaashrafi at rome5.pgi.net>
Added:
Modified:
flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
flang/test/HLFIR/inline-hlfir-assign.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp b/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
index a6a2eb0cb3c37..356552fac249d 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRAssign.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Analysis/AliasAnalysis.h"
+#include "flang/Optimizer/Analysis/ArraySectionAnalyzer.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
@@ -93,14 +94,19 @@ class InlineHLFIRAssignConversion
// and proceed with the inlining.
fir::AliasAnalysis aliasAnalysis;
mlir::AliasResult aliasRes = aliasAnalysis.alias(lhs, rhs);
- // TODO: use areIdenticalOrDisjointSlices() from
- // OptimizedBufferization.cpp to check if we can still do the expansion.
if (!aliasRes.isNo()) {
- LLVM_DEBUG(llvm::dbgs() << "InlineHLFIRAssign:\n"
- << "\tLHS: " << lhs << "\n"
- << "\tRHS: " << rhs << "\n"
- << "\tALIAS: " << aliasRes << "\n");
- return rewriter.notifyMatchFailure(assign, "RHS/LHS may alias");
+ // Alias analysis reports potential aliasing, but we can use
+ // ArraySectionAnalyzer to check if the slices are disjoint
+ // or identical (which is safe for element-wise assignment).
+ fir::ArraySectionAnalyzer::SlicesOverlapKind overlap =
+ fir::ArraySectionAnalyzer::analyze(lhs, rhs);
+ if (overlap == fir::ArraySectionAnalyzer::SlicesOverlapKind::Unknown) {
+ LLVM_DEBUG(llvm::dbgs() << "InlineHLFIRAssign:\n"
+ << "\tLHS: " << lhs << "\n"
+ << "\tRHS: " << rhs << "\n"
+ << "\tALIAS: " << aliasRes << "\n");
+ return rewriter.notifyMatchFailure(assign, "RHS/LHS may alias");
+ }
}
}
diff --git a/flang/test/HLFIR/inline-hlfir-assign.fir b/flang/test/HLFIR/inline-hlfir-assign.fir
index 5f728bf140ea3..797ef6e81946a 100644
--- a/flang/test/HLFIR/inline-hlfir-assign.fir
+++ b/flang/test/HLFIR/inline-hlfir-assign.fir
@@ -407,3 +407,40 @@ func.func @_QMtest_global_shaped_targetPtest() {
}
fir.global @_QMtest_global_shaped_targetEa1 target : !fir.array<100xf32>
fir.global @_QMtest_global_shaped_targetEb1 target : !fir.array<100xf32>
+
+// Test disjoint array sections: a(n+1, :) = a(n, :) for a 2D array
+// The first index
diff ers by 1 (n vs n+1), so ArraySectionAnalyzer detects them as disjoint.
+func.func @_QPtest_disjoint(%arg0: !fir.ref<!fir.array<10x10xf32>>) {
+ %c1 = arith.constant 1 : index
+ %c10 = arith.constant 10 : index
+ %0 = fir.shape %c10, %c10 : (index, index) -> !fir.shape<2>
+ %1:2 = hlfir.declare %arg0(%0) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEa"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
+ %2 = fir.alloca index
+ %n = fir.load %2 : !fir.ref<index>
+ %n_plus_1 = arith.addi %n, %c1 : index
+ %3 = fir.shape %c10 : (index) -> !fir.shape<1>
+ %4 = hlfir.designate %1#0 (%n, %c1:%c10:%c1) shape %3 : (!fir.ref<!fir.array<10x10xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ %5 = hlfir.designate %1#0 (%n_plus_1, %c1:%c10:%c1) shape %3 : (!fir.ref<!fir.array<10x10xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+ hlfir.assign %4 to %5 : !fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>
+ return
+}
+// CHECK-LABEL: func.func @_QPtest_disjoint(
+// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x10xf32>>) {
+// CHECK: %[[VAL_1:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_2:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_2]], %[[VAL_2]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_3]]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEa"} : (!fir.ref<!fir.array<10x10xf32>>, !fir.shape<2>) -> (!fir.ref<!fir.array<10x10xf32>>, !fir.ref<!fir.array<10x10xf32>>)
+// CHECK: %[[VAL_5:.*]] = fir.alloca index
+// CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_5]] : !fir.ref<index>
+// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_6]], %[[VAL_1]] : index
+// CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_9:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_6]], %[[VAL_1]]:%[[VAL_2]]:%[[VAL_1]]) shape %[[VAL_8]] : (!fir.ref<!fir.array<10x10xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+// CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_7]], %[[VAL_1]]:%[[VAL_2]]:%[[VAL_1]]) shape %[[VAL_8]] : (!fir.ref<!fir.array<10x10xf32>>, index, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
+// CHECK: fir.do_loop %[[VAL_11:.*]] = %[[VAL_1]] to %[[VAL_2]] step %[[VAL_1]] unordered {
+// CHECK: %[[VAL_12:.*]] = hlfir.designate %[[VAL_9]] (%[[VAL_11]]) : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+// CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_12]] : !fir.ref<f32>
+// CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_10]] (%[[VAL_11]]) : (!fir.ref<!fir.array<10xf32>>, index) -> !fir.ref<f32>
+// CHECK: hlfir.assign %[[VAL_13]] to %[[VAL_14]] : f32, !fir.ref<f32>
+// CHECK: }
+// CHECK: return
+// CHECK: }
More information about the flang-commits
mailing list