[flang-commits] [flang] c6d770f - [flang] Fix FIRToMemRef index computation for array_coor with slice and shape_shift (#189496)

via flang-commits flang-commits at lists.llvm.org
Tue Mar 31 12:09:52 PDT 2026


Author: khaki3
Date: 2026-03-31T12:09:43-07:00
New Revision: c6d770fece415d7e8a55dcd495fd24862b3b1ca6

URL: https://github.com/llvm/llvm-project/commit/c6d770fece415d7e8a55dcd495fd24862b3b1ca6
DIFF: https://github.com/llvm/llvm-project/commit/c6d770fece415d7e8a55dcd495fd24862b3b1ca6.diff

LOG: [flang] Fix FIRToMemRef index computation for array_coor with slice and shape_shift (#189496)

Use shift instead of sliceLb only when the array_coor has an explicit
slice (indicesAreFortran case). When the slice comes from an embox,
the indices are 1-based section indices and must subtract 1.

Added: 
    

Modified: 
    flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
    flang/test/Transforms/FIRToMemRef/array-coor-slice-shift.mlir

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
index 3b0b4bc007e61..4f8c8582fb0e2 100644
--- a/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
+++ b/flang/lib/Optimizer/Transforms/FIRToMemRef.cpp
@@ -485,15 +485,16 @@ FIRToMemRef::getMemrefIndices(fir::ArrayCoorOp arrayCoorOp, Operation *memref,
     Value sliceLb = isSliced ? sliceLbs[i] : shift;
 
     // When the array_coor has an explicit slice with a shape_shift (i.e.
-    // non-default lower bounds), the indices are Fortran indices; subtract
-    // the slice lower bound to get 0-based memref indices. Otherwise (the
-    // slice comes from an embox, or the shape has no shift), the indices
-    // are 1-based section indices; subtract 1.
+    // non-default lower bounds), the indices are in the shape_shift
+    // coordinate space; subtract the lower bound (shift) to get 0-based
+    // memref indices. Otherwise (the slice comes from an embox, or the
+    // shape has no shift), the indices are 1-based section indices;
+    // subtract 1.
     bool indicesAreFortran = isShifted && arrayCoorOp.getSlice() != nullptr;
     Value indexAdjustment =
         (isSliced && !indicesAreFortran)
             ? arith::ConstantIndexOp::create(rewriter, loc, 1)
-            : sliceLb;
+            : shift;
     Value delta = arith::SubIOp::create(rewriter, loc, index, indexAdjustment);
 
     Value scaled = arith::MulIOp::create(rewriter, loc, delta, stride);

diff  --git a/flang/test/Transforms/FIRToMemRef/array-coor-slice-shift.mlir b/flang/test/Transforms/FIRToMemRef/array-coor-slice-shift.mlir
index f1fb23e0ff9fd..22b69a3fa9e60 100644
--- a/flang/test/Transforms/FIRToMemRef/array-coor-slice-shift.mlir
+++ b/flang/test/Transforms/FIRToMemRef/array-coor-slice-shift.mlir
@@ -1,8 +1,5 @@
 // Verify fir.array_coor with explicit shape_shift and slice correctly
-// computes 0-based memref indices when lower bounds are non-default.
-// This pattern arises after inlining canonicalizes fir.embox+fir.array_coor
-// into a single fir.array_coor with explicit shape and slice operands,
-// where the indices become Fortran indices rather than 1-based section indices.
+// computes 0-based memref indices.
 //
 // RUN: fir-opt %s --fir-to-memref --allow-unregistered-dialect | FileCheck %s
 
@@ -47,3 +44,33 @@ func.func @array_coor_slice_shift_2d() {
   fir.store %c1_i32 to %4 : !fir.ref<i32>
   return
 }
+
+// A(1:6, 1:9) with section A(:, 2:4).  (default lb=1, slice starts at 2)
+// Index (1, 1) = lower bounds => memref indices must be (1, 0).
+// The slice offset for dim 2 (sliceLb=2, shift=1 => offset=1) must be
+// preserved, not cancelled out.
+// CHECK-LABEL: func.func @array_coor_slice_shift_section
+// CHECK:       %[[C1:.*]] = arith.constant 1 : index
+// CHECK:       %[[C2:.*]] = arith.constant 2 : index
+// The dim 2 offset = sliceLb - shift = 2 - 1 = 1:
+// CHECK:       arith.subi %[[C2]], %[[C1]] : index
+// CHECK:       memref.store
+// CHECK-NOT:   fir.array_coor
+func.func @array_coor_slice_shift_section() {
+  %c1 = arith.constant 1 : index
+  %c2 = arith.constant 2 : index
+  %c4 = arith.constant 4 : index
+  %c6 = arith.constant 6 : index
+  %c9 = arith.constant 9 : index
+  %c1_i32 = arith.constant 1 : i32
+  %0 = fir.alloca !fir.array<6x9xi32> {bindc_name = "a", uniq_name = "_QFEa"}
+  %1 = fir.shape_shift %c1, %c6, %c1, %c9 : (index, index, index, index) -> !fir.shapeshift<2>
+  %2 = fir.declare %0(%1) {uniq_name = "_QFEa"} : (!fir.ref<!fir.array<6x9xi32>>, !fir.shapeshift<2>) -> !fir.ref<!fir.array<6x9xi32>>
+  // Slice: full range in dim 1, section 2:4 in dim 2.
+  %3 = fir.slice %c1, %c6, %c1, %c2, %c4, %c1 : (index, index, index, index, index, index) -> !fir.slice<2>
+  // Index (1, 1) in shape_shift space. Dim 2 slice starts at 2,
+  // so memref index for dim 2 must be (1-1)+(2-1) = 1, not 0.
+  %4 = fir.array_coor %2(%1) [%3] %c1, %c1 : (!fir.ref<!fir.array<6x9xi32>>, !fir.shapeshift<2>, !fir.slice<2>, index, index) -> !fir.ref<i32>
+  fir.store %c1_i32 to %4 : !fir.ref<i32>
+  return
+}


        


More information about the flang-commits mailing list