Skip to content

Commit ef56f4b

Browse files
authored
[flang][OpenMP] Fix reduction of arrays with non-default lower bounds (#132228)
Using LoopNest's indices with ShapeShifts that have non-default lower bounds results in accesses to incorrect array elements. To avoid having to adjust each index, a ShapeShift with default lower bounds can be used instead. Fixes #131751
1 parent 4fa5ab3 commit ef56f4b

17 files changed

+169
-65
lines changed

flang/lib/Lower/OpenMP/PrivateReductionUtils.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,9 @@ static void createCleanupRegion(Fortran::lower::AbstractConverter &converter,
122122
typeError();
123123
}
124124

125-
fir::ShapeShiftOp
126-
Fortran::lower::omp::getShapeShift(fir::FirOpBuilder &builder,
127-
mlir::Location loc, mlir::Value box,
128-
bool cannotHaveNonDefaultLowerBounds) {
125+
fir::ShapeShiftOp Fortran::lower::omp::getShapeShift(
126+
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value box,
127+
bool cannotHaveNonDefaultLowerBounds, bool useDefaultLowerBounds) {
129128
fir::SequenceType sequenceType = mlir::cast<fir::SequenceType>(
130129
hlfir::getFortranElementOrSequenceType(box.getType()));
131130
const unsigned rank = sequenceType.getDimension();
@@ -134,15 +133,24 @@ Fortran::lower::omp::getShapeShift(fir::FirOpBuilder &builder,
134133
lbAndExtents.reserve(rank * 2);
135134
mlir::Type idxTy = builder.getIndexType();
136135

137-
if (cannotHaveNonDefaultLowerBounds && !sequenceType.hasDynamicExtents()) {
136+
mlir::Value oneVal;
137+
auto one = [&] {
138+
if (!oneVal)
139+
oneVal = builder.createIntegerConstant(loc, idxTy, 1);
140+
return oneVal;
141+
};
142+
143+
if ((cannotHaveNonDefaultLowerBounds || useDefaultLowerBounds) &&
144+
!sequenceType.hasDynamicExtents()) {
138145
// We don't need fir::BoxDimsOp if all of the extents are statically known
139146
// and we can assume default lower bounds. This helps avoids reads from the
140147
// mold arg.
141-
mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
148+
// We may also want to use default lower bounds to iterate through array
149+
// elements without having to adjust each index.
142150
for (int64_t extent : sequenceType.getShape()) {
143151
assert(extent != sequenceType.getUnknownExtent());
152+
lbAndExtents.push_back(one());
144153
mlir::Value extentVal = builder.createIntegerConstant(loc, idxTy, extent);
145-
lbAndExtents.push_back(one);
146154
lbAndExtents.push_back(extentVal);
147155
}
148156
} else {
@@ -153,7 +161,8 @@ Fortran::lower::omp::getShapeShift(fir::FirOpBuilder &builder,
153161
mlir::Value dim = builder.createIntegerConstant(loc, idxTy, i);
154162
auto dimInfo =
155163
builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dim);
156-
lbAndExtents.push_back(dimInfo.getLowerBound());
164+
lbAndExtents.push_back(useDefaultLowerBounds ? one()
165+
: dimInfo.getLowerBound());
157166
lbAndExtents.push_back(dimInfo.getExtent());
158167
}
159168
}

flang/lib/Lower/OpenMP/PrivateReductionUtils.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,15 @@ void populateByRefInitAndCleanupRegions(
5959
bool cannotHaveNonDefaultLowerBounds = false);
6060

6161
/// Generate a fir::ShapeShift op describing the provided boxed array.
62+
/// `cannotHaveNonDefaultLowerBounds` should be set if `box` is known to have
63+
/// default lower bounds. This can improve code generation.
64+
/// `useDefaultLowerBounds` can be set to force the returned fir::ShapeShiftOp
65+
/// to have default lower bounds, which is useful to iterate through array
66+
/// elements without having to adjust each index.
6267
fir::ShapeShiftOp getShapeShift(fir::FirOpBuilder &builder, mlir::Location loc,
6368
mlir::Value box,
64-
bool cannotHaveNonDefaultLowerBounds = false);
69+
bool cannotHaveNonDefaultLowerBounds = false,
70+
bool useDefaultLowerBounds = false);
6571

6672
} // namespace omp
6773
} // namespace lower

flang/lib/Lower/OpenMP/ReductionProcessor.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,12 @@ static void genBoxCombiner(fir::FirOpBuilder &builder, mlir::Location loc,
337337
return;
338338
}
339339

340-
fir::ShapeShiftOp shapeShift = getShapeShift(builder, loc, lhs);
340+
// Get ShapeShift with default lower bounds. This makes it possible to use
341+
// unmodified LoopNest's indices with ArrayCoorOp.
342+
fir::ShapeShiftOp shapeShift =
343+
getShapeShift(builder, loc, lhs,
344+
/*cannotHaveNonDefaultLowerBounds=*/false,
345+
/*useDefaultLowerBounds=*/true);
341346

342347
// Iterate over array elements, applying the equivalent scalar reduction:
343348

flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ program reduce
5555
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
5656
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
5757
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
58-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
58+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
59+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
5960
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
6061
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
6162
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>

flang/test/Lower/OpenMP/parallel-reduction-array-lb.f90

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,15 @@ program reduce
3838
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3x2xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<3x2xi32>>>):
3939
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3x2xi32>>>
4040
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<3x2xi32>>>
41-
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
42-
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<3x2xi32>>, index) -> (index, index, index)
43-
! CHECK: %[[VAL_6:.*]] = arith.constant 1 : index
44-
! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_6]] : (!fir.box<!fir.array<3x2xi32>>, index) -> (index, index, index)
45-
! CHECK: %[[VAL_8:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1, %[[VAL_7]]#0, %[[VAL_7]]#1 : (index, index, index, index) -> !fir.shapeshift<2>
46-
! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index
47-
! CHECK: fir.do_loop %[[VAL_10:.*]] = %[[VAL_9]] to %[[VAL_7]]#1 step %[[VAL_9]] unordered {
48-
! CHECK: fir.do_loop %[[VAL_11:.*]] = %[[VAL_9]] to %[[VAL_5]]#1 step %[[VAL_9]] unordered {
49-
! CHECK: %[[VAL_12:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_8]]) %[[VAL_11]], %[[VAL_10]] : (!fir.box<!fir.array<3x2xi32>>, !fir.shapeshift<2>, index, index) -> !fir.ref<i32>
50-
! CHECK: %[[VAL_13:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_8]]) %[[VAL_11]], %[[VAL_10]] : (!fir.box<!fir.array<3x2xi32>>, !fir.shapeshift<2>, index, index) -> !fir.ref<i32>
41+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
42+
! CHECK: %[[C3:.*]] = arith.constant 3 : index
43+
! CHECK: %[[C2:.*]] = arith.constant 2 : index
44+
! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[C1]], %[[C3]], %[[C1]], %[[C2]] : (index, index, index, index) -> !fir.shapeshift<2>
45+
! CHECK: %[[C1_0:.*]] = arith.constant 1 : index
46+
! CHECK: fir.do_loop %[[VAL_10:.*]] = %[[C1_0]] to %[[C2]] step %[[C1_0]] unordered {
47+
! CHECK: fir.do_loop %[[VAL_11:.*]] = %[[C1_0]] to %[[C3]] step %[[C1_0]] unordered {
48+
! CHECK: %[[VAL_12:.*]] = fir.array_coor %[[VAL_2]](%[[SHAPE_SHIFT]]) %[[VAL_11]], %[[VAL_10]] : (!fir.box<!fir.array<3x2xi32>>, !fir.shapeshift<2>, index, index) -> !fir.ref<i32>
49+
! CHECK: %[[VAL_13:.*]] = fir.array_coor %[[VAL_3]](%[[SHAPE_SHIFT]]) %[[VAL_11]], %[[VAL_10]] : (!fir.box<!fir.array<3x2xi32>>, !fir.shapeshift<2>, index, index) -> !fir.ref<i32>
5150
! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_12]] : !fir.ref<i32>
5251
! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
5352
! CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_14]], %[[VAL_15]] : i32

flang/test/Lower/OpenMP/parallel-reduction-array.f90

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ program reduce
3737
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>):
3838
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>>
3939
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<3xi32>>>
40-
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
41-
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<3xi32>>, index) -> (index, index, index)
42-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
43-
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
44-
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
45-
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
46-
! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
40+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
41+
! CHECK: %[[C3:.*]] = arith.constant 3 : index
42+
! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[C1]], %[[C3]] : (index, index) -> !fir.shapeshift<1>
43+
! CHECK: %[[C1_0:.*]] = arith.constant 1 : index
44+
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[C1_0]] to %[[C3]] step %[[C1_0]] unordered {
45+
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[SHAPE_SHIFT]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
46+
! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[SHAPE_SHIFT]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
4747
! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
4848
! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
4949
! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32

flang/test/Lower/OpenMP/parallel-reduction-array2.f90

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ program reduce
3636
! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.array<3xi32>>>):
3737
! CHECK: %[[VAL_2:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.array<3xi32>>>
3838
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<3xi32>>>
39-
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
40-
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<3xi32>>, index) -> (index, index, index)
41-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
42-
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
43-
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
44-
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
45-
! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
39+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
40+
! CHECK: %[[C3:.*]] = arith.constant 3 : index
41+
! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[C1]], %[[C3]] : (index, index) -> !fir.shapeshift<1>
42+
! CHECK: %[[C1_0:.*]] = arith.constant 1 : index
43+
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[C1_0]] to %[[C3]] step %[[C1_0]] unordered {
44+
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[SHAPE_SHIFT]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
45+
! CHECK: %[[VAL_10:.*]] = fir.array_coor %[[VAL_3]](%[[SHAPE_SHIFT]]) %[[VAL_8]] : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
4646
! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
4747
! CHECK: %[[VAL_12:.*]] = fir.load %[[VAL_10]] : !fir.ref<i32>
4848
! CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32

flang/test/Lower/OpenMP/parallel-reduction-pointer-array.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ program reduce
5656
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
5757
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
5858
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
59-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
59+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
60+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
6061
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
6162
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
6263
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>

flang/test/Lower/OpenMP/parallel-reduction3.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
2828
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
2929
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
30-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
30+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
31+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
3132
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
3233
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
3334
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>

flang/test/Lower/OpenMP/reduction-array-intrinsic.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ subroutine max_array_reduction(l, r)
3535
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?xi32>>>
3636
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
3737
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<?xi32>>, index) -> (index, index, index)
38-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
38+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
39+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
3940
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
4041
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
4142
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>

flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ program reduce15
6969
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
7070
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
7171
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
72-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
72+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
73+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
7374
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
7475
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
7576
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
@@ -130,7 +131,8 @@ program reduce15
130131
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
131132
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
132133
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
133-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
134+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
135+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
134136
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
135137
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
136138
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>

flang/test/Lower/OpenMP/wsloop-reduction-array-assumed-shape.f90

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ subroutine reduce(r)
4848
! CHECK: %[[VAL_3:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?xf64>>>
4949
! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
5050
! CHECK: %[[VAL_5:.*]]:3 = fir.box_dims %[[VAL_2]], %[[VAL_4]] : (!fir.box<!fir.array<?xf64>>, index) -> (index, index, index)
51-
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[VAL_5]]#0, %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
51+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
52+
! CHECK: %[[VAL_6:.*]] = fir.shape_shift %[[C1]], %[[VAL_5]]#1 : (index, index) -> !fir.shapeshift<1>
5253
! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index
5354
! CHECK: fir.do_loop %[[VAL_8:.*]] = %[[VAL_7]] to %[[VAL_5]]#1 step %[[VAL_7]] unordered {
5455
! CHECK: %[[VAL_9:.*]] = fir.array_coor %[[VAL_2]](%[[VAL_6]]) %[[VAL_8]] : (!fir.box<!fir.array<?xf64>>, !fir.shapeshift<1>, index) -> !fir.ref<f64>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
2+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
3+
4+
program reduce
5+
integer a(0:1)
6+
7+
!$omp parallel do reduction(+:a)
8+
do i = 1, 10
9+
a(0) = a(0) + 1
10+
end do
11+
!$omp end parallel do
12+
end program
13+
14+
! CHECK-LABEL: omp.declare_reduction @add_reduction_byref_box_2xi32 : !fir.ref<!fir.box<!fir.array<2xi32>>> alloc {
15+
! CHECK: } combiner {
16+
! CHECK: ^bb0(%[[ARG0:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>, %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.array<2xi32>>>):
17+
! CHECK: %[[ARR0:.*]] = fir.load %[[ARG0]] : !fir.ref<!fir.box<!fir.array<2xi32>>>
18+
! CHECK: %[[ARR1:.*]] = fir.load %[[ARG1]] : !fir.ref<!fir.box<!fir.array<2xi32>>>
19+
! CHECK: %[[C1:.*]] = arith.constant 1 : index
20+
! CHECK: %[[C2:.*]] = arith.constant 2 : index
21+
! CHECK: %[[SHAPE_SHIFT:.*]] = fir.shape_shift %[[C1]], %[[C2]] : (index, index) -> !fir.shapeshift<1>
22+
! CHECK: %[[C1_0:.*]] = arith.constant 1 : index
23+
! CHECK: fir.do_loop %[[ARG2:.*]] = %[[C1_0]] to %[[C2]] step %[[C1_0]] unordered {
24+
! CHECK: %[[COOR0:.*]] = fir.array_coor %[[ARR0]](%[[SHAPE_SHIFT]]) %[[ARG2]] : (!fir.box<!fir.array<2xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
25+
! CHECK: %[[COOR1:.*]] = fir.array_coor %[[ARR1]](%[[SHAPE_SHIFT]]) %[[ARG2]] : (!fir.box<!fir.array<2xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
26+
! CHECK: %[[ELEM0:.*]] = fir.load %[[COOR0]] : !fir.ref<i32>
27+
! CHECK: %[[ELEM1:.*]] = fir.load %[[COOR1]] : !fir.ref<i32>
28+
! CHECK: %[[SUM:.*]] = arith.addi %[[ELEM0]], %[[ELEM1]] : i32
29+
! CHECK: fir.store %[[SUM]] to %[[COOR0]] : !fir.ref<i32>
30+
! CHECK: }
31+
! CHECK: omp.yield(%[[ARG0]] : !fir.ref<!fir.box<!fir.array<2xi32>>>)
32+
! CHECK: }
33+
34+
! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "reduce"} {
35+
! CHECK: omp.wsloop {{.*}} reduction(byref @add_reduction_byref_box_2xi32 %{{.*}} -> %{{.*}} : !fir.ref<!fir.box<!fir.array<2xi32>>>)

0 commit comments

Comments
 (0)