Skip to content

Commit 283c2e8

Browse files
authored
[flang][semantics] fix issue with equality of min/max in module files (#145824)
Convert all binary calls of min/max to extremum operations, so that extremums generated by the compiler compare equal, and user min/max calls also compare equal. Fixes #133646 Originally opened as #144162 but I accidentally pushed a merge in such a way that a bunch of code owners got added to the review. This is just rebasing the original work on main and fixing the failing tests.
1 parent e25db2f commit 283c2e8

10 files changed

+167
-91
lines changed

flang/include/flang/Evaluate/tools.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,6 +1510,16 @@ Operator OperationCode(
15101510
}
15111511
}
15121512

1513+
template <typename T, typename... Ts>
1514+
Operator OperationCode(
1515+
const evaluate::Operation<evaluate::Extremum<T>, Ts...> &op) {
1516+
if (op.derived().ordering == evaluate::Ordering::Greater) {
1517+
return Operator::Max;
1518+
} else {
1519+
return Operator::Min;
1520+
}
1521+
}
1522+
15131523
template <typename T> Operator OperationCode(const evaluate::Constant<T> &x) {
15141524
return Operator::Constant;
15151525
}

flang/lib/Evaluate/fold-implementation.h

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,49 +1102,85 @@ template <typename T> Expr<T> Folder<T>::TRANSFER(FunctionRef<T> &&funcRef) {
11021102
}
11031103
}
11041104

1105+
// TODO: Once the backend supports character extremums we could support
1106+
// min/max with non-optional arguments to trees of extremum operations.
11051107
template <typename T>
11061108
Expr<T> FoldMINorMAX(
11071109
FoldingContext &context, FunctionRef<T> &&funcRef, Ordering order) {
11081110
static_assert(T::category == TypeCategory::Integer ||
11091111
T::category == TypeCategory::Unsigned ||
11101112
T::category == TypeCategory::Real ||
11111113
T::category == TypeCategory::Character);
1114+
1115+
// Lots of constraints:
1116+
// - We want Extremum<T> generated by semantics to compare equal to
1117+
// Extremum<T> written out to module files as max or min calls.
1118+
// - Users can also write min/max calls that must also compare equal
1119+
// to min/max calls that wind up being written to module files.
1120+
// - Extremeum<T> is binary and can't currently handle processing
1121+
// optional arguments that may show up in 3rd + argument.
1122+
// - The code below only accepts more than 2 arguments if all the
1123+
// arguments are constant (and hence known to be present).
1124+
// - ConvertExprToHLFIR can't currently handle Extremum<Character>
1125+
// - Semantics doesn't currently generate Extremum<Character>
1126+
// The original code did the folding of arguments and the overall extremum
1127+
// operation in a single pass. This was shorter code-wise, but took me
1128+
// a while to tease out all the logic and was doing redundant work.
1129+
// So I split it into two passes:
1130+
// 1) fold the arguments and check if they are constant,
1131+
// 2) Decide if we:
1132+
// - can constant-fold the min/max operation, or
1133+
// - need to generate an extremum anyway,
1134+
// and do it if so.
1135+
// Otherwise, return the original call.
11121136
auto &args{funcRef.arguments()};
1113-
bool ok{true};
1114-
std::optional<Expr<T>> result;
1115-
Folder<T> folder{context};
1116-
for (std::optional<ActualArgument> &arg : args) {
1117-
// Call Folding on all arguments to make operand promotion explicit.
1118-
if (!folder.Folding(arg)) {
1119-
// TODO: Lowering can't handle having every FunctionRef for max and min
1120-
// being converted into Extremum<T>. That needs fixing. Until that
1121-
// is corrected, however, it is important that max and min references
1122-
// in module files be converted into Extremum<T> even when not constant;
1123-
// the Extremum<SubscriptInteger> operations created to normalize the
1124-
// values of array bounds are formatted as max operations in the
1125-
// declarations in modules, and need to be read back in as such in
1126-
// order for expression comparison to not produce false inequalities
1127-
// when checking function results for procedure interface compatibility.
1128-
if (!context.moduleFileName()) {
1129-
ok = false;
1137+
std::size_t nargs{args.size()};
1138+
bool allArgsConstant{true};
1139+
bool extremumAnyway{nargs == 2 && T::category != TypeCategory::Character};
1140+
// 1a)Fold the first two arguments.
1141+
{
1142+
Folder<T> folder{context, /*forOptionalArgument=*/false};
1143+
if (!folder.Folding(args[0])) {
1144+
allArgsConstant = false;
1145+
}
1146+
if (!folder.Folding(args[1])) {
1147+
allArgsConstant = false;
1148+
}
1149+
}
1150+
// 1b) Fold any optional arguments.
1151+
if (nargs > 2) {
1152+
Folder<T> folder{context, /*forOptionalArgument=*/true};
1153+
for (std::size_t i{2}; i < nargs; ++i) {
1154+
if (args[i]) {
1155+
if (!folder.Folding(args[i])) {
1156+
allArgsConstant = false;
1157+
}
11301158
}
11311159
}
1132-
Expr<SomeType> *argExpr{arg ? arg->UnwrapExpr() : nullptr};
1133-
if (argExpr) {
1134-
*argExpr = Fold(context, std::move(*argExpr));
1135-
}
1136-
if (Expr<T> * tExpr{UnwrapExpr<Expr<T>>(argExpr)}) {
1137-
if (result) {
1138-
result = FoldOperation(
1139-
context, Extremum<T>{order, std::move(*result), Expr<T>{*tExpr}});
1140-
} else {
1141-
result = Expr<T>{*tExpr};
1160+
}
1161+
// 2) If we can fold the result or the call to min/max may compare equal to
1162+
// an extremum generated by semantics go ahead and convert to an extremum,
1163+
// and try to fold the result.
1164+
if (allArgsConstant || extremumAnyway) {
1165+
// Folding updates the argument expressions in place, no need to call
1166+
// Fold() on each argument again.
1167+
if (const auto *resultp{UnwrapExpr<Expr<T>>(args[0])}) {
1168+
Expr<T> result{*resultp};
1169+
for (std::size_t i{1}; i < nargs; ++i) {
1170+
if (const auto *tExpr{UnwrapExpr<Expr<T>>(args[i])}) {
1171+
result = FoldOperation(
1172+
context, Extremum<T>{order, std::move(result), *tExpr});
1173+
} else {
1174+
// This should never happen, but here is a value to return.
1175+
return Expr<T>{std::move(funcRef)};
1176+
}
11421177
}
1143-
} else {
1144-
ok = false;
1178+
return result;
11451179
}
11461180
}
1147-
return ok && result ? std::move(*result) : Expr<T>{std::move(funcRef)};
1181+
// If we decided to not generate an extremum just return the original call,
1182+
// with the arguments folded.
1183+
return Expr<T>{std::move(funcRef)};
11481184
}
11491185

11501186
// For AMAX0, AMIN0, AMAX1, AMIN1, DMAX1, DMIN1, MAX0, MIN0, MAX1, and MIN1

flang/test/Lower/HLFIR/custom-intrinsic.f90

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ function max_array(a, b)
115115
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]](%[[VAL_10]]) {uniq_name = "_QFmax_arrayEmax_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
116116
! CHECK: %[[VAL_12:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
117117
! CHECK: ^bb0(%[[VAL_13:.*]]: index):
118-
! CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
119-
! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
120-
! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
121-
! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<i32>
118+
! CHECK-DAG: %[[VAL_14:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
119+
! CHECK-DAG: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
120+
! CHECK-DAG: %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
121+
! CHECK-DAG: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<i32>
122122
! CHECK: %[[VAL_18:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_17]] : i32
123123
! CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_18]], %[[VAL_15]], %[[VAL_17]] : i32
124124
! CHECK: hlfir.yield_element %[[VAL_19]] : i32
@@ -288,10 +288,10 @@ function min_array(a, b)
288288
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]](%[[VAL_10]]) {uniq_name = "_QFmin_arrayEmin_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
289289
! CHECK: %[[VAL_12:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
290290
! CHECK: ^bb0(%[[VAL_13:.*]]: index):
291-
! CHECK: %[[VAL_14:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
292-
! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
293-
! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
294-
! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<i32>
291+
! CHECK-DAG: %[[VAL_14:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
292+
! CHECK-DAG: %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
293+
! CHECK-DAG: %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_13]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
294+
! CHECK-DAG: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<i32>
295295
! CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_17]] : i32
296296
! CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_18]], %[[VAL_15]], %[[VAL_17]] : i32
297297
! CHECK: hlfir.yield_element %[[VAL_19]] : i32

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ subroutine max_array_reduction(l, r)
8282
! CHECK: %[[VAL_16:.*]] = arith.constant 1 : index
8383
! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_15]]#0, %[[VAL_16]] : index
8484
! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_13]], %[[VAL_17]] : index
85-
! CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_8]] (%[[VAL_18]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
86-
! CHECK: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
87-
! CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
88-
! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref<i32>
85+
! CHECK-DAG: %[[VAL_19:.*]] = hlfir.designate %[[VAL_8]] (%[[VAL_18]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
86+
! CHECK-DAG: %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
87+
! CHECK-DAG: %[[VAL_21:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_13]]) : (!fir.box<!fir.array<?xi32>>, index) -> !fir.ref<i32>
88+
! CHECK-DAG: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref<i32>
8989
! CHECK: %[[VAL_23:.*]] = arith.cmpi sgt, %[[VAL_20]], %[[VAL_22]] : i32
9090
! CHECK: %[[VAL_24:.*]] = arith.select %[[VAL_23]], %[[VAL_20]], %[[VAL_22]] : i32
9191
! CHECK: hlfir.yield_element %[[VAL_24]] : i32

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

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -228,27 +228,27 @@ program reduce15
228228
! CHECK: %[[VAL_56:.*]]:2 = hlfir.declare %[[VAL_55]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
229229
! CHECK: %[[VAL_62:.*]]:2 = hlfir.declare %[[VAL_60]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEmaxes"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
230230
! CHECK: hlfir.assign %[[VAL_61]] to %[[VAL_56]]#0 : i32, !fir.ref<i32>
231-
! CHECK: %[[VAL_63:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
232-
! CHECK: %[[VAL_64:.*]] = arith.constant 0 : index
233-
! CHECK: %[[VAL_65:.*]]:3 = fir.box_dims %[[VAL_63]], %[[VAL_64]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
234-
! CHECK: %[[VAL_66:.*]] = fir.shape %[[VAL_65]]#1 : (index) -> !fir.shape<1>
235-
! CHECK: %[[VAL_67:.*]] = fir.load %[[VAL_62]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
231+
! CHECK-DAG: %[[VAL_63:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
232+
! CHECK-DAG: %[[VAL_64:.*]] = arith.constant 0 : index
233+
! CHECK-DAG: %[[VAL_65:.*]]:3 = fir.box_dims %[[VAL_63]], %[[VAL_64]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
234+
! CHECK-DAG: %[[VAL_66:.*]] = fir.shape %[[VAL_65]]#1 : (index) -> !fir.shape<1>
235+
! CHECK-DAG: %[[VAL_67:.*]] = fir.load %[[VAL_62]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
236236
! CHECK: %[[VAL_68:.*]] = hlfir.elemental %[[VAL_66]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
237237
! CHECK: ^bb0(%[[VAL_69:.*]]: index):
238238
! CHECK: %[[VAL_70:.*]] = arith.constant 0 : index
239239
! CHECK: %[[VAL_71:.*]]:3 = fir.box_dims %[[VAL_63]], %[[VAL_70]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
240240
! CHECK: %[[VAL_72:.*]] = arith.constant 1 : index
241241
! CHECK: %[[VAL_73:.*]] = arith.subi %[[VAL_71]]#0, %[[VAL_72]] : index
242242
! CHECK: %[[VAL_74:.*]] = arith.addi %[[VAL_69]], %[[VAL_73]] : index
243-
! CHECK: %[[VAL_75:.*]] = hlfir.designate %[[VAL_63]] (%[[VAL_74]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
244-
! CHECK: %[[VAL_76:.*]] = fir.load %[[VAL_75]] : !fir.ref<i32>
245-
! CHECK: %[[VAL_77:.*]] = arith.constant 0 : index
246-
! CHECK: %[[VAL_78:.*]]:3 = fir.box_dims %[[VAL_67]], %[[VAL_77]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
247-
! CHECK: %[[VAL_79:.*]] = arith.constant 1 : index
248-
! CHECK: %[[VAL_80:.*]] = arith.subi %[[VAL_78]]#0, %[[VAL_79]] : index
249-
! CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_69]], %[[VAL_80]] : index
250-
! CHECK: %[[VAL_82:.*]] = hlfir.designate %[[VAL_67]] (%[[VAL_81]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
251-
! CHECK: %[[VAL_83:.*]] = fir.load %[[VAL_82]] : !fir.ref<i32>
243+
! CHECK-DAG: %[[VAL_75:.*]] = hlfir.designate %[[VAL_63]] (%[[VAL_74]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
244+
! CHECK-DAG: %[[VAL_76:.*]] = fir.load %[[VAL_75]] : !fir.ref<i32>
245+
! CHECK-DAG: %[[VAL_77:.*]] = arith.constant 0 : index
246+
! CHECK-DAG: %[[VAL_78:.*]]:3 = fir.box_dims %[[VAL_67]], %[[VAL_77]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
247+
! CHECK-DAG: %[[VAL_79:.*]] = arith.constant 1 : index
248+
! CHECK-DAG: %[[VAL_80:.*]] = arith.subi %[[VAL_78]]#0, %[[VAL_79]] : index
249+
! CHECK-DAG: %[[VAL_81:.*]] = arith.addi %[[VAL_69]], %[[VAL_80]] : index
250+
! CHECK-DAG: %[[VAL_82:.*]] = hlfir.designate %[[VAL_67]] (%[[VAL_81]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
251+
! CHECK-DAG: %[[VAL_83:.*]] = fir.load %[[VAL_82]] : !fir.ref<i32>
252252
! CHECK: %[[VAL_84:.*]] = arith.cmpi sgt, %[[VAL_76]], %[[VAL_83]] : i32
253253
! CHECK: %[[VAL_85:.*]] = arith.select %[[VAL_84]], %[[VAL_76]], %[[VAL_83]] : i32
254254
! CHECK: hlfir.yield_element %[[VAL_85]] : i32
@@ -269,27 +269,27 @@ program reduce15
269269
! CHECK: %[[VAL_88:.*]]:2 = hlfir.declare %[[VAL_87]] {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
270270
! CHECK: %[[VAL_94:.*]]:2 = hlfir.declare %[[VAL_92]] {fortran_attrs = {{.*}}<allocatable>, uniq_name = "_QFEmins"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)
271271
! CHECK: hlfir.assign %[[VAL_93]] to %[[VAL_88]]#0 : i32, !fir.ref<i32>
272-
! CHECK: %[[VAL_95:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
273-
! CHECK: %[[VAL_96:.*]] = arith.constant 0 : index
274-
! CHECK: %[[VAL_97:.*]]:3 = fir.box_dims %[[VAL_95]], %[[VAL_96]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
275-
! CHECK: %[[VAL_98:.*]] = fir.shape %[[VAL_97]]#1 : (index) -> !fir.shape<1>
276-
! CHECK: %[[VAL_99:.*]] = fir.load %[[VAL_94]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
277-
! CHECK: %[[VAL_100:.*]] = hlfir.elemental %[[VAL_98]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
272+
! CHECK-DAG: %[[VAL_95:.*]] = fir.load %[[VAL_1]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
273+
! CHECK-DAG: %[[VAL_96:.*]] = arith.constant 0 : index
274+
! CHECK-DAG: %[[VAL_97:.*]]:3 = fir.box_dims %[[VAL_95]], %[[VAL_96]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
275+
! CHECK-DAG: %[[VAL_98:.*]] = fir.shape %[[VAL_97]]#1 : (index) -> !fir.shape<1>
276+
! CHECK-DAG: %[[VAL_99:.*]] = fir.load %[[VAL_94]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
277+
! CHECK-DAG: %[[VAL_100:.*]] = hlfir.elemental %[[VAL_98]] unordered : (!fir.shape<1>) -> !hlfir.expr<?xi32> {
278278
! CHECK: ^bb0(%[[VAL_101:.*]]: index):
279279
! CHECK: %[[VAL_102:.*]] = arith.constant 0 : index
280280
! CHECK: %[[VAL_103:.*]]:3 = fir.box_dims %[[VAL_95]], %[[VAL_102]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
281281
! CHECK: %[[VAL_104:.*]] = arith.constant 1 : index
282282
! CHECK: %[[VAL_105:.*]] = arith.subi %[[VAL_103]]#0, %[[VAL_104]] : index
283283
! CHECK: %[[VAL_106:.*]] = arith.addi %[[VAL_101]], %[[VAL_105]] : index
284-
! CHECK: %[[VAL_107:.*]] = hlfir.designate %[[VAL_95]] (%[[VAL_106]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
285-
! CHECK: %[[VAL_108:.*]] = fir.load %[[VAL_107]] : !fir.ref<i32>
286-
! CHECK: %[[VAL_109:.*]] = arith.constant 0 : index
287-
! CHECK: %[[VAL_110:.*]]:3 = fir.box_dims %[[VAL_99]], %[[VAL_109]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
288-
! CHECK: %[[VAL_111:.*]] = arith.constant 1 : index
289-
! CHECK: %[[VAL_112:.*]] = arith.subi %[[VAL_110]]#0, %[[VAL_111]] : index
290-
! CHECK: %[[VAL_113:.*]] = arith.addi %[[VAL_101]], %[[VAL_112]] : index
291-
! CHECK: %[[VAL_114:.*]] = hlfir.designate %[[VAL_99]] (%[[VAL_113]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
292-
! CHECK: %[[VAL_115:.*]] = fir.load %[[VAL_114]] : !fir.ref<i32>
284+
! CHECK-DAG: %[[VAL_107:.*]] = hlfir.designate %[[VAL_95]] (%[[VAL_106]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
285+
! CHECK-DAG: %[[VAL_108:.*]] = fir.load %[[VAL_107]] : !fir.ref<i32>
286+
! CHECK-DAG: %[[VAL_109:.*]] = arith.constant 0 : index
287+
! CHECK-DAG: %[[VAL_110:.*]]:3 = fir.box_dims %[[VAL_99]], %[[VAL_109]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
288+
! CHECK-DAG: %[[VAL_111:.*]] = arith.constant 1 : index
289+
! CHECK-DAG: %[[VAL_112:.*]] = arith.subi %[[VAL_110]]#0, %[[VAL_111]] : index
290+
! CHECK-DAG: %[[VAL_113:.*]] = arith.addi %[[VAL_101]], %[[VAL_112]] : index
291+
! CHECK-DAG: %[[VAL_114:.*]] = hlfir.designate %[[VAL_99]] (%[[VAL_113]]) : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
292+
! CHECK-DAG: %[[VAL_115:.*]] = fir.load %[[VAL_114]] : !fir.ref<i32>
293293
! CHECK: %[[VAL_116:.*]] = arith.cmpi slt, %[[VAL_108]], %[[VAL_115]] : i32
294294
! CHECK: %[[VAL_117:.*]] = arith.select %[[VAL_116]], %[[VAL_108]], %[[VAL_115]] : i32
295295
! CHECK: hlfir.yield_element %[[VAL_117]] : i32

0 commit comments

Comments
 (0)