[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