[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.
This commit is contained in:
parent
8af44b7867
commit
c6d770fece
@ -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);
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user