[flang-commits] [flang] db7b665 - [flang][hlfir] support dynamically optional array arguments to intrinsics with custom handling
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Tue Jul 18 04:04:39 PDT 2023
Author: Tom Eccles
Date: 2023-07-18T11:03:35Z
New Revision: db7b665c5c7136d21665555916785129460b5860
URL: https://github.com/llvm/llvm-project/commit/db7b665c5c7136d21665555916785129460b5860
DIFF: https://github.com/llvm/llvm-project/commit/db7b665c5c7136d21665555916785129460b5860.diff
LOG: [flang][hlfir] support dynamically optional array arguments to intrinsics with custom handling
The previous code path created the elemental kernel by generating a
scalar intrinsic call using pre-prepared arguments using genIntrinsicRefCore,
which then generated the intrinsic call using genIntrinsicCall().
The problem with this approach was that the dynamically optional
arguments were marked as having no argLowering, which meant that they
were unconditionally passed by value without any check to see if they
were present.
It would be nice to put an if operation in the path for !argLowering,
doing something similar to genOptionalValue(). However, this can't be
done because it isn't clear what value should be used for the default.
If zero was used (like in genOptionalValue) this could effect the result
of MIN or MAX.
Instead, this patch re-uses the implementation for scalar dynamically
optional arguments (in non-elemental calls). This does the correct
thing, entirely ignoring absent optional arguments.
Depends On: D155292
Differential Revision: https://reviews.llvm.org/D155293
Added:
Modified:
flang/lib/Lower/ConvertCall.cpp
flang/test/Lower/HLFIR/custom-intrinsic.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index ec2c8ab737d97d..f7d37f793e3694 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1272,6 +1272,52 @@ static ExvAndCleanup genOptionalBox(fir::FirOpBuilder &builder,
return {fir::BoxValue(boxOrAbsent), cleanup};
}
+/// Lower calls to intrinsic procedures with custom optional handling where the
+/// actual arguments have been pre-lowered
+static std::optional<hlfir::EntityWithAttributes> genCustomIntrinsicRefCore(
+ Fortran::lower::PreparedActualArguments &loweredActuals,
+ const Fortran::evaluate::SpecificIntrinsic *intrinsic,
+ CallContext &callContext) {
+ auto &converter = callContext.converter;
+ auto &builder = callContext.getBuilder();
+ const auto &loc = callContext.loc;
+ assert(intrinsic && Fortran::lower::intrinsicRequiresCustomOptionalHandling(
+ callContext.procRef, *intrinsic, converter));
+
+ // helper to get a particular prepared argument
+ auto getArgument = [&](std::size_t i, bool loadArg) -> fir::ExtendedValue {
+ if (!loweredActuals[i])
+ return fir::getAbsentIntrinsicArgument();
+ hlfir::Entity actual = loweredActuals[i]->getActual(loc, builder);
+ if (loadArg && fir::conformsWithPassByRef(actual.getType())) {
+ return hlfir::loadTrivialScalar(loc, builder, actual);
+ }
+ return actual;
+ };
+ // helper to get the isPresent flag for a particular prepared argument
+ auto isPresent = [&](std::size_t i) -> std::optional<mlir::Value> {
+ if (!loweredActuals[i])
+ return {builder.createBool(loc, false)};
+ if (loweredActuals[i]->handleDynamicOptional())
+ return {loweredActuals[i]->getIsPresent()};
+ return std::nullopt;
+ };
+
+ assert(callContext.resultType &&
+ "the elemental intrinsics with custom handling are all functions");
+ // if callContext.resultType is an array then this was originally an elemental
+ // call. What we are lowering here is inside the kernel of the hlfir.elemental
+ // so we should return the scalar type. If the return type is already a scalar
+ // then it should be unchanged here.
+ mlir::Type resTy = hlfir::getFortranElementType(*callContext.resultType);
+ fir::ExtendedValue result = Fortran::lower::lowerCustomIntrinsic(
+ builder, loc, callContext.getProcedureName(), resTy, isPresent,
+ getArgument, loweredActuals.size(), callContext.stmtCtx);
+
+ return {hlfir::EntityWithAttributes{extendedValueToHlfirEntity(
+ loc, builder, result, ".tmp.custom_intrinsic_result")}};
+}
+
/// Lower calls to intrinsic procedures with actual arguments that have been
/// pre-lowered but have not yet been prepared according to the interface.
static std::optional<hlfir::EntityWithAttributes>
@@ -1279,6 +1325,10 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
const Fortran::evaluate::SpecificIntrinsic *intrinsic,
const fir::IntrinsicArgumentLoweringRules *argLowering,
CallContext &callContext) {
+ auto &converter = callContext.converter;
+ if (intrinsic && Fortran::lower::intrinsicRequiresCustomOptionalHandling(
+ callContext.procRef, *intrinsic, converter))
+ return genCustomIntrinsicRefCore(loweredActuals, intrinsic, callContext);
llvm::SmallVector<fir::ExtendedValue> operands;
llvm::SmallVector<hlfir::CleanupFunction> cleanupFns;
auto addToCleanups = [&cleanupFns](std::optional<hlfir::CleanupFunction> fn) {
@@ -1286,7 +1336,6 @@ genIntrinsicRefCore(Fortran::lower::PreparedActualArguments &loweredActuals,
cleanupFns.emplace_back(std::move(*fn));
};
auto &stmtCtx = callContext.stmtCtx;
- auto &converter = callContext.converter;
fir::FirOpBuilder &builder = callContext.getBuilder();
mlir::Location loc = callContext.loc;
for (auto arg : llvm::enumerate(loweredActuals)) {
@@ -1758,16 +1807,11 @@ genCustomElementalIntrinsicRef(
auto prepareOptionalArg = [&](const Fortran::lower::SomeExpr &expr) {
hlfir::EntityWithAttributes actual = Fortran::lower::convertExprToHLFIR(
loc, converter, expr, callContext.symMap, callContext.stmtCtx);
- if (expr.Rank() == 0) {
- std::optional<mlir::Value> isPresent =
- genIsPresentIfArgMaybeAbsent(loc, actual, expr, callContext,
- /*passAsAllocatableOrPointer=*/false);
- operands.emplace_back(
- Fortran::lower::PreparedActualArgument{actual, isPresent});
- } else {
- TODO(loc, "elemental intrinsic with custom optional handling optional "
- "array argument");
- }
+ std::optional<mlir::Value> isPresent =
+ genIsPresentIfArgMaybeAbsent(loc, actual, expr, callContext,
+ /*passAsAllocatableOrPointer=*/false);
+ operands.emplace_back(
+ Fortran::lower::PreparedActualArgument{actual, isPresent});
};
// callback for non-optional arguments
@@ -1855,31 +1899,7 @@ genCustomIntrinsicRef(const Fortran::evaluate::SpecificIntrinsic *intrinsic,
callContext.procRef, *intrinsic, callContext.resultType,
prepareOptionalArg, prepareOtherArg, converter);
- // helper to get a particular prepared argument
- auto getArgument = [&](std::size_t i, bool loadArg) -> fir::ExtendedValue {
- if (!loweredActuals[i])
- return fir::getAbsentIntrinsicArgument();
- hlfir::Entity actual = loweredActuals[i]->getActual(loc, builder);
- if (loadArg && fir::conformsWithPassByRef(actual.getType())) {
- return hlfir::loadTrivialScalar(loc, builder, actual);
- }
- return actual;
- };
- // helper to get the isPresent flag for a particular prepared argument
- auto isPresent = [&](std::size_t i) -> std::optional<mlir::Value> {
- if (!loweredActuals[i])
- return {builder.createBool(loc, false)};
- if (loweredActuals[i]->handleDynamicOptional())
- return {loweredActuals[i]->getIsPresent()};
- return std::nullopt;
- };
-
- fir::ExtendedValue result = Fortran::lower::lowerCustomIntrinsic(
- builder, loc, callContext.getProcedureName(), callContext.resultType,
- isPresent, getArgument, loweredActuals.size(), stmtCtx);
-
- return {hlfir::EntityWithAttributes{extendedValueToHlfirEntity(
- loc, builder, result, ".tmp.custom_intrinsic_result")}};
+ return genCustomIntrinsicRefCore(loweredActuals, intrinsic, callContext);
}
/// Lower an intrinsic procedure reference.
diff --git a/flang/test/Lower/HLFIR/custom-intrinsic.f90 b/flang/test/Lower/HLFIR/custom-intrinsic.f90
index c6c856b5435087..cf91ea332cdc7d 100644
--- a/flang/test/Lower/HLFIR/custom-intrinsic.f90
+++ b/flang/test/Lower/HLFIR/custom-intrinsic.f90
@@ -128,6 +128,51 @@ function max_array(a, b)
! CHECK: return %[[VAL_21]] : !fir.array<42xi32>
! CHECK: }
+function max_dynamic_optional_array(a, b, c)
+ integer :: a, b(10), max_dynamic_optional_array(10)
+ integer, optional :: c(10)
+ max_dynamic_optional_array = max(a, b, c)
+end function
+! CHECK-LABEL: func.func @_QPmax_dynamic_optional_array(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "b"},
+! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "c", fir.optional}) -> !fir.array<10xi32> {
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFmax_dynamic_optional_arrayEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_5]]) {uniq_name = "_QFmax_dynamic_optional_arrayEb"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[VAL_7:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_8]]) {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFmax_dynamic_optional_arrayEc"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[VAL_10:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_11:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "max_dynamic_optional_array", uniq_name = "_QFmax_dynamic_optional_arrayEmax_dynamic_optional_array"}
+! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_12]]) {uniq_name = "_QFmax_dynamic_optional_arrayEmax_dynamic_optional_array"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_9]]#0 : (!fir.ref<!fir.array<10xi32>>) -> i1
+! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_16:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<10xi32> {
+! CHECK: ^bb0(%[[VAL_17:.*]]: index):
+! CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_17]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_18]] : !fir.ref<i32>
+! CHECK: %[[VAL_20:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_19]] : i32
+! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_20]], %[[VAL_15]], %[[VAL_19]] : i32
+! CHECK: %[[VAL_22:.*]] = fir.if %[[VAL_14]] -> (i32) {
+! CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_17]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref<i32>
+! CHECK: %[[VAL_25:.*]] = arith.cmpi sgt, %[[VAL_21]], %[[VAL_24]] : i32
+! CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_25]], %[[VAL_21]], %[[VAL_24]] : i32
+! CHECK: fir.result %[[VAL_26]] : i32
+! CHECK: } else {
+! CHECK: fir.result %[[VAL_21]] : i32
+! CHECK: }
+! CHECK: hlfir.yield_element %[[VAL_27:.*]] : i32
+! CHECK: }
+! CHECK: hlfir.assign %[[VAL_28:.*]] to %[[VAL_13]]#0 : !hlfir.expr<10xi32>, !fir.ref<!fir.array<10xi32>>
+! CHECK: hlfir.destroy %[[VAL_28]] : !hlfir.expr<10xi32>
+! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_13]]#1 : !fir.ref<!fir.array<10xi32>>
+! CHECK: return %[[VAL_29]] : !fir.array<10xi32>
+! CHECK: }
+
function min_simple(a, b)
integer :: a, b, min_simple
min_simple = min(a, b)
@@ -256,6 +301,51 @@ function min_array(a, b)
! CHECK: return %[[VAL_21]] : !fir.array<42xi32>
! CHECK: }
+function min_dynamic_optional_array(a, b, c)
+ integer :: a, b(10), min_dynamic_optional_array(10)
+ integer, optional :: c(10)
+ min_dynamic_optional_array = min(a, b, c)
+end function
+! CHECK-LABEL: func.func @_QPmin_dynamic_optional_array(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "b"},
+! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "c", fir.optional}) -> !fir.array<10xi32> {
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFmin_dynamic_optional_arrayEa"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_5]]) {uniq_name = "_QFmin_dynamic_optional_arrayEb"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[VAL_7:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_8]]) {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFmin_dynamic_optional_arrayEc"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[VAL_10:.*]] = arith.constant 10 : index
+! CHECK: %[[VAL_11:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "min_dynamic_optional_array", uniq_name = "_QFmin_dynamic_optional_arrayEmin_dynamic_optional_array"}
+! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_12]]) {uniq_name = "_QFmin_dynamic_optional_arrayEmin_dynamic_optional_array"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_9]]#0 : (!fir.ref<!fir.array<10xi32>>) -> i1
+! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_16:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<10xi32> {
+! CHECK: ^bb0(%[[VAL_17:.*]]: index):
+! CHECK: %[[VAL_18:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_17]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_18]] : !fir.ref<i32>
+! CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_19]] : i32
+! CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_20]], %[[VAL_15]], %[[VAL_19]] : i32
+! CHECK: %[[VAL_22:.*]] = fir.if %[[VAL_14]] -> (i32) {
+! CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_9]]#0 (%[[VAL_17]]) : (!fir.ref<!fir.array<10xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref<i32>
+! CHECK: %[[VAL_25:.*]] = arith.cmpi slt, %[[VAL_21]], %[[VAL_24]] : i32
+! CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_25]], %[[VAL_21]], %[[VAL_24]] : i32
+! CHECK: fir.result %[[VAL_26]] : i32
+! CHECK: } else {
+! CHECK: fir.result %[[VAL_21]] : i32
+! CHECK: }
+! CHECK: hlfir.yield_element %[[VAL_27:.*]] : i32
+! CHECK: }
+! CHECK: hlfir.assign %[[VAL_28:.*]] to %[[VAL_13]]#0 : !hlfir.expr<10xi32>, !fir.ref<!fir.array<10xi32>>
+! CHECK: hlfir.destroy %[[VAL_28]] : !hlfir.expr<10xi32>
+! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_13]]#1 : !fir.ref<!fir.array<10xi32>>
+! CHECK: return %[[VAL_29]] : !fir.array<10xi32>
+! CHECK: }
+
function associated_simple(pointer)
integer, pointer :: pointer
logical :: associated_simple
@@ -521,4 +611,233 @@ function ishftc_array(i, shift, size)
! CHECK: hlfir.destroy %[[VAL_53]] : !hlfir.expr<42xi32>
! CHECK: %[[VAL_54:.*]] = fir.load %[[VAL_9]]#1 : !fir.ref<!fir.array<42xi32>>
! CHECK: return %[[VAL_54]] : !fir.array<42xi32>
+! CHECK: }
+
+function ishftc_dynamically_optional_array(i, shift, size)
+ integer :: ishftc_dynamically_optional_array(42), i(42), shift
+ integer, optional :: size
+ ishftc_dynamically_optional_array = ishftc(i, shift, size)
+end function
+! CHECK-LABEL: func.func @_QPishftc_dynamically_optional_array(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<42xi32>> {fir.bindc_name = "i"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<i32> {fir.bindc_name = "shift"},
+! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "size", fir.optional}) -> !fir.array<42xi32> {
+! CHECK: %[[VAL_3:.*]] = arith.constant 42 : index
+! CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) {uniq_name = "_QFishftc_dynamically_optional_arrayEi"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
+! CHECK: %[[VAL_6:.*]] = arith.constant 42 : index
+! CHECK: %[[VAL_7:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "ishftc_dynamically_optional_array", uniq_name = "_QFishftc_dynamically_optional_arrayEishftc_dynamically_optional_array"}
+! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {uniq_name = "_QFishftc_dynamically_optional_arrayEishftc_dynamically_optional_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
+! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFishftc_dynamically_optional_arrayEshift"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_2]] {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFishftc_dynamically_optional_arrayEsize"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]]#0 : (!fir.ref<i32>) -> i1
+! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_14:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
+! CHECK: ^bb0(%[[VAL_15:.*]]: index):
+! CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_5]]#0 (%[[VAL_15]]) : (!fir.ref<!fir.array<42xi32>>, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<i32>
+! CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_12]] -> (i32) {
+! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<i32>
+! CHECK: fir.result %[[VAL_19]] : i32
+! CHECK: } else {
+! CHECK: %[[VAL_20:.*]] = arith.constant 32 : i32
+! CHECK: fir.result %[[VAL_20]] : i32
+! CHECK: }
+! CHECK: %[[VAL_21:.*]] = arith.constant 32 : i32
+! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i32
+! CHECK: %[[VAL_23:.*]] = arith.constant -1 : i32
+! CHECK: %[[VAL_24:.*]] = arith.constant 31 : i32
+! CHECK: %[[VAL_25:.*]] = arith.shrsi %[[VAL_13]], %[[VAL_24]] : i32
+! CHECK: %[[VAL_26:.*]] = arith.xori %[[VAL_13]], %[[VAL_25]] : i32
+! CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_26]], %[[VAL_25]] : i32
+! CHECK: %[[VAL_28:.*]] = arith.subi %[[VAL_29:.*]], %[[VAL_27]] : i32
+! CHECK: %[[VAL_30:.*]] = arith.cmpi eq, %[[VAL_13]], %[[VAL_22]] : i32
+! CHECK: %[[VAL_31:.*]] = arith.cmpi eq, %[[VAL_27]], %[[VAL_29]] : i32
+! CHECK: %[[VAL_32:.*]] = arith.ori %[[VAL_30]], %[[VAL_31]] : i1
+! CHECK: %[[VAL_33:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_22]] : i32
+! CHECK: %[[VAL_34:.*]] = arith.select %[[VAL_33]], %[[VAL_27]], %[[VAL_28]] : i32
+! CHECK: %[[VAL_35:.*]] = arith.select %[[VAL_33]], %[[VAL_28]], %[[VAL_27]] : i32
+! CHECK: %[[VAL_36:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_21]] : i32
+! CHECK: %[[VAL_37:.*]] = arith.shrui %[[VAL_17]], %[[VAL_29]] : i32
+! CHECK: %[[VAL_38:.*]] = arith.shli %[[VAL_37]], %[[VAL_29]] : i32
+! CHECK: %[[VAL_39:.*]] = arith.select %[[VAL_36]], %[[VAL_38]], %[[VAL_22]] : i32
+! CHECK: %[[VAL_40:.*]] = arith.subi %[[VAL_21]], %[[VAL_34]] : i32
+! CHECK: %[[VAL_41:.*]] = arith.shrui %[[VAL_23]], %[[VAL_40]] : i32
+! CHECK: %[[VAL_42:.*]] = arith.shrui %[[VAL_17]], %[[VAL_35]] : i32
+! CHECK: %[[VAL_43:.*]] = arith.andi %[[VAL_42]], %[[VAL_41]] : i32
+! CHECK: %[[VAL_44:.*]] = arith.subi %[[VAL_21]], %[[VAL_35]] : i32
+! CHECK: %[[VAL_45:.*]] = arith.shrui %[[VAL_23]], %[[VAL_44]] : i32
+! CHECK: %[[VAL_46:.*]] = arith.andi %[[VAL_17]], %[[VAL_45]] : i32
+! CHECK: %[[VAL_47:.*]] = arith.shli %[[VAL_46]], %[[VAL_34]] : i32
+! CHECK: %[[VAL_48:.*]] = arith.ori %[[VAL_39]], %[[VAL_43]] : i32
+! CHECK: %[[VAL_49:.*]] = arith.ori %[[VAL_48]], %[[VAL_47]] : i32
+! CHECK: %[[VAL_50:.*]] = arith.select %[[VAL_32]], %[[VAL_17]], %[[VAL_49]] : i32
+! CHECK: hlfir.yield_element %[[VAL_50]] : i32
+! CHECK: }
+! CHECK: hlfir.assign %[[VAL_51:.*]] to %[[VAL_9]]#0 : !hlfir.expr<42xi32>, !fir.ref<!fir.array<42xi32>>
+! CHECK: hlfir.destroy %[[VAL_51]] : !hlfir.expr<42xi32>
+! CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_9]]#1 : !fir.ref<!fir.array<42xi32>>
+! CHECK: return %[[VAL_52]] : !fir.array<42xi32>
+! CHECK: }
+
+subroutine allocatables_test(a, b, c)
+ implicit none
+ integer, parameter :: nx = 1
+ integer, parameter :: ny = 2
+ integer, parameter :: nz = 3
+ integer, dimension(:,:,:), allocatable :: a, b, c
+
+ allocate(a(nx,ny,nz))
+ allocate(b(nx,ny,nz))
+ allocate(c(nx,ny,nz))
+
+ c = min(a, b, c)
+end subroutine
+! CHECK-LABEL: func.func @_QPallocatables_test(
+! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>> {fir.bindc_name = "b"},
+! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>> {fir.bindc_name = "c"}) {
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFallocatables_testEa"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>)
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFallocatables_testEb"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFallocatables_testEc"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>)
+! CHECK: %[[VAL_6:.*]] = fir.address_of(@_QFallocatables_testECnx) : !fir.ref<i32>
+! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QFallocatables_testECnx"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_8:.*]] = fir.address_of(@_QFallocatables_testECny) : !fir.ref<i32>
+! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QFallocatables_testECny"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QFallocatables_testECnz) : !fir.ref<i32>
+! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QFallocatables_testECnz"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_12:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i32) -> index
+! CHECK: %[[VAL_14:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> index
+! CHECK: %[[VAL_16:.*]] = arith.constant 3 : i32
+! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i32) -> index
+! CHECK: %[[VAL_18:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_19:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_18]] : index
+! CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_19]], %[[VAL_13]], %[[VAL_18]] : index
+! CHECK: %[[VAL_21:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_22:.*]] = arith.cmpi sgt, %[[VAL_15]], %[[VAL_21]] : index
+! CHECK: %[[VAL_23:.*]] = arith.select %[[VAL_22]], %[[VAL_15]], %[[VAL_21]] : index
+! CHECK: %[[VAL_24:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_25:.*]] = arith.cmpi sgt, %[[VAL_17]], %[[VAL_24]] : index
+! CHECK: %[[VAL_26:.*]] = arith.select %[[VAL_25]], %[[VAL_17]], %[[VAL_24]] : index
+! CHECK: %[[VAL_27:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_20]], %[[VAL_23]], %[[VAL_26]] {fir.must_be_heap = true, uniq_name = "_QFallocatables_testEa.alloc"}
+! CHECK: %[[VAL_28:.*]] = fir.shape %[[VAL_20]], %[[VAL_23]], %[[VAL_26]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[VAL_29:.*]] = fir.embox %[[VAL_27]](%[[VAL_28]]) : (!fir.heap<!fir.array<?x?x?xi32>>, !fir.shape<3>) -> !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>
+! CHECK: fir.store %[[VAL_29]] to %[[VAL_3]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_30:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i32) -> index
+! CHECK: %[[VAL_32:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (i32) -> index
+! CHECK: %[[VAL_34:.*]] = arith.constant 3 : i32
+! CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i32) -> index
+! CHECK: %[[VAL_36:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_37:.*]] = arith.cmpi sgt, %[[VAL_31]], %[[VAL_36]] : index
+! CHECK: %[[VAL_38:.*]] = arith.select %[[VAL_37]], %[[VAL_31]], %[[VAL_36]] : index
+! CHECK: %[[VAL_39:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_40:.*]] = arith.cmpi sgt, %[[VAL_33]], %[[VAL_39]] : index
+! CHECK: %[[VAL_41:.*]] = arith.select %[[VAL_40]], %[[VAL_33]], %[[VAL_39]] : index
+! CHECK: %[[VAL_42:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_43:.*]] = arith.cmpi sgt, %[[VAL_35]], %[[VAL_42]] : index
+! CHECK: %[[VAL_44:.*]] = arith.select %[[VAL_43]], %[[VAL_35]], %[[VAL_42]] : index
+! CHECK: %[[VAL_45:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_38]], %[[VAL_41]], %[[VAL_44]] {fir.must_be_heap = true, uniq_name = "_QFallocatables_testEb.alloc"}
+! CHECK: %[[VAL_46:.*]] = fir.shape %[[VAL_38]], %[[VAL_41]], %[[VAL_44]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[VAL_47:.*]] = fir.embox %[[VAL_45]](%[[VAL_46]]) : (!fir.heap<!fir.array<?x?x?xi32>>, !fir.shape<3>) -> !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>
+! CHECK: fir.store %[[VAL_47]] to %[[VAL_4]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_48:.*]] = arith.constant 1 : i32
+! CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_48]] : (i32) -> index
+! CHECK: %[[VAL_50:.*]] = arith.constant 2 : i32
+! CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_50]] : (i32) -> index
+! CHECK: %[[VAL_52:.*]] = arith.constant 3 : i32
+! CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_52]] : (i32) -> index
+! CHECK: %[[VAL_54:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_55:.*]] = arith.cmpi sgt, %[[VAL_49]], %[[VAL_54]] : index
+! CHECK: %[[VAL_56:.*]] = arith.select %[[VAL_55]], %[[VAL_49]], %[[VAL_54]] : index
+! CHECK: %[[VAL_57:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_58:.*]] = arith.cmpi sgt, %[[VAL_51]], %[[VAL_57]] : index
+! CHECK: %[[VAL_59:.*]] = arith.select %[[VAL_58]], %[[VAL_51]], %[[VAL_57]] : index
+! CHECK: %[[VAL_60:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_61:.*]] = arith.cmpi sgt, %[[VAL_53]], %[[VAL_60]] : index
+! CHECK: %[[VAL_62:.*]] = arith.select %[[VAL_61]], %[[VAL_53]], %[[VAL_60]] : index
+! CHECK: %[[VAL_63:.*]] = fir.allocmem !fir.array<?x?x?xi32>, %[[VAL_56]], %[[VAL_59]], %[[VAL_62]] {fir.must_be_heap = true, uniq_name = "_QFallocatables_testEc.alloc"}
+! CHECK: %[[VAL_64:.*]] = fir.shape %[[VAL_56]], %[[VAL_59]], %[[VAL_62]] : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[VAL_65:.*]] = fir.embox %[[VAL_63]](%[[VAL_64]]) : (!fir.heap<!fir.array<?x?x?xi32>>, !fir.shape<3>) -> !fir.box<!fir.heap<!fir.array<?x?x?xi32>>>
+! CHECK: fir.store %[[VAL_65]] to %[[VAL_5]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_66:.*]] = fir.load %[[VAL_5]]#1 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_67:.*]] = fir.box_addr %[[VAL_66]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>) -> !fir.heap<!fir.array<?x?x?xi32>>
+! CHECK: %[[VAL_68:.*]] = fir.convert %[[VAL_67]] : (!fir.heap<!fir.array<?x?x?xi32>>) -> i64
+! CHECK: %[[VAL_69:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_70:.*]] = arith.cmpi ne, %[[VAL_68]], %[[VAL_69]] : i64
+! CHECK: %[[VAL_71:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_72:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_73:.*]]:3 = fir.box_dims %[[VAL_71]], %[[VAL_72]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_74:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_75:.*]]:3 = fir.box_dims %[[VAL_71]], %[[VAL_74]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_76:.*]] = arith.constant 2 : index
+! CHECK: %[[VAL_77:.*]]:3 = fir.box_dims %[[VAL_71]], %[[VAL_76]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_78:.*]] = fir.shape %[[VAL_73]]#1, %[[VAL_75]]#1, %[[VAL_77]]#1 : (index, index, index) -> !fir.shape<3>
+! CHECK: %[[VAL_79:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_80:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: %[[VAL_81:.*]] = hlfir.elemental %[[VAL_78]] unordered : (!fir.shape<3>) -> !hlfir.expr<?x?x?xi32> {
+! CHECK: ^bb0(%[[VAL_82:.*]]: index, %[[VAL_83:.*]]: index, %[[VAL_84:.*]]: index):
+! CHECK: %[[VAL_85:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_86:.*]]:3 = fir.box_dims %[[VAL_71]], %[[VAL_85]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_87:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_88:.*]]:3 = fir.box_dims %[[VAL_71]], %[[VAL_87]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_89:.*]] = arith.constant 2 : index
+! CHECK: %[[VAL_90:.*]]:3 = fir.box_dims %[[VAL_71]], %[[VAL_89]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_91:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_92:.*]] = arith.subi %[[VAL_86]]#0, %[[VAL_91]] : index
+! CHECK: %[[VAL_93:.*]] = arith.addi %[[VAL_82]], %[[VAL_92]] : index
+! CHECK: %[[VAL_94:.*]] = arith.subi %[[VAL_88]]#0, %[[VAL_91]] : index
+! CHECK: %[[VAL_95:.*]] = arith.addi %[[VAL_83]], %[[VAL_94]] : index
+! CHECK: %[[VAL_96:.*]] = arith.subi %[[VAL_90]]#0, %[[VAL_91]] : index
+! CHECK: %[[VAL_97:.*]] = arith.addi %[[VAL_84]], %[[VAL_96]] : index
+! CHECK: %[[VAL_98:.*]] = hlfir.designate %[[VAL_71]] (%[[VAL_93]], %[[VAL_95]], %[[VAL_97]]) : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index, index, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_99:.*]] = fir.load %[[VAL_98]] : !fir.ref<i32>
+! CHECK: %[[VAL_100:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_101:.*]]:3 = fir.box_dims %[[VAL_79]], %[[VAL_100]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_102:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_103:.*]]:3 = fir.box_dims %[[VAL_79]], %[[VAL_102]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_104:.*]] = arith.constant 2 : index
+! CHECK: %[[VAL_105:.*]]:3 = fir.box_dims %[[VAL_79]], %[[VAL_104]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_106:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_107:.*]] = arith.subi %[[VAL_101]]#0, %[[VAL_106]] : index
+! CHECK: %[[VAL_108:.*]] = arith.addi %[[VAL_82]], %[[VAL_107]] : index
+! CHECK: %[[VAL_109:.*]] = arith.subi %[[VAL_103]]#0, %[[VAL_106]] : index
+! CHECK: %[[VAL_110:.*]] = arith.addi %[[VAL_83]], %[[VAL_109]] : index
+! CHECK: %[[VAL_111:.*]] = arith.subi %[[VAL_105]]#0, %[[VAL_106]] : index
+! CHECK: %[[VAL_112:.*]] = arith.addi %[[VAL_84]], %[[VAL_111]] : index
+! CHECK: %[[VAL_113:.*]] = hlfir.designate %[[VAL_79]] (%[[VAL_108]], %[[VAL_110]], %[[VAL_112]]) : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index, index, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_114:.*]] = fir.load %[[VAL_113]] : !fir.ref<i32>
+! CHECK: %[[VAL_115:.*]] = arith.cmpi slt, %[[VAL_99]], %[[VAL_114]] : i32
+! CHECK: %[[VAL_116:.*]] = arith.select %[[VAL_115]], %[[VAL_99]], %[[VAL_114]] : i32
+! CHECK: %[[VAL_117:.*]] = fir.if %[[VAL_70]] -> (i32) {
+! CHECK: %[[VAL_118:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_119:.*]]:3 = fir.box_dims %[[VAL_80]], %[[VAL_118]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_120:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_121:.*]]:3 = fir.box_dims %[[VAL_80]], %[[VAL_120]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_122:.*]] = arith.constant 2 : index
+! CHECK: %[[VAL_123:.*]]:3 = fir.box_dims %[[VAL_80]], %[[VAL_122]] : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index) -> (index, index, index)
+! CHECK: %[[VAL_124:.*]] = arith.constant 1 : index
+! CHECK: %[[VAL_125:.*]] = arith.subi %[[VAL_119]]#0, %[[VAL_124]] : index
+! CHECK: %[[VAL_126:.*]] = arith.addi %[[VAL_82]], %[[VAL_125]] : index
+! CHECK: %[[VAL_127:.*]] = arith.subi %[[VAL_121]]#0, %[[VAL_124]] : index
+! CHECK: %[[VAL_128:.*]] = arith.addi %[[VAL_83]], %[[VAL_127]] : index
+! CHECK: %[[VAL_129:.*]] = arith.subi %[[VAL_123]]#0, %[[VAL_124]] : index
+! CHECK: %[[VAL_130:.*]] = arith.addi %[[VAL_84]], %[[VAL_129]] : index
+! CHECK: %[[VAL_131:.*]] = hlfir.designate %[[VAL_80]] (%[[VAL_126]], %[[VAL_128]], %[[VAL_130]]) : (!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>, index, index, index) -> !fir.ref<i32>
+! CHECK: %[[VAL_132:.*]] = fir.load %[[VAL_131]] : !fir.ref<i32>
+! CHECK: %[[VAL_133:.*]] = arith.cmpi slt, %[[VAL_116]], %[[VAL_132]] : i32
+! CHECK: %[[VAL_134:.*]] = arith.select %[[VAL_133]], %[[VAL_116]], %[[VAL_132]] : i32
+! CHECK: fir.result %[[VAL_134]] : i32
+! CHECK: } else {
+! CHECK: fir.result %[[VAL_116]] : i32
+! CHECK: }
+! CHECK: hlfir.yield_element %[[VAL_135:.*]] : i32
+! CHECK: }
+! CHECK: hlfir.assign %[[VAL_136:.*]] to %[[VAL_5]]#0 realloc : !hlfir.expr<?x?x?xi32>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x?xi32>>>>
+! CHECK: hlfir.destroy %[[VAL_136]] : !hlfir.expr<?x?x?xi32>
+! CHECK: return
! CHECK: }
\ No newline at end of file
More information about the flang-commits
mailing list