[flang-commits] [flang] [flang] Code generation for fir.pack/unpack_array. (PR #132080)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Tue Mar 25 12:19:57 PDT 2025
https://github.com/vzakhari updated https://github.com/llvm/llvm-project/pull/132080
>From f92cee81489bf216d432fd9a66d303dc7dd2b202 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 11 Mar 2025 12:52:54 -0700
Subject: [PATCH 1/7] [flang] Code generation for fir.pack/unpack_array.
The code generation relies on `ShallowCopyDirect` runtime
to copy data between the original and the temporary arrays
(both directions). The allocations are done by the compiler
generated code. The heap allocations could have been passed
to `ShallowCopy` runtime, but I decided to expose the allocations
so that the temporary descriptor passed to `ShallowCopyDirect`
has `nocapture` - maybe this will be better for LLVM optimizations.
---
.../flang/Optimizer/CodeGen/CGPasses.td | 11 +
.../include/flang/Optimizer/CodeGen/CodeGen.h | 1 +
flang/lib/Optimizer/CodeGen/CMakeLists.txt | 1 +
.../Optimizer/CodeGen/LowerRepackArrays.cpp | 403 ++++++
flang/lib/Optimizer/Passes/Pipelines.cpp | 1 +
flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 1 +
.../test/Driver/mlir-debug-pass-pipeline.f90 | 1 +
flang/test/Driver/mlir-pass-pipeline.f90 | 1 +
flang/test/Fir/basic-program.fir | 1 +
flang/test/Transforms/lower-repack-arrays.fir | 1124 +++++++++++++++++
10 files changed, 1545 insertions(+)
create mode 100644 flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
create mode 100644 flang/test/Transforms/lower-repack-arrays.fir
diff --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
index 2e097faec5403..df0ecf5540776 100644
--- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td
+++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
@@ -99,4 +99,15 @@ def BoxedProcedurePass : Pass<"boxed-procedure", "mlir::ModuleOp"> {
];
}
+def LowerRepackArraysPass : Pass<"lower-repack-arrays", "mlir::ModuleOp"> {
+ let summary = "Convert fir.pack/unpack_array to other FIR operations";
+ let description = [{
+ Convert fir.pack/unpack_array operations to other FIR operations
+ and Fortran runtime calls that implement the semantics
+ of packing/unpacking.
+ }];
+ let dependentDialects = ["fir::FIROpsDialect", "mlir::arith::ArithDialect",
+ "mlir::func::FuncDialect"];
+}
+
#endif // FORTRAN_OPTIMIZER_CODEGEN_FIR_PASSES
diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
index 255b1950c8425..0398d0f248e08 100644
--- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h
+++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
@@ -26,6 +26,7 @@ struct NameUniquer;
#define GEN_PASS_DECL_CODEGENREWRITE
#define GEN_PASS_DECL_TARGETREWRITEPASS
#define GEN_PASS_DECL_BOXEDPROCEDUREPASS
+#define GEN_PASS_DECL_LOWERREPACKARRAYSPASS
#include "flang/Optimizer/CodeGen/CGPasses.h.inc"
/// FIR to LLVM translation pass options.
diff --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
index 553c20bb85d38..f730c7fd03948 100644
--- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt
+++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
@@ -4,6 +4,7 @@ add_flang_library(FIRCodeGen
CodeGen.cpp
CodeGenOpenMP.cpp
FIROpPatterns.cpp
+ LowerRepackArrays.cpp
PreCGRewrite.cpp
TBAABuilder.cpp
Target.cpp
diff --git a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
new file mode 100644
index 0000000000000..c109dc4732ca5
--- /dev/null
+++ b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
@@ -0,0 +1,403 @@
+//===-- LowerRepackArrays.cpp
+//------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/CodeGen/CodeGen.h"
+
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/Character.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/MutableBox.h"
+#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
+#include "flang/Optimizer/Builder/Runtime/Transformational.h"
+#include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Support/DataLayout.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+namespace fir {
+#define GEN_PASS_DEF_LOWERREPACKARRAYSPASS
+#include "flang/Optimizer/CodeGen/CGPasses.h.inc"
+} // namespace fir
+
+#define DEBUG_TYPE "lower-repack-arrays"
+
+namespace {
+class RepackArrayConversion {
+public:
+ RepackArrayConversion(std::optional<mlir::DataLayout> dataLayout)
+ : dataLayout(dataLayout) {}
+
+protected:
+ std::optional<mlir::DataLayout> dataLayout;
+
+ static bool canAllocateTempOnStack(mlir::Value box);
+};
+
+class PackArrayConversion : public mlir::OpRewritePattern<fir::PackArrayOp>,
+ RepackArrayConversion {
+public:
+ using OpRewritePattern::OpRewritePattern;
+
+ PackArrayConversion(mlir::MLIRContext *context,
+ std::optional<mlir::DataLayout> dataLayout)
+ : OpRewritePattern(context), RepackArrayConversion(dataLayout) {}
+
+ mlir::LogicalResult
+ matchAndRewrite(fir::PackArrayOp op,
+ mlir::PatternRewriter &rewriter) const override;
+
+private:
+ static constexpr llvm::StringRef bufferName = ".repacked";
+
+ static mlir::Value allocateTempBuffer(fir::FirOpBuilder &builder,
+ mlir::Location loc, bool useStack,
+ mlir::Value origBox,
+ llvm::ArrayRef<mlir::Value> extents,
+ llvm::ArrayRef<mlir::Value> typeParams);
+};
+
+class UnpackArrayConversion : public mlir::OpRewritePattern<fir::UnpackArrayOp>,
+ RepackArrayConversion {
+public:
+ using OpRewritePattern::OpRewritePattern;
+
+ UnpackArrayConversion(mlir::MLIRContext *context,
+ std::optional<mlir::DataLayout> dataLayout)
+ : OpRewritePattern(context), RepackArrayConversion(dataLayout) {}
+
+ mlir::LogicalResult
+ matchAndRewrite(fir::UnpackArrayOp op,
+ mlir::PatternRewriter &rewriter) const override;
+};
+} // anonymous namespace
+
+bool RepackArrayConversion::canAllocateTempOnStack(mlir::Value box) {
+ return !fir::isPolymorphicType(box.getType());
+}
+
+mlir::LogicalResult
+PackArrayConversion::matchAndRewrite(fir::PackArrayOp op,
+ mlir::PatternRewriter &rewriter) const {
+ mlir::Location loc = op.getLoc();
+ fir::FirOpBuilder builder(rewriter, op.getOperation());
+ if (op.getMaxSize() || op.getMaxElementSize() || op.getMinStride())
+ TODO(loc, "fir.pack_array with constraints");
+ if (op.getHeuristics() != fir::PackArrayHeuristics::None)
+ TODO(loc, "fir.pack_array with heuristics");
+
+ mlir::Value box = op.getArray();
+ llvm::SmallVector<mlir::Value> typeParams(op.getTypeparams().begin(),
+ op.getTypeparams().end());
+ // TODO: set non-default lower bounds on fir.pack_array,
+ // so that we can preserve lower bounds in the temporary box.
+ fir::BoxValue boxValue(box, /*lbounds=*/{}, typeParams);
+ mlir::Type boxType = boxValue.getBoxTy();
+ unsigned rank = boxValue.rank();
+ mlir::Type indexType = builder.getIndexType();
+ mlir::Value zero = fir::factory::createZeroValue(builder, loc, indexType);
+
+ // Fetch the extents from the box, and see if the array
+ // is not empty.
+ // If the type params are not explicitly provided, then we must also
+ // fetch the type parameters from the box.
+ //
+ // bool isNotEmpty;
+ // vector<int64_t> extents;
+ // if (IsPresent(box) && !IsContiguous[UpTo](box[, 1])) {
+ // isNotEmpty = box->base_addr != null;
+ // extents = SHAPE(box);
+ // } else {
+ // isNotEmpty = false;
+ // extents = vector<int64_t>(rank, 0);
+ // }
+
+ unsigned numTypeParams = 0;
+ if (typeParams.size() == 0) {
+ if (auto recordType = mlir::dyn_cast<fir::RecordType>(boxValue.getEleTy()))
+ if (recordType.getNumLenParams() != 0)
+ TODO(loc,
+ "allocating temporary for a parameterized derived type array");
+
+ if (auto charType = mlir::dyn_cast<fir::CharacterType>(boxValue.getEleTy()))
+ if (charType.hasDynamicLen())
+ numTypeParams = 1;
+ }
+
+ // For now we have to always check if the box is present.
+ mlir::Type predicateType = builder.getI1Type();
+ auto isPresent =
+ builder.create<fir::IsPresentOp>(loc, predicateType, boxValue.getAddr());
+
+ // The results of the IfOp are:
+ // (extent1, ..., extentN, typeParam1, ..., typeParamM, isNotEmpty)
+ // The number of results is rank + numTypeParams + 1.
+ llvm::SmallVector<mlir::Type> ifTypes(rank + numTypeParams, indexType);
+ ifTypes.push_back(predicateType);
+ llvm::SmallVector<mlir::Value> negativeResult(rank + numTypeParams, zero);
+ negativeResult.push_back(
+ fir::factory::createZeroValue(builder, loc, predicateType));
+ bool failedTypeParams = false;
+ llvm::SmallVector<mlir::Value> extentsAndPredicate =
+ builder
+ .genIfOp(loc, ifTypes, isPresent,
+ /*withElseRegion=*/true)
+ .genThen([&]() {
+ // The box is present.
+ auto isContiguous = builder.create<fir::IsContiguousBoxOp>(
+ loc, box, op.getInnermost());
+ llvm::SmallVector<mlir::Value> extentsAndPredicate =
+ builder
+ .genIfOp(loc, ifTypes, isContiguous,
+ /*withElseRegion=*/true)
+ .genThen([&]() {
+ // Box is contiguous, return zero.
+ builder.create<fir::ResultOp>(loc, negativeResult);
+ })
+ .genElse([&]() {
+ // Get the extents.
+ llvm::SmallVector<mlir::Value> results =
+ fir::factory::readExtents(builder, loc, boxValue);
+
+ // Get the type parameters from the box, if needed.
+ llvm::SmallVector<mlir::Value> assumedTypeParams;
+ if (numTypeParams != 0) {
+ if (auto charType = mlir::dyn_cast<fir::CharacterType>(
+ boxValue.getEleTy()))
+ if (charType.hasDynamicLen()) {
+ fir::factory::CharacterExprHelper charHelper(
+ builder, loc);
+ mlir::Value len = charHelper.readLengthFromBox(
+ boxValue.getAddr(), charType);
+ assumedTypeParams.push_back(
+ builder.createConvert(loc, indexType, len));
+ }
+
+ if (numTypeParams != assumedTypeParams.size()) {
+ failedTypeParams = true;
+ assumedTypeParams.append(
+ numTypeParams - assumedTypeParams.size(), zero);
+ }
+ }
+ results.append(assumedTypeParams);
+
+ auto dataAddr = builder.create<fir::BoxAddrOp>(
+ loc, boxValue.getMemTy(), boxValue.getAddr());
+ auto isNotEmpty = builder.create<fir::IsPresentOp>(
+ loc, predicateType, dataAddr);
+ results.push_back(isNotEmpty);
+ builder.create<fir::ResultOp>(loc, results);
+ })
+ .getResults();
+
+ builder.create<fir::ResultOp>(loc, extentsAndPredicate);
+ })
+ .genElse([&]() {
+ // Box is absent, nothing to do.
+ builder.create<fir::ResultOp>(loc, negativeResult);
+ })
+ .getResults();
+
+ if (failedTypeParams)
+ return emitError(loc) << "failed to compute the type parameters for "
+ << op.getOperation() << '\n';
+
+ // The last result is the isNotEmpty predicate value.
+ mlir::Value isNotEmpty = extentsAndPredicate.pop_back_val();
+ // If fir.pack_array does not specify type parameters, but they are needed
+ // for the type, then use the parameters fetched from the box.
+ if (typeParams.size() == 0 && numTypeParams != 0) {
+ assert(extentsAndPredicate.size() > numTypeParams);
+ typeParams.append(extentsAndPredicate.end() - numTypeParams,
+ extentsAndPredicate.end());
+ extentsAndPredicate.pop_back_n(numTypeParams);
+ }
+ // The remaining resulst are the extents.
+ llvm::SmallVector<mlir::Value> extents = std::move(extentsAndPredicate);
+ assert(extents.size() == rank);
+
+ mlir::Value tempBox;
+ // Allocate memory for the temporary, if allocating on stack.
+ // We can do it unconditionally, even if size is zero.
+ if (op.getStack() && canAllocateTempOnStack(boxValue.getAddr())) {
+ tempBox = allocateTempBuffer(builder, loc, /*useStack=*/true,
+ boxValue.getAddr(), extents, typeParams);
+ if (!tempBox)
+ return rewriter.notifyMatchFailure(op,
+ "failed to produce stack allocation");
+ }
+
+ mlir::Value newResult =
+ builder.genIfOp(loc, {boxType}, isNotEmpty, /*withElseRegion=*/true)
+ .genThen([&]() {
+ // Do the heap allocation conditionally.
+ if (!tempBox)
+ tempBox =
+ allocateTempBuffer(builder, loc, /*useStack=*/false,
+ boxValue.getAddr(), extents, typeParams);
+
+ // Do the copy, if needed, and return the new box (shaped same way
+ // as the original one).
+ if (!op.getNoCopy())
+ fir::runtime::genShallowCopy(builder, loc, tempBox,
+ boxValue.getAddr(),
+ /*resultIsAllocated=*/true);
+
+ // Set the lower bounds after the original box.
+ mlir::Value shape;
+ if (!boxValue.getLBounds().empty()) {
+ shape = builder.genShape(loc, boxValue.getLBounds(), extents);
+ }
+
+ // Rebox the temporary box to make its type the same as
+ // the original box's.
+ tempBox = builder.create<fir::ReboxOp>(loc, boxType, tempBox, shape,
+ /*slice=*/nullptr);
+ builder.create<fir::ResultOp>(loc, tempBox);
+ })
+ .genElse([&]() {
+ // Return original box.
+ builder.create<fir::ResultOp>(loc, boxValue.getAddr());
+ })
+ .getResults()[0];
+
+ rewriter.replaceOp(op, newResult);
+ return mlir::success();
+}
+
+mlir::Value PackArrayConversion::allocateTempBuffer(
+ fir::FirOpBuilder &builder, mlir::Location loc, bool useStack,
+ mlir::Value origBox, llvm::ArrayRef<mlir::Value> extents,
+ llvm::ArrayRef<mlir::Value> typeParams) {
+ auto tempType = mlir::cast<fir::SequenceType>(
+ fir::extractSequenceType(origBox.getType()));
+ assert(tempType.getDimension() == extents.size() &&
+ "number of extents does not match the rank");
+
+ if (fir::isPolymorphicType(origBox.getType())) {
+ // Use runtime to allocate polymorphic temporary vector using the dynamic
+ // type of the original box and the provided numElements.
+ // TODO: try to generalize it with BufferizeHLFIR.cpp:createArrayTemp().
+
+ // We cannot allocate polymorphic entity on stack.
+ // Return null, and allow the caller to reissue the call.
+ if (useStack)
+ return nullptr;
+
+ mlir::Type indexType = builder.getIndexType();
+ mlir::Type boxHeapType = fir::HeapType::get(tempType);
+ mlir::Value boxAlloc = fir::factory::genNullBoxStorage(
+ builder, loc, fir::ClassType::get(boxHeapType));
+ fir::runtime::genAllocatableApplyMold(builder, loc, boxAlloc, origBox,
+ tempType.getDimension());
+ mlir::Value one = builder.createIntegerConstant(loc, indexType, 1);
+ unsigned dim = 0;
+ for (mlir::Value extent : extents) {
+ mlir::Value dimIndex =
+ builder.createIntegerConstant(loc, indexType, dim++);
+ fir::runtime::genAllocatableSetBounds(builder, loc, boxAlloc, dimIndex,
+ one, extent);
+ }
+
+ if (!typeParams.empty()) {
+ // We should call AllocatableSetDerivedLength() here.
+ TODO(loc,
+ "polymorphic type with length parameters in PackArrayConversion");
+ }
+
+ fir::runtime::genAllocatableAllocate(builder, loc, boxAlloc);
+ return builder.create<fir::LoadOp>(loc, boxAlloc);
+ }
+
+ // Allocate non-polymorphic temporary on stack or in heap.
+ mlir::Value newBuffer;
+ if (useStack)
+ newBuffer =
+ builder.createTemporary(loc, tempType, bufferName, extents, typeParams);
+ else
+ newBuffer = builder.createHeapTemporary(loc, tempType, bufferName, extents,
+ typeParams);
+
+ mlir::Type ptrType = newBuffer.getType();
+ mlir::Type tempBoxType = fir::BoxType::get(mlir::isa<fir::HeapType>(ptrType)
+ ? ptrType
+ : fir::unwrapRefType(ptrType));
+ mlir::Value shape = builder.genShape(loc, extents);
+ mlir::Value newBox =
+ builder.createBox(loc, tempBoxType, newBuffer, shape, /*slice=*/nullptr,
+ typeParams, /*tdesc=*/nullptr);
+ return newBox;
+}
+
+mlir::LogicalResult
+UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op,
+ mlir::PatternRewriter &rewriter) const {
+ mlir::Location loc = op.getLoc();
+ fir::FirOpBuilder builder(rewriter, op.getOperation());
+ mlir::Type predicateType = builder.getI1Type();
+ mlir::Type indexType = builder.getIndexType();
+ mlir::Value tempBox = op.getTemp();
+ mlir::Value originalBox = op.getOriginal();
+
+ // For now we have to always check if the box is present.
+ auto isPresent =
+ builder.create<fir::IsPresentOp>(loc, predicateType, originalBox);
+
+ builder.genIfThen(loc, isPresent).genThen([&]() {
+ mlir::Type addrType =
+ fir::HeapType::get(fir::extractSequenceType(tempBox.getType()));
+ mlir::Value tempAddr =
+ builder.create<fir::BoxAddrOp>(loc, addrType, tempBox);
+ mlir::Value tempAddrAsIndex =
+ builder.createConvert(loc, indexType, tempAddr);
+ mlir::Value originalAddr =
+ builder.create<fir::BoxAddrOp>(loc, addrType, originalBox);
+ originalAddr = builder.createConvert(loc, indexType, originalAddr);
+
+ auto isNotSame = builder.create<mlir::arith::CmpIOp>(
+ loc, mlir::arith::CmpIPredicate::ne, tempAddrAsIndex, originalAddr);
+ builder.genIfThen(loc, isNotSame).genThen([&]() {});
+ // Copy from temporary to the original.
+ if (!op.getNoCopy())
+ fir::runtime::genShallowCopy(builder, loc, originalBox, tempBox,
+ /*resultIsAllocated=*/true);
+
+ // Deallocate, if it was allocated in heap.
+ if (!op.getStack())
+ builder.create<fir::FreeMemOp>(loc, tempAddr);
+ });
+ rewriter.eraseOp(op);
+ return mlir::success();
+}
+
+namespace {
+class LowerRepackArraysPass
+ : public fir::impl::LowerRepackArraysPassBase<LowerRepackArraysPass> {
+public:
+ using LowerRepackArraysPassBase<
+ LowerRepackArraysPass>::LowerRepackArraysPassBase;
+
+ void runOnOperation() override final {
+ auto *context = &getContext();
+ mlir::ModuleOp module = getOperation();
+ std::optional<mlir::DataLayout> dl = fir::support::getOrSetMLIRDataLayout(
+ module, /*allowDefaultLayout=*/false);
+ mlir::RewritePatternSet patterns(context);
+ patterns.insert<PackArrayConversion>(context, dl);
+ patterns.insert<UnpackArrayConversion>(context, dl);
+ mlir::GreedyRewriteConfig config;
+ config.enableRegionSimplification =
+ mlir::GreedySimplifyRegionLevel::Disabled;
+ (void)applyPatternsGreedily(module, std::move(patterns), config);
+ }
+};
+
+} // anonymous namespace
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 3aea021e596f6..6ec19556625bc 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -198,6 +198,7 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm,
pm.addPass(fir::createPolymorphicOpConversion());
pm.addPass(fir::createAssumedRankOpConversion());
+ pm.addPass(fir::createLowerRepackArraysPass());
// Expand FIR operations that may use SCF dialect for their
// implementation. This is a mandatory pass.
pm.addPass(fir::createSimplifyFIROperations(
diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
index 276ef818622a1..137c19608c38f 100644
--- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90
+++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
@@ -47,6 +47,7 @@
! CHECK-NEXT: PolymorphicOpConversion
! CHECK-NEXT: AssumedRankOpConversion
+! CHECK-NEXT: LowerRepackArraysPass
! CHECK-NEXT: SimplifyFIROperations
! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private']
diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90
index 70fa0cf5ae47c..42a71b2d6adc3 100644
--- a/flang/test/Driver/mlir-debug-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90
@@ -77,6 +77,7 @@
! ALL-NEXT: PolymorphicOpConversion
! ALL-NEXT: AssumedRankOpConversion
+! ALL-NEXT: LowerRepackArraysPass
! ALL-NEXT: SimplifyFIROperations
! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private']
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index 852764be1f136..45370895db397 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -101,6 +101,7 @@
! ALL-NEXT: PolymorphicOpConversion
! ALL-NEXT: AssumedRankOpConversion
+! ALL-NEXT: LowerRepackArraysPass
! ALL-NEXT: SimplifyFIROperations
! O2-NEXT: AddAliasTags
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index 90bff80da1915..ded42886aad44 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -99,6 +99,7 @@ func.func @_QQmain() {
// PASSES-NEXT: PolymorphicOpConversion
// PASSES-NEXT: AssumedRankOpConversion
+// PASSES-NEXT: LowerRepackArraysPass
// PASSES-NEXT: SimplifyFIROperations
// PASSES-NEXT: AddAliasTags
diff --git a/flang/test/Transforms/lower-repack-arrays.fir b/flang/test/Transforms/lower-repack-arrays.fir
new file mode 100644
index 0000000000000..b09363e62f78b
--- /dev/null
+++ b/flang/test/Transforms/lower-repack-arrays.fir
@@ -0,0 +1,1124 @@
+// RUN: fir-opt --lower-repack-arrays %s | FileCheck %s
+
+// Test trivial type array repacking.
+// CHECK-LABEL: func.func @_QPtest1(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+func.func @_QPtest1(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_27]] {
+// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
+// CHECK: fir.if %[[VAL_32]] {
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_28]] : !fir.heap<!fir.array<?x?xf32>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?xf32>>
+ return
+}
+
+// Test 'stack whole' repacking.
+// CHECK-LABEL: func.func @_QPtest1_whole(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+func.func @_QPtest1_whole(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] whole : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_16:.*]] = fir.alloca !fir.array<?x?xf32>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_16]](%[[VAL_18]]) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 stack whole : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1_wholeEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1_wholeEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_27]] {
+// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
+// CHECK: fir.if %[[VAL_32]] {
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?xf32>>
+ return
+}
+
+// Test unpacking with no_copy.
+// CHECK-LABEL: func.func @_QPtest1_in(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+func.func @_QPtest1_in(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant false
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_6:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.result %[[VAL_10]]#1, %[[VAL_11]]#1, %[[VAL_13]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_9]]#0, %[[VAL_9]]#1, %[[VAL_9]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_7]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_7]]#0, %[[VAL_7]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_7]]#0, %[[VAL_7]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_17]](%[[VAL_18]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<none>
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_24:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_24]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_25:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest1_inEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest1_inEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_26:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_26]] {
+// CHECK: %[[VAL_27:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_31:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_30]] : index
+// CHECK: fir.if %[[VAL_31]] {
+// CHECK: fir.freemem %[[VAL_27]] : !fir.heap<!fir.array<?x?xf32>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap no_copy : !fir.box<!fir.array<?x?xf32>>
+ return
+}
+
+// Test packing with no_copy.
+// CHECK-LABEL: func.func @_QPtest1_out(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+func.func @_QPtest1_out(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant false
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_6:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.result %[[VAL_10]]#1, %[[VAL_11]]#1, %[[VAL_13]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_9]]#0, %[[VAL_9]]#1, %[[VAL_9]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_7]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_7]]#0, %[[VAL_7]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_7]]#0, %[[VAL_7]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_17]](%[[VAL_18]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_20]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost no_copy : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_21:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QFtest1_outEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QFtest1_outEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_22:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_22]] {
+// CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_23]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_27:.*]] = arith.cmpi ne, %[[VAL_25]], %[[VAL_26]] : index
+// CHECK: fir.if %[[VAL_27]] {
+// CHECK: %[[VAL_28:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_23]] : !fir.heap<!fir.array<?x?xf32>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?xf32>>
+ return
+}
+
+// Test character array with dynamic length and heap allocation
+// CHECK-LABEL: func.func @_QPtest2(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<i32> {fir.bindc_name = "n"},
+// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest2(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
+// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32
+// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
+ %c0_i32 = arith.constant 0 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_9:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2En"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2En"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
+ %2 = fir.load %1 : !fir.ref<i32>
+// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_10]], %[[VAL_7]] : i32
+ %3 = arith.cmpi sgt, %2, %c0_i32 : i32
+// CHECK: %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_10]], %[[VAL_7]] : i32
+ %4 = arith.select %3, %2, %c0_i32 : i32
+// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) {
+// CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.result %[[VAL_17]]#1, %[[VAL_18]]#1, %[[VAL_20]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_16]]#0, %[[VAL_16]]#1, %[[VAL_16]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_22:.*]] = fir.if %[[VAL_14]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,?>>(%[[VAL_12]] : i32), %[[VAL_14]]#0, %[[VAL_14]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_14]]#0, %[[VAL_14]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_24]](%[[VAL_25]]) typeparams %[[VAL_12]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_26]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_31]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_1]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: }
+ %5 = fir.pack_array %arg1 heap innermost typeparams %4 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_22]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_38:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_37]] : index
+// CHECK: fir.if %[[VAL_38]] {
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_22]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_34]] : !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %5 to %arg1 heap : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
+
+// Test character array with dynamic length and stack allocation
+// CHECK-LABEL: func.func @_QPtest2_stack(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<i32> {fir.bindc_name = "n"},
+// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest2_stack(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
+// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32
+// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
+ %c0_i32 = arith.constant 0 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_9:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2_stackEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
+ %2 = fir.load %1 : !fir.ref<i32>
+// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_10]], %[[VAL_7]] : i32
+ %3 = arith.cmpi sgt, %2, %c0_i32 : i32
+// CHECK: %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_10]], %[[VAL_7]] : i32
+ %4 = arith.select %3, %2, %c0_i32 : i32
+// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) {
+// CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.result %[[VAL_17]]#1, %[[VAL_18]]#1, %[[VAL_20]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_16]]#0, %[[VAL_16]]#1, %[[VAL_16]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_22:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[VAL_12]] : i32), %[[VAL_14]]#0, %[[VAL_14]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_14]]#0, %[[VAL_14]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_22]](%[[VAL_24]]) typeparams %[[VAL_12]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_14]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_25]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_31]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_1]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: }
+ %5 = fir.pack_array %arg1 stack innermost typeparams %4 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_26]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_26]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_38:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_37]] : index
+// CHECK: fir.if %[[VAL_38]] {
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_26]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %5 to %arg1 stack : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
+
+// Test character array with assumed length and heap allocation.
+// CHECK-LABEL: func.func @_QPtest3(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest3(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_8:.*]]:4 = fir.if %[[VAL_7]] -> (index, index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_10:.*]]:4 = fir.if %[[VAL_9]] -> (index, index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_13]], %[[VAL_15]] : index, index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2, %[[VAL_10]]#3 : index, index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_17:.*]] = fir.if %[[VAL_8]]#3 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,?>>(%[[VAL_8]]#2 : index), %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) typeparams %[[VAL_8]]#2 : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_29]] : !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
+
+// Test character array with assumed length and stack allocation.
+// CHECK-LABEL: func.func @_QPtest3_stack(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest3_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_8:.*]]:4 = fir.if %[[VAL_7]] -> (index, index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: %[[VAL_10:.*]]:4 = fir.if %[[VAL_9]] -> (index, index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_13]], %[[VAL_15]] : index, index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2, %[[VAL_10]]#3 : index, index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_17:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[VAL_8]]#2 : index), %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_17]](%[[VAL_19]]) typeparams %[[VAL_8]]#2 : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_8]]#3 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
+
+// Test character array with constant length and heap allocation.
+// CHECK-LABEL: func.func @_QPtest4(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest4(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_7:.*]] = fir.dummy_scope : !fir.dscope
+ %c10 = arith.constant 10 : index
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_8:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
+// CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: %[[VAL_11:.*]]:3 = fir.if %[[VAL_10]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: fir.result %[[VAL_12]]#1, %[[VAL_13]]#1, %[[VAL_15]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_11]]#0, %[[VAL_11]]#1, %[[VAL_11]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_17:.*]] = fir.if %[[VAL_9]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
+// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,10>>, %[[VAL_9]]#0, %[[VAL_9]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_9]]#0, %[[VAL_9]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_29]] : !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ return
+}
+
+// Test character array with constant length and stack allocation.
+// CHECK-LABEL: func.func @_QPtest4_stack(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest4_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant 10 : index
+// CHECK: %[[VAL_7:.*]] = fir.dummy_scope : !fir.dscope
+ %c10 = arith.constant 10 : index
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_8:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
+// CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: %[[VAL_11:.*]]:3 = fir.if %[[VAL_10]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: fir.result %[[VAL_12]]#1, %[[VAL_13]]#1, %[[VAL_15]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_11]]#0, %[[VAL_11]]#1, %[[VAL_11]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_17:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,10>>, %[[VAL_9]]#0, %[[VAL_9]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_9]]#0, %[[VAL_9]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_17]](%[[VAL_19]]) : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_9]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ return
+}
+
+// Test derived type array with heap allocation.
+// CHECK-LABEL: func.func @_QPtest5(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest5(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x?x!fir.type<_QMmTt>>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_27]] {
+// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
+// CHECK: fir.if %[[VAL_32]] {
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_28]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
+
+// Test derived type array with stack allocation.
+// CHECK-LABEL: func.func @_QPtest5_stack(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest5_stack(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_16:.*]] = fir.alloca !fir.array<?x?x!fir.type<_QMmTt>>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_16]](%[[VAL_18]]) : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5_stackEx"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5_stackEx"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_27]] {
+// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
+// CHECK: fir.if %[[VAL_32]] {
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
+
+// Test polymorphic type array with heap allocation.
+// CHECK-LABEL: func.func @_QPtest6(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest6(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
+// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6Ex"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6Ex"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_45]] {
+// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
+// CHECK: fir.if %[[VAL_50]] {
+// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_46]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
+
+// Test polymorphic type array with stack allocation.
+// CHECK-LABEL: func.func @_QPtest6_stack(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+func.func @_QPtest6_stack(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
+// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6_stackEx"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6_stackEx"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_45]] {
+// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
+// CHECK: fir.if %[[VAL_50]] {
+// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 stack : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
+
+// Test unlimited polymorphic type array with heap allocation.
+// CHECK-LABEL: func.func @_QPtest7(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
+func.func @_QPtest7(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
+// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?xnone>>>
+// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?xnone>>) -> i1
+// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?xnone>>) {
+// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?xnone>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?xnone>>>
+// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?xnone>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?xnone>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: fir.if %[[VAL_45]] {
+// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
+// CHECK: fir.if %[[VAL_50]] {
+// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_46]] : !fir.heap<!fir.array<?x?xnone>>
+// CHECK: }
+// CHECK: }
+ fir.unpack_array %1 to %arg0 heap : !fir.class<!fir.array<?x?xnone>>
+ return
+}
+
+// Test unlimited polymorphic type array with stack allocation.
+// CHECK-LABEL: func.func @_QPtest7_stack(
+// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
+func.func @_QPtest7_stack(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
+// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
+// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
+// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?xnone>>>
+// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
+ %0 = fir.dummy_scope : !fir.dscope
+// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: } else {
+// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?xnone>>) -> i1
+// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: }
+// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: }
+// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?xnone>>) {
+// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?xnone>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?xnone>>>
+// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?xnone>>
+// CHECK: } else {
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?xnone>>
+// CHECK: }
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: fir.if %[[VAL_45]] {
+// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
+// CHECK: fir.if %[[VAL_50]] {
+// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: }
+// CHECK: }
+// CHECK: return
+// CHECK: }
+ fir.unpack_array %1 to %arg0 stack : !fir.class<!fir.array<?x?xnone>>
+ return
+}
>From fb56d9123bd8dfbd1ad6a814a9876298d897de3b Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Wed, 19 Mar 2025 12:19:05 -0700
Subject: [PATCH 2/7] Updated the header comment for LowerRepackArrays.cpp
file.
---
.../Optimizer/CodeGen/LowerRepackArrays.cpp | 24 +++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
index c109dc4732ca5..8e00fcf49dd88 100644
--- a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
+++ b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
@@ -1,11 +1,31 @@
-//===-- LowerRepackArrays.cpp
-//------------------------------------------------===//
+//===-- LowerRepackArrays.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
+/// \file
+/// This pass expands fir.pack_array and fir.unpack_array operations
+/// into sequences of other FIR operations and Fortran runtime calls.
+/// This pass is using structured control flow FIR operations such
+/// as fir.if, so its placement in the pipeline should guarantee
+/// further lowering of these operations.
+///
+/// A fir.pack_array operation is converted into a sequence of checks
+/// identifying whether an array needs to be copied into a contiguous
+/// temporary. When the checks pass, a new memory allocation is done
+/// for the temporary array (in either stack or heap memory).
+/// If `fir.pack_array` does not have no_copy attribute, then
+/// the original array is shallow-copied into the temporary.
+///
+/// A fir.unpack_array operations is converted into a check
+/// of whether the original and the temporary arrays are different
+/// memory. When the check passes, the temporary array might be
+/// shallow-copied into the original array, and then the temporary
+/// array is deallocated (if it was allocated in stack memory,
+/// then there is no explicit deallocation).
+//===----------------------------------------------------------------------===//
#include "flang/Optimizer/CodeGen/CodeGen.h"
>From 5403a3671d0697e5e95da7d1753a93815cce006d Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Mon, 24 Mar 2025 19:11:14 -0700
Subject: [PATCH 3/7] Code refactoring to address review comments.
---
.../flang/Optimizer/Builder/FIRBuilder.h | 45 +
flang/lib/Optimizer/Builder/FIRBuilder.cpp | 93 +
flang/lib/Optimizer/Builder/HLFIRTools.cpp | 26 +-
.../Optimizer/CodeGen/LowerRepackArrays.cpp | 411 ++--
.../HLFIR/Transforms/BufferizeHLFIR.cpp | 31 +-
flang/test/HLFIR/elemental-codegen.fir | 6 +-
flang/test/Transforms/lower-repack-arrays.fir | 1737 +++++++++--------
7 files changed, 1209 insertions(+), 1140 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 003b4358572c1..82f5785090699 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -268,6 +268,40 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
mlir::ValueRange lenParams = {},
llvm::ArrayRef<mlir::NamedAttribute> attrs = {});
+ /// Sample genDeclare callback for createArrayTemp() below.
+ /// It creates fir.declare operation using the given operands.
+ /// \p memref is the base of the allocated temporary,
+ /// which may be !fir.ref<!fir.array<>> or !fir.ref<!fir.box/class<>>.
+ static mlir::Value genTempDeclareOp(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value memref,
+ llvm::StringRef name, mlir::Value shape,
+ llvm::ArrayRef<mlir::Value> typeParams,
+ fir::FortranVariableFlagsAttr attrs);
+
+ /// Create a temporary array with the given \p arrayType,
+ /// \p shape, \p extents and \p typeParams. An optional
+ /// \p polymorphicMold specifies the entity which dynamic type
+ /// has to be used for the allocation.
+ /// \p genDeclare callback generates a declare operation
+ /// for the created temporary. FIR passes may use genTempDeclareOp()
+ /// function above that creates fir.declare.
+ /// HLFIR passes may provide their own callback that generates
+ /// hlfir.declare. Some passes may provide a callback that
+ /// just passes through the base of the temporary.
+ /// If \p useStack is true, the function will try to do the allocation
+ /// in stack memory (which is not always possible currently).
+ /// The first return value is the base of the temporary object,
+ /// which may be !fir.ref<!fir.array<>> or !fir.ref<!fir.box/class<>>.
+ /// The second return value is true, if the actual allocation
+ /// was done in heap memory.
+ std::pair<mlir::Value, bool>
+ createArrayTemp(mlir::Location loc, fir::SequenceType arrayType,
+ mlir::Value shape, llvm::ArrayRef<mlir::Value> extents,
+ llvm::ArrayRef<mlir::Value> typeParams,
+ const std::function<decltype(genTempDeclareOp)> &genDeclare,
+ mlir::Value polymorphicMold, bool useStack = false,
+ llvm::StringRef tmpName = ".tmp.array");
+
/// Create an LLVM stack save intrinsic op. Returns the saved stack pointer.
/// The stack address space is fetched from the data layout of the current
/// module.
@@ -850,6 +884,17 @@ llvm::SmallVector<mlir::Value> deduceOptimalExtents(mlir::ValueRange extents1,
/// %result1 = arith.select %p4, %c0, %e1 : index
llvm::SmallVector<mlir::Value> updateRuntimeExtentsForEmptyArrays(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::ValueRange extents);
+
+/// Given \p box of type fir::BaseBoxType representing an array,
+/// the function generates code to fetch the lower bounds,
+/// the extents and the strides from the box. The values are returned via
+/// \p lbounds, \p extents and \p strides.
+void genDimInfoFromBox(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value box,
+ llvm::SmallVectorImpl<mlir::Value> *lbounds,
+ llvm::SmallVectorImpl<mlir::Value> *extents,
+ llvm::SmallVectorImpl<mlir::Value> *strides);
+
} // namespace fir::factory
#endif // FORTRAN_OPTIMIZER_BUILDER_FIRBUILDER_H
diff --git a/flang/lib/Optimizer/Builder/FIRBuilder.cpp b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
index b7f8a8d3a9d56..fdc155ef2ef18 100644
--- a/flang/lib/Optimizer/Builder/FIRBuilder.cpp
+++ b/flang/lib/Optimizer/Builder/FIRBuilder.cpp
@@ -11,6 +11,7 @@
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/Complex.h"
#include "flang/Optimizer/Builder/MutableBox.h"
+#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
#include "flang/Optimizer/Builder/Runtime/Assign.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Todo.h"
@@ -362,6 +363,72 @@ mlir::Value fir::FirOpBuilder::createHeapTemporary(
name, dynamicLength, dynamicShape, attrs);
}
+std::pair<mlir::Value, bool> fir::FirOpBuilder::createArrayTemp(
+ mlir::Location loc, fir::SequenceType arrayType, mlir::Value shape,
+ llvm::ArrayRef<mlir::Value> extents, llvm::ArrayRef<mlir::Value> typeParams,
+ const std::function<decltype(FirOpBuilder::genTempDeclareOp)> &genDeclare,
+ mlir::Value polymorphicMold, bool useStack, llvm::StringRef tmpName) {
+ if (polymorphicMold) {
+ // Create *allocated* polymorphic temporary using the dynamic type
+ // of the mold and the provided shape/extents. The created temporary
+ // array will be written element per element, that is why it has to be
+ // allocated.
+ mlir::Type boxHeapType = fir::HeapType::get(arrayType);
+ mlir::Value alloc = fir::factory::genNullBoxStorage(
+ *this, loc, fir::ClassType::get(boxHeapType));
+ fir::FortranVariableFlagsAttr declAttrs =
+ fir::FortranVariableFlagsAttr::get(
+ getContext(), fir::FortranVariableFlagsEnum::allocatable);
+
+ mlir::Value base = genDeclare(*this, loc, alloc, tmpName,
+ /*shape=*/nullptr, typeParams, declAttrs);
+
+ int rank = extents.size();
+ fir::runtime::genAllocatableApplyMold(*this, loc, alloc, polymorphicMold,
+ rank);
+ if (!extents.empty()) {
+ mlir::Type idxTy = getIndexType();
+ mlir::Value one = createIntegerConstant(loc, idxTy, 1);
+ unsigned dim = 0;
+ for (mlir::Value extent : extents) {
+ mlir::Value dimIndex = createIntegerConstant(loc, idxTy, dim++);
+ fir::runtime::genAllocatableSetBounds(*this, loc, alloc, dimIndex, one,
+ extent);
+ }
+ }
+ if (!typeParams.empty()) {
+ // We should call AllocatableSetDerivedLength() here.
+ // TODO: does the mold provide the length parameters or
+ // the operation itself or should they be in sync?
+ TODO(loc, "polymorphic type with length parameters");
+ }
+ fir::runtime::genAllocatableAllocate(*this, loc, alloc);
+
+ return {base, /*isHeapAllocation=*/true};
+ }
+ mlir::Value allocmem;
+ if (useStack)
+ allocmem = createTemporary(loc, arrayType, tmpName, extents, typeParams);
+ else
+ allocmem =
+ createHeapTemporary(loc, arrayType, tmpName, extents, typeParams);
+ mlir::Value base = genDeclare(*this, loc, allocmem, tmpName, shape,
+ typeParams, fir::FortranVariableFlagsAttr{});
+ return {base, !useStack};
+}
+
+mlir::Value fir::FirOpBuilder::genTempDeclareOp(
+ fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value memref,
+ llvm::StringRef name, mlir::Value shape,
+ llvm::ArrayRef<mlir::Value> typeParams,
+ fir::FortranVariableFlagsAttr fortranAttrs) {
+ auto nameAttr = mlir::StringAttr::get(builder.getContext(), name);
+ return builder.create<fir::DeclareOp>(loc, memref.getType(), memref, shape,
+ typeParams,
+ /*dummy_scope=*/nullptr, nameAttr,
+ fortranAttrs, cuf::DataAttributeAttr{});
+}
+
mlir::Value fir::FirOpBuilder::genStackSave(mlir::Location loc) {
mlir::Type voidPtr = mlir::LLVM::LLVMPointerType::get(
getContext(), fir::factory::getAllocaAddressSpace(&getDataLayout()));
@@ -1825,3 +1892,29 @@ llvm::SmallVector<mlir::Value> fir::factory::updateRuntimeExtentsForEmptyArrays(
}
return newExtents;
}
+
+void fir::factory::genDimInfoFromBox(
+ fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value box,
+ llvm::SmallVectorImpl<mlir::Value> *lbounds,
+ llvm::SmallVectorImpl<mlir::Value> *extents,
+ llvm::SmallVectorImpl<mlir::Value> *strides) {
+ auto boxType = mlir::dyn_cast<fir::BaseBoxType>(box.getType());
+ assert(boxType && "must be a box");
+ if (!lbounds && !extents && !strides)
+ return;
+
+ unsigned rank = fir::getBoxRank(boxType);
+ assert(rank != 0 && "must be an array of known rank");
+ mlir::Type idxTy = builder.getIndexType();
+ for (unsigned i = 0; i < rank; ++i) {
+ mlir::Value dim = builder.createIntegerConstant(loc, idxTy, i);
+ auto dimInfo =
+ builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy, box, dim);
+ if (lbounds)
+ lbounds->push_back(dimInfo.getLowerBound());
+ if (extents)
+ extents->push_back(dimInfo.getExtent());
+ if (strides)
+ strides->push_back(dimInfo.getByteStride());
+ }
+}
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 85fd742db6beb..06a3e177da1d0 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -95,24 +95,6 @@ getExplicitLbounds(fir::FortranVariableOpInterface var) {
return {};
}
-static void
-genLboundsAndExtentsFromBox(mlir::Location loc, fir::FirOpBuilder &builder,
- hlfir::Entity boxEntity,
- llvm::SmallVectorImpl<mlir::Value> &lbounds,
- llvm::SmallVectorImpl<mlir::Value> *extents) {
- assert(mlir::isa<fir::BaseBoxType>(boxEntity.getType()) && "must be a box");
- mlir::Type idxTy = builder.getIndexType();
- const int rank = boxEntity.getRank();
- for (int i = 0; i < rank; ++i) {
- mlir::Value dim = builder.createIntegerConstant(loc, idxTy, i);
- auto dimInfo = builder.create<fir::BoxDimsOp>(loc, idxTy, idxTy, idxTy,
- boxEntity, dim);
- lbounds.push_back(dimInfo.getLowerBound());
- if (extents)
- extents->push_back(dimInfo.getExtent());
- }
-}
-
static llvm::SmallVector<mlir::Value>
getNonDefaultLowerBounds(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity entity) {
@@ -128,8 +110,8 @@ getNonDefaultLowerBounds(mlir::Location loc, fir::FirOpBuilder &builder,
if (entity.isMutableBox())
entity = hlfir::derefPointersAndAllocatables(loc, builder, entity);
llvm::SmallVector<mlir::Value> lowerBounds;
- genLboundsAndExtentsFromBox(loc, builder, entity, lowerBounds,
- /*extents=*/nullptr);
+ fir::factory::genDimInfoFromBox(builder, loc, entity, &lowerBounds,
+ /*extents=*/nullptr, /*strides=*/nullptr);
return lowerBounds;
}
@@ -1149,8 +1131,8 @@ static fir::ExtendedValue translateVariableToExtendedValue(
variable.mayHaveNonDefaultLowerBounds()) {
// This special case avoids generating two sets of identical
// fir.box_dim to get both the lower bounds and extents.
- genLboundsAndExtentsFromBox(loc, builder, variable, nonDefaultLbounds,
- &extents);
+ fir::factory::genDimInfoFromBox(builder, loc, variable, &nonDefaultLbounds,
+ &extents, /*strides=*/nullptr);
} else {
extents = getVariableExtents(loc, builder, variable);
nonDefaultLbounds = getNonDefaultLowerBounds(loc, builder, variable);
diff --git a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
index 8e00fcf49dd88..170e648d77fe4 100644
--- a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
+++ b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
@@ -29,7 +29,6 @@
#include "flang/Optimizer/CodeGen/CodeGen.h"
-#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/MutableBox.h"
@@ -39,7 +38,6 @@
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
-#include "flang/Optimizer/Support/DataLayout.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
@@ -51,26 +49,10 @@ namespace fir {
#define DEBUG_TYPE "lower-repack-arrays"
namespace {
-class RepackArrayConversion {
-public:
- RepackArrayConversion(std::optional<mlir::DataLayout> dataLayout)
- : dataLayout(dataLayout) {}
-
-protected:
- std::optional<mlir::DataLayout> dataLayout;
-
- static bool canAllocateTempOnStack(mlir::Value box);
-};
-
-class PackArrayConversion : public mlir::OpRewritePattern<fir::PackArrayOp>,
- RepackArrayConversion {
+class PackArrayConversion : public mlir::OpRewritePattern<fir::PackArrayOp> {
public:
using OpRewritePattern::OpRewritePattern;
- PackArrayConversion(mlir::MLIRContext *context,
- std::optional<mlir::DataLayout> dataLayout)
- : OpRewritePattern(context), RepackArrayConversion(dataLayout) {}
-
mlir::LogicalResult
matchAndRewrite(fir::PackArrayOp op,
mlir::PatternRewriter &rewriter) const override;
@@ -78,29 +60,48 @@ class PackArrayConversion : public mlir::OpRewritePattern<fir::PackArrayOp>,
private:
static constexpr llvm::StringRef bufferName = ".repacked";
+ // Return value of fir::BaseBoxType that represents a temporary
+ // array created for the original box with given extents and
+ // type parameters. The new box has the default lower bounds.
+ // If useStack is true, then the temporary will be allocated
+ // in stack memory (when possible).
static mlir::Value allocateTempBuffer(fir::FirOpBuilder &builder,
mlir::Location loc, bool useStack,
mlir::Value origBox,
llvm::ArrayRef<mlir::Value> extents,
llvm::ArrayRef<mlir::Value> typeParams);
+
+ // Generate value of fir::BaseBoxType that represents the result
+ // of the given fir.pack_array operation. The original box
+ // is assumed to be present (though, it may represent an empty array).
+ static mlir::FailureOr<mlir::Value> genRepackedBox(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ fir::PackArrayOp packOp);
};
-class UnpackArrayConversion : public mlir::OpRewritePattern<fir::UnpackArrayOp>,
- RepackArrayConversion {
+class UnpackArrayConversion
+ : public mlir::OpRewritePattern<fir::UnpackArrayOp> {
public:
using OpRewritePattern::OpRewritePattern;
- UnpackArrayConversion(mlir::MLIRContext *context,
- std::optional<mlir::DataLayout> dataLayout)
- : OpRewritePattern(context), RepackArrayConversion(dataLayout) {}
-
mlir::LogicalResult
matchAndRewrite(fir::UnpackArrayOp op,
mlir::PatternRewriter &rewriter) const override;
};
} // anonymous namespace
-bool RepackArrayConversion::canAllocateTempOnStack(mlir::Value box) {
+// Return true iff for the given original boxed array we can
+// allocate temporary memory in stack memory.
+// This function is used to synchronize allocation/deallocation
+// implied by fir.pack_array and fir.unpack_array, because
+// the presence of the stack attribute does not automatically
+// mean that the allocation is actually done in stack memory.
+// For example, we always do the heap allocation for polymorphic
+// types using Fortran runtime.
+// Adding the polymorpic mold to fir.alloca and then using
+// Fortran runtime to compute the allocation size could probably
+// resolve this limitation.
+static bool canAllocateTempOnStack(mlir::Value box) {
return !fir::isPolymorphicType(box.getType());
}
@@ -115,181 +116,26 @@ PackArrayConversion::matchAndRewrite(fir::PackArrayOp op,
TODO(loc, "fir.pack_array with heuristics");
mlir::Value box = op.getArray();
- llvm::SmallVector<mlir::Value> typeParams(op.getTypeparams().begin(),
- op.getTypeparams().end());
- // TODO: set non-default lower bounds on fir.pack_array,
- // so that we can preserve lower bounds in the temporary box.
- fir::BoxValue boxValue(box, /*lbounds=*/{}, typeParams);
- mlir::Type boxType = boxValue.getBoxTy();
- unsigned rank = boxValue.rank();
- mlir::Type indexType = builder.getIndexType();
- mlir::Value zero = fir::factory::createZeroValue(builder, loc, indexType);
-
- // Fetch the extents from the box, and see if the array
- // is not empty.
- // If the type params are not explicitly provided, then we must also
- // fetch the type parameters from the box.
- //
- // bool isNotEmpty;
- // vector<int64_t> extents;
- // if (IsPresent(box) && !IsContiguous[UpTo](box[, 1])) {
- // isNotEmpty = box->base_addr != null;
- // extents = SHAPE(box);
- // } else {
- // isNotEmpty = false;
- // extents = vector<int64_t>(rank, 0);
- // }
-
- unsigned numTypeParams = 0;
- if (typeParams.size() == 0) {
- if (auto recordType = mlir::dyn_cast<fir::RecordType>(boxValue.getEleTy()))
- if (recordType.getNumLenParams() != 0)
- TODO(loc,
- "allocating temporary for a parameterized derived type array");
-
- if (auto charType = mlir::dyn_cast<fir::CharacterType>(boxValue.getEleTy()))
- if (charType.hasDynamicLen())
- numTypeParams = 1;
- }
+ auto boxType = mlir::cast<fir::BaseBoxType>(box.getType());
// For now we have to always check if the box is present.
- mlir::Type predicateType = builder.getI1Type();
auto isPresent =
- builder.create<fir::IsPresentOp>(loc, predicateType, boxValue.getAddr());
-
- // The results of the IfOp are:
- // (extent1, ..., extentN, typeParam1, ..., typeParamM, isNotEmpty)
- // The number of results is rank + numTypeParams + 1.
- llvm::SmallVector<mlir::Type> ifTypes(rank + numTypeParams, indexType);
- ifTypes.push_back(predicateType);
- llvm::SmallVector<mlir::Value> negativeResult(rank + numTypeParams, zero);
- negativeResult.push_back(
- fir::factory::createZeroValue(builder, loc, predicateType));
- bool failedTypeParams = false;
- llvm::SmallVector<mlir::Value> extentsAndPredicate =
- builder
- .genIfOp(loc, ifTypes, isPresent,
- /*withElseRegion=*/true)
- .genThen([&]() {
- // The box is present.
- auto isContiguous = builder.create<fir::IsContiguousBoxOp>(
- loc, box, op.getInnermost());
- llvm::SmallVector<mlir::Value> extentsAndPredicate =
- builder
- .genIfOp(loc, ifTypes, isContiguous,
- /*withElseRegion=*/true)
- .genThen([&]() {
- // Box is contiguous, return zero.
- builder.create<fir::ResultOp>(loc, negativeResult);
- })
- .genElse([&]() {
- // Get the extents.
- llvm::SmallVector<mlir::Value> results =
- fir::factory::readExtents(builder, loc, boxValue);
-
- // Get the type parameters from the box, if needed.
- llvm::SmallVector<mlir::Value> assumedTypeParams;
- if (numTypeParams != 0) {
- if (auto charType = mlir::dyn_cast<fir::CharacterType>(
- boxValue.getEleTy()))
- if (charType.hasDynamicLen()) {
- fir::factory::CharacterExprHelper charHelper(
- builder, loc);
- mlir::Value len = charHelper.readLengthFromBox(
- boxValue.getAddr(), charType);
- assumedTypeParams.push_back(
- builder.createConvert(loc, indexType, len));
- }
-
- if (numTypeParams != assumedTypeParams.size()) {
- failedTypeParams = true;
- assumedTypeParams.append(
- numTypeParams - assumedTypeParams.size(), zero);
- }
- }
- results.append(assumedTypeParams);
-
- auto dataAddr = builder.create<fir::BoxAddrOp>(
- loc, boxValue.getMemTy(), boxValue.getAddr());
- auto isNotEmpty = builder.create<fir::IsPresentOp>(
- loc, predicateType, dataAddr);
- results.push_back(isNotEmpty);
- builder.create<fir::ResultOp>(loc, results);
- })
- .getResults();
-
- builder.create<fir::ResultOp>(loc, extentsAndPredicate);
- })
- .genElse([&]() {
- // Box is absent, nothing to do.
- builder.create<fir::ResultOp>(loc, negativeResult);
- })
- .getResults();
-
- if (failedTypeParams)
- return emitError(loc) << "failed to compute the type parameters for "
- << op.getOperation() << '\n';
-
- // The last result is the isNotEmpty predicate value.
- mlir::Value isNotEmpty = extentsAndPredicate.pop_back_val();
- // If fir.pack_array does not specify type parameters, but they are needed
- // for the type, then use the parameters fetched from the box.
- if (typeParams.size() == 0 && numTypeParams != 0) {
- assert(extentsAndPredicate.size() > numTypeParams);
- typeParams.append(extentsAndPredicate.end() - numTypeParams,
- extentsAndPredicate.end());
- extentsAndPredicate.pop_back_n(numTypeParams);
- }
- // The remaining resulst are the extents.
- llvm::SmallVector<mlir::Value> extents = std::move(extentsAndPredicate);
- assert(extents.size() == rank);
-
- mlir::Value tempBox;
- // Allocate memory for the temporary, if allocating on stack.
- // We can do it unconditionally, even if size is zero.
- if (op.getStack() && canAllocateTempOnStack(boxValue.getAddr())) {
- tempBox = allocateTempBuffer(builder, loc, /*useStack=*/true,
- boxValue.getAddr(), extents, typeParams);
- if (!tempBox)
- return rewriter.notifyMatchFailure(op,
- "failed to produce stack allocation");
- }
-
- mlir::Value newResult =
- builder.genIfOp(loc, {boxType}, isNotEmpty, /*withElseRegion=*/true)
- .genThen([&]() {
- // Do the heap allocation conditionally.
- if (!tempBox)
- tempBox =
- allocateTempBuffer(builder, loc, /*useStack=*/false,
- boxValue.getAddr(), extents, typeParams);
-
- // Do the copy, if needed, and return the new box (shaped same way
- // as the original one).
- if (!op.getNoCopy())
- fir::runtime::genShallowCopy(builder, loc, tempBox,
- boxValue.getAddr(),
- /*resultIsAllocated=*/true);
-
- // Set the lower bounds after the original box.
- mlir::Value shape;
- if (!boxValue.getLBounds().empty()) {
- shape = builder.genShape(loc, boxValue.getLBounds(), extents);
- }
-
- // Rebox the temporary box to make its type the same as
- // the original box's.
- tempBox = builder.create<fir::ReboxOp>(loc, boxType, tempBox, shape,
- /*slice=*/nullptr);
- builder.create<fir::ResultOp>(loc, tempBox);
- })
- .genElse([&]() {
- // Return original box.
- builder.create<fir::ResultOp>(loc, boxValue.getAddr());
- })
- .getResults()[0];
-
- rewriter.replaceOp(op, newResult);
+ builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), box);
+
+ fir::IfOp ifOp = builder.create<fir::IfOp>(loc, boxType, isPresent,
+ /*withElseRegion=*/true);
+ builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
+ // The box is present.
+ auto newBox = genRepackedBox(builder, loc, op);
+ if (mlir::failed(newBox))
+ return newBox;
+ builder.create<fir::ResultOp>(loc, *newBox);
+
+ // The box is not present. Return original box.
+ builder.setInsertionPointToStart(&ifOp.getElseRegion().front());
+ builder.create<fir::ResultOp>(loc, box);
+
+ rewriter.replaceOp(op, ifOp.getResult(0));
return mlir::success();
}
@@ -302,61 +148,123 @@ mlir::Value PackArrayConversion::allocateTempBuffer(
assert(tempType.getDimension() == extents.size() &&
"number of extents does not match the rank");
- if (fir::isPolymorphicType(origBox.getType())) {
- // Use runtime to allocate polymorphic temporary vector using the dynamic
- // type of the original box and the provided numElements.
- // TODO: try to generalize it with BufferizeHLFIR.cpp:createArrayTemp().
-
- // We cannot allocate polymorphic entity on stack.
- // Return null, and allow the caller to reissue the call.
- if (useStack)
- return nullptr;
-
- mlir::Type indexType = builder.getIndexType();
- mlir::Type boxHeapType = fir::HeapType::get(tempType);
- mlir::Value boxAlloc = fir::factory::genNullBoxStorage(
- builder, loc, fir::ClassType::get(boxHeapType));
- fir::runtime::genAllocatableApplyMold(builder, loc, boxAlloc, origBox,
- tempType.getDimension());
- mlir::Value one = builder.createIntegerConstant(loc, indexType, 1);
- unsigned dim = 0;
- for (mlir::Value extent : extents) {
- mlir::Value dimIndex =
- builder.createIntegerConstant(loc, indexType, dim++);
- fir::runtime::genAllocatableSetBounds(builder, loc, boxAlloc, dimIndex,
- one, extent);
- }
-
- if (!typeParams.empty()) {
- // We should call AllocatableSetDerivedLength() here.
- TODO(loc,
- "polymorphic type with length parameters in PackArrayConversion");
- }
-
- fir::runtime::genAllocatableAllocate(builder, loc, boxAlloc);
- return builder.create<fir::LoadOp>(loc, boxAlloc);
- }
-
- // Allocate non-polymorphic temporary on stack or in heap.
- mlir::Value newBuffer;
- if (useStack)
- newBuffer =
- builder.createTemporary(loc, tempType, bufferName, extents, typeParams);
- else
- newBuffer = builder.createHeapTemporary(loc, tempType, bufferName, extents,
- typeParams);
-
- mlir::Type ptrType = newBuffer.getType();
+ mlir::Value shape = builder.genShape(loc, extents);
+ auto [base, isHeapAllocation] = builder.createArrayTemp(
+ loc, tempType, shape, extents, typeParams,
+ fir::FirOpBuilder::genTempDeclareOp,
+ fir::isPolymorphicType(origBox.getType()) ? origBox : nullptr, useStack,
+ bufferName);
+ // Make sure canAllocateTempOnStack() can recognize when
+ // the temporary is actually allocated on the stack
+ // by createArrayTemp(). Otherwise, we may miss dynamic
+ // deallocation when lowering fir.unpack_array.
+ if (useStack && canAllocateTempOnStack(origBox))
+ assert(!isHeapAllocation && "temp must have been allocated on the stack");
+
+ if (isHeapAllocation)
+ if (auto baseType = mlir::dyn_cast<fir::ReferenceType>(base.getType()))
+ if (mlir::isa<fir::BaseBoxType>(baseType.getEleTy()))
+ return builder.create<fir::LoadOp>(loc, base);
+
+ mlir::Type ptrType = base.getType();
mlir::Type tempBoxType = fir::BoxType::get(mlir::isa<fir::HeapType>(ptrType)
? ptrType
: fir::unwrapRefType(ptrType));
- mlir::Value shape = builder.genShape(loc, extents);
mlir::Value newBox =
- builder.createBox(loc, tempBoxType, newBuffer, shape, /*slice=*/nullptr,
+ builder.createBox(loc, tempBoxType, base, shape, /*slice=*/nullptr,
typeParams, /*tdesc=*/nullptr);
return newBox;
}
+mlir::FailureOr<mlir::Value>
+PackArrayConversion::genRepackedBox(fir::FirOpBuilder &builder,
+ mlir::Location loc, fir::PackArrayOp op) {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ mlir::Value box = op.getArray();
+ llvm::SmallVector<mlir::Value> typeParams(op.getTypeparams().begin(),
+ op.getTypeparams().end());
+ auto boxType = mlir::cast<fir::BaseBoxType>(box.getType());
+ mlir::Type indexType = builder.getIndexType();
+
+ // If type parameters are not specified by fir.pack_array,
+ // figure out how many of them we need to read from the box.
+ unsigned numTypeParams = 0;
+ if (typeParams.size() == 0) {
+ if (auto recordType =
+ mlir::dyn_cast<fir::RecordType>(boxType.unwrapInnerType()))
+ if (recordType.getNumLenParams() != 0)
+ TODO(loc,
+ "allocating temporary for a parameterized derived type array");
+
+ if (auto charType =
+ mlir::dyn_cast<fir::CharacterType>(boxType.unwrapInnerType())) {
+ if (charType.hasDynamicLen()) {
+ // Read one length parameter from the box.
+ numTypeParams = 1;
+ } else {
+ // Place the constant length into typeParams.
+ mlir::Value length =
+ builder.createIntegerConstant(loc, indexType, charType.getLen());
+ typeParams.push_back(length);
+ }
+ }
+ }
+
+ // Create a temporay iff the original is not contigous and is not empty.
+ auto isNotContiguous = builder.genNot(
+ loc, builder.create<fir::IsContiguousBoxOp>(loc, box, op.getInnermost()));
+ auto dataAddr =
+ builder.create<fir::BoxAddrOp>(loc, fir::boxMemRefType(boxType), box);
+ auto isNotEmpty =
+ builder.create<fir::IsPresentOp>(loc, builder.getI1Type(), dataAddr);
+ auto doPack =
+ builder.create<mlir::arith::AndIOp>(loc, isNotContiguous, isNotEmpty);
+
+ fir::IfOp ifOp =
+ builder.create<fir::IfOp>(loc, boxType, doPack, /*withElseRegion=*/true);
+
+ // Return original box.
+ builder.setInsertionPointToStart(&ifOp.getElseRegion().front());
+ builder.create<fir::ResultOp>(loc, box);
+
+ // Create a new box.
+ builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
+
+ // Get lower bounds and extents from the box.
+ llvm::SmallVector<mlir::Value, Fortran::common::maxRank> lbounds, extents;
+ fir::factory::genDimInfoFromBox(builder, loc, box, &lbounds, &extents,
+ /*strides=*/nullptr);
+ // Get the type parameters from the box, if needed.
+ llvm::SmallVector<mlir::Value> assumedTypeParams;
+ if (numTypeParams != 0) {
+ if (auto charType =
+ mlir::dyn_cast<fir::CharacterType>(boxType.unwrapInnerType()))
+ if (charType.hasDynamicLen()) {
+ fir::factory::CharacterExprHelper charHelper(builder, loc);
+ mlir::Value len = charHelper.readLengthFromBox(box, charType);
+ typeParams.push_back(builder.createConvert(loc, indexType, len));
+ }
+
+ if (numTypeParams != typeParams.size())
+ return emitError(loc) << "failed to compute the type parameters for "
+ << op.getOperation() << '\n';
+ }
+
+ mlir::Value tempBox =
+ allocateTempBuffer(builder, loc, op.getStack(), box, extents, typeParams);
+ if (!op.getNoCopy())
+ fir::runtime::genShallowCopy(builder, loc, tempBox, box,
+ /*resultIsAllocated=*/true);
+
+ // Set lower bounds after the original box.
+ mlir::Value shift = builder.genShift(loc, lbounds);
+ tempBox = builder.create<fir::ReboxOp>(loc, boxType, tempBox, shift,
+ /*slice=*/nullptr);
+ builder.create<fir::ResultOp>(loc, tempBox);
+
+ return ifOp.getResult(0);
+}
+
mlir::LogicalResult
UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op,
mlir::PatternRewriter &rewriter) const {
@@ -391,7 +299,12 @@ UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op,
/*resultIsAllocated=*/true);
// Deallocate, if it was allocated in heap.
- if (!op.getStack())
+ // Note that the stack attribute does not always mean
+ // that the allocation was actually done in stack memory.
+ // There are currently cases where we delegate the allocation
+ // to the runtime that uses heap memory, even when the stack
+ // attribute is set on fir.pack_array.
+ if (!op.getStack() || !canAllocateTempOnStack(originalBox))
builder.create<fir::FreeMemOp>(loc, tempAddr);
});
rewriter.eraseOp(op);
@@ -408,11 +321,9 @@ class LowerRepackArraysPass
void runOnOperation() override final {
auto *context = &getContext();
mlir::ModuleOp module = getOperation();
- std::optional<mlir::DataLayout> dl = fir::support::getOrSetMLIRDataLayout(
- module, /*allowDefaultLayout=*/false);
mlir::RewritePatternSet patterns(context);
- patterns.insert<PackArrayConversion>(context, dl);
- patterns.insert<UnpackArrayConversion>(context, dl);
+ patterns.insert<PackArrayConversion>(context);
+ patterns.insert<UnpackArrayConversion>(context);
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification =
mlir::GreedySimplifyRegionLevel::Disabled;
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
index 30e7ef7890953..68d286aa29a6a 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
@@ -105,9 +105,28 @@ static mlir::Value getBufferizedExprMustFreeFlag(mlir::Value bufferizedExpr) {
static std::pair<hlfir::Entity, mlir::Value>
createArrayTemp(mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Type exprType, mlir::Value shape,
- mlir::ValueRange extents, mlir::ValueRange lenParams,
+ llvm::ArrayRef<mlir::Value> extents,
+ llvm::ArrayRef<mlir::Value> lenParams,
std::optional<hlfir::Entity> polymorphicMold) {
- mlir::Type sequenceType = hlfir::getFortranElementOrSequenceType(exprType);
+ auto sequenceType = mlir::cast<fir::SequenceType>(
+ hlfir::getFortranElementOrSequenceType(exprType));
+
+ auto genTempDeclareOp =
+ [](fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value memref,
+ llvm::StringRef name, mlir::Value shape,
+ llvm::ArrayRef<mlir::Value> typeParams,
+ fir::FortranVariableFlagsAttr attrs) -> mlir::Value {
+ auto declareOp =
+ builder.create<hlfir::DeclareOp>(loc, memref, name, shape, typeParams,
+ /*dummy_scope=*/nullptr, attrs);
+ return declareOp.getBase();
+ };
+
+ auto [base, isHeapAlloc] = builder.createArrayTemp(
+ loc, sequenceType, shape, extents, lenParams, genTempDeclareOp,
+ polymorphicMold ? polymorphicMold->getFirBase() : nullptr);
+ return {hlfir::Entity{base}, builder.createBool(loc, isHeapAlloc)};
+#if 0
llvm::StringRef tmpName{".tmp.array"};
if (polymorphicMold) {
@@ -159,6 +178,7 @@ createArrayTemp(mlir::Location loc, fir::FirOpBuilder &builder,
/*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
mlir::Value trueVal = builder.createBool(loc, true);
return {hlfir::Entity{declareOp.getBase()}, trueVal};
+#endif
}
/// Copy \p source into a new temporary and package the temporary into a
@@ -786,9 +806,10 @@ struct ElementalOpConversion
if (adaptor.getMold())
mold = getBufferizedExprStorage(adaptor.getMold());
auto extents = hlfir::getIndexExtents(loc, builder, shape);
- auto [temp, cleanup] =
- createArrayTemp(loc, builder, elemental.getType(), shape, extents,
- adaptor.getTypeparams(), mold);
+ llvm::SmallVector<mlir::Value> typeParams(adaptor.getTypeparams().begin(),
+ adaptor.getTypeparams().end());
+ auto [temp, cleanup] = createArrayTemp(loc, builder, elemental.getType(),
+ shape, extents, typeParams, mold);
// If the box load is needed, we'd better place it outside
// of the loop nest.
temp = derefPointersAndAllocatables(loc, builder, temp);
diff --git a/flang/test/HLFIR/elemental-codegen.fir b/flang/test/HLFIR/elemental-codegen.fir
index 2443217f557f8..c05c05cfa0413 100644
--- a/flang/test/HLFIR/elemental-codegen.fir
+++ b/flang/test/HLFIR/elemental-codegen.fir
@@ -166,7 +166,6 @@ func.func @test_polymorphic(%arg0: !fir.class<!fir.type<_QMtypesTt>> {fir.bindc_
// CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_9]], %[[VAL_9]] : (index, index) -> !fir.shape<2>
// CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_8]](%[[VAL_10]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>
// CHECK: fir.store %[[VAL_11]] to %[[VAL_4]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>
-// CHECK: %[[VAL_12:.*]] = arith.constant true
// CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".tmp.array"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>)
// CHECK: %[[RANK:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> !fir.ref<!fir.box<none>>
@@ -193,6 +192,7 @@ func.func @test_polymorphic(%arg0: !fir.class<!fir.type<_QMtypesTt>> {fir.bindc_
// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_31]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
// CHECK: %[[VAL_38:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_36]], %[[VAL_34]], %[[VAL_35]], %[[VAL_37]], %[[VAL_33]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_12:.*]] = arith.constant true
// CHECK: %[[VAL_39:.*]] = fir.load %[[VAL_13]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>
// CHECK: %[[VAL_40:.*]] = arith.constant 1 : index
// CHECK: fir.do_loop %[[VAL_41:.*]] = %[[VAL_40]] to %[[EX1]] step %[[VAL_40]] unordered {
@@ -250,7 +250,6 @@ func.func @test_polymorphic_expr(%arg0: !fir.class<!fir.type<_QMtypesTt>> {fir.b
// CHECK: %[[VAL_11:.*]] = fir.shape %[[VAL_10]], %[[VAL_10]] : (index, index) -> !fir.shape<2>
// CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_9]](%[[VAL_11]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>
// CHECK: fir.store %[[VAL_12]] to %[[VAL_5]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>
-// CHECK: %[[VAL_13:.*]] = arith.constant true
// CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_5]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".tmp.array"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>)
// CHECK: %[[VAL_15:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> !fir.ref<!fir.box<none>>
@@ -277,6 +276,7 @@ func.func @test_polymorphic_expr(%arg0: !fir.class<!fir.type<_QMtypesTt>> {fir.b
// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_5]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_32]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
// CHECK: %[[VAL_39:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_37]], %[[VAL_35]], %[[VAL_36]], %[[VAL_38]], %[[VAL_34]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_13:.*]] = arith.constant true
// CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>
// CHECK: %[[VAL_41:.*]] = arith.constant 1 : index
// CHECK: fir.do_loop %[[VAL_42:.*]] = %[[VAL_41]] to %[[VAL_3]] step %[[VAL_41]] unordered {
@@ -303,7 +303,6 @@ func.func @test_polymorphic_expr(%arg0: !fir.class<!fir.type<_QMtypesTt>> {fir.b
// CHECK: %[[VAL_60:.*]] = fir.shape %[[VAL_59]], %[[VAL_59]] : (index, index) -> !fir.shape<2>
// CHECK: %[[VAL_61:.*]] = fir.embox %[[VAL_58]](%[[VAL_60]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>
// CHECK: fir.store %[[VAL_61]] to %[[VAL_4]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>
-// CHECK: %[[VAL_62:.*]] = arith.constant true
// CHECK: %[[VAL_63:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".tmp.array"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>, !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>)
// CHECK: %[[VAL_64:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> !fir.ref<!fir.box<none>>
@@ -330,6 +329,7 @@ func.func @test_polymorphic_expr(%arg0: !fir.class<!fir.type<_QMtypesTt>> {fir.b
// CHECK: %[[VAL_86:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[VAL_87:.*]] = fir.convert %[[VAL_81]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
// CHECK: %[[VAL_88:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_86]], %[[VAL_84]], %[[VAL_85]], %[[VAL_87]], %[[VAL_83]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_62:.*]] = arith.constant true
// CHECK: %[[VAL_89:.*]] = fir.load %[[VAL_63]]#0 : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMtypesTt>>>>>
// CHECK: %[[VAL_90:.*]] = arith.constant 1 : index
// CHECK: fir.do_loop %[[VAL_91:.*]] = %[[VAL_90]] to %[[VAL_3]] step %[[VAL_90]] unordered {
diff --git a/flang/test/Transforms/lower-repack-arrays.fir b/flang/test/Transforms/lower-repack-arrays.fir
index b09363e62f78b..c1db3e2ce9c05 100644
--- a/flang/test/Transforms/lower-repack-arrays.fir
+++ b/flang/test/Transforms/lower-repack-arrays.fir
@@ -1,1124 +1,1141 @@
// RUN: fir-opt --lower-repack-arrays %s | FileCheck %s
-
// Test trivial type array repacking.
+func.func @_QPtest1(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?xf32>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest1(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-func.func @_QPtest1(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x?xf32>>) {
// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.box<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref<!fir.box<!fir.array<?x?xf32>>>) -> i1
+// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_19:.*]] = fir.declare %[[VAL_18]](%[[VAL_17]]) {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.shift %[[VAL_15]]#0, %[[VAL_16]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]](%[[VAL_25]]) : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
-// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
-// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
-// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<none>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_14]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.if %[[VAL_27]] {
-// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
-// CHECK: fir.if %[[VAL_32]] {
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_28]] : !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1Ex"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_29]] : !fir.heap<!fir.array<?x?xf32>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?xf32>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test 'stack whole' repacking.
+func.func @_QPtest1_whole(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 stack whole : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1_wholeEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?xf32>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest1_whole(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-func.func @_QPtest1_whole(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x?xf32>>) {
// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] whole : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.box<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref<!fir.box<!fir.array<?x?xf32>>>) -> i1
+// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_18:.*]] = fir.alloca !fir.array<?x?xf32>, %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_19:.*]] = fir.declare %[[VAL_18]](%[[VAL_17]]) {uniq_name = ".repacked"} : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.ref<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.shift %[[VAL_15]]#0, %[[VAL_16]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]](%[[VAL_25]]) : (!fir.box<!fir.array<?x?xf32>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
-// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_16:.*]] = fir.alloca !fir.array<?x?xf32>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked"}
-// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_16]](%[[VAL_18]]) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
-// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_14]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
- %1 = fir.pack_array %arg0 stack whole : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1_wholeEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1_wholeEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.if %[[VAL_27]] {
-// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
-// CHECK: fir.if %[[VAL_32]] {
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1_wholeEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?xf32>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test unpacking with no_copy.
+func.func @_QPtest1_in(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest1_inEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ fir.unpack_array %1 to %arg0 heap no_copy : !fir.box<!fir.array<?x?xf32>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest1_in(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-func.func @_QPtest1_in(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_3:.*]] = arith.constant false
-// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
// CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_6:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) {
+// CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.box<!fir.array<?x?xf32>>) {
// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
+// CHECK: %[[VAL_9:.*]] = arith.cmpi eq, %[[VAL_8]], %[[VAL_4]] : i1
+// CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.box<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref<!fir.box<!fir.array<?x?xf32>>>) -> i1
+// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1
+// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]]#1, %[[VAL_15]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_14]]#1, %[[VAL_15]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_18:.*]] = fir.declare %[[VAL_17]](%[[VAL_16]]) {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_18]](%[[VAL_16]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<none>
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_24:.*]] = fir.shift %[[VAL_14]]#0, %[[VAL_15]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]](%[[VAL_24]]) : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
-// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.result %[[VAL_10]]#1, %[[VAL_11]]#1, %[[VAL_13]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
-// CHECK: fir.result %[[VAL_9]]#0, %[[VAL_9]]#1, %[[VAL_9]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_7]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
-// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_7]]#0, %[[VAL_7]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_7]]#0, %[[VAL_7]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_17]](%[[VAL_18]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
-// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<none>
-// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_24:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: fir.result %[[VAL_24]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_13]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_25:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest1_inEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
- %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest1_inEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_26:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.if %[[VAL_26]] {
-// CHECK: %[[VAL_27:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_31:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_30]] : index
-// CHECK: fir.if %[[VAL_31]] {
-// CHECK: fir.freemem %[[VAL_27]] : !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_7]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest1_inEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_27]] {
+// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_31]] : index
+// CHECK: fir.if %[[VAL_32]] {
+// CHECK: fir.freemem %[[VAL_28]] : !fir.heap<!fir.array<?x?xf32>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap no_copy : !fir.box<!fir.array<?x?xf32>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test packing with no_copy.
+func.func @_QPtest1_out(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost no_copy : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
+ %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QFtest1_outEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?xf32>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest1_out(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-func.func @_QPtest1_out(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_3:.*]] = arith.constant false
-// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant false
// CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_6:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) {
+// CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.box<!fir.array<?x?xf32>>) {
// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
+// CHECK: %[[VAL_9:.*]] = arith.cmpi eq, %[[VAL_8]], %[[VAL_4]] : i1
+// CHECK: %[[VAL_10:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.box<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref<!fir.box<!fir.array<?x?xf32>>>) -> i1
+// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1
+// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] -> (!fir.box<!fir.array<?x?xf32>>) {
+// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_14]]#1, %[[VAL_15]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_14]]#1, %[[VAL_15]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_18:.*]] = fir.declare %[[VAL_17]](%[[VAL_16]]) {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_18]](%[[VAL_16]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
+// CHECK: %[[VAL_20:.*]] = fir.shift %[[VAL_14]]#0, %[[VAL_15]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_21:.*]] = fir.rebox %[[VAL_19]](%[[VAL_20]]) : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_21]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
-// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.result %[[VAL_10]]#1, %[[VAL_11]]#1, %[[VAL_13]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
-// CHECK: fir.result %[[VAL_9]]#0, %[[VAL_9]]#1, %[[VAL_9]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_4]], %[[VAL_4]], %[[VAL_3]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_7]]#2 -> (!fir.box<!fir.array<?x?xf32>>) {
-// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array<?x?xf32>, %[[VAL_7]]#0, %[[VAL_7]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_7]]#0, %[[VAL_7]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_17]](%[[VAL_18]]) : (!fir.heap<!fir.array<?x?xf32>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?xf32>>>
-// CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x?xf32>>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: fir.result %[[VAL_20]] : !fir.box<!fir.array<?x?xf32>>
+// CHECK: fir.result %[[VAL_13]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?xf32>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost no_copy : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_21:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QFtest1_outEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
- %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QFtest1_outEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_22:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
-// CHECK: fir.if %[[VAL_22]] {
-// CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_23]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
-// CHECK: %[[VAL_27:.*]] = arith.cmpi ne, %[[VAL_25]], %[[VAL_26]] : index
-// CHECK: fir.if %[[VAL_27]] {
-// CHECK: %[[VAL_28:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_23]] : !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs<intent_out>, uniq_name = "_QFtest1_outEx"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> !fir.box<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_23:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
+// CHECK: fir.if %[[VAL_23]] {
+// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_26:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
+// CHECK: %[[VAL_28:.*]] = arith.cmpi ne, %[[VAL_25]], %[[VAL_27]] : index
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_7]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.box<none>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_29]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_30]], %[[VAL_31]], %[[VAL_32]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_24]] : !fir.heap<!fir.array<?x?xf32>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?xf32>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test character array with dynamic length and heap allocation
+func.func @_QPtest2(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+ %c0_i32 = arith.constant 0 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2En"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %2 = fir.load %1 : !fir.ref<i32>
+ %3 = arith.cmpi sgt, %2, %c0_i32 : i32
+ %4 = arith.select %3, %2, %c0_i32 : i32
+ %5 = fir.pack_array %arg1 heap innermost typeparams %4 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ fir.unpack_array %5 to %arg1 heap : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest2(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<i32> {fir.bindc_name = "n"},
// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest2(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_3:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant
+// CHECK: %[[VAL_3:.*]] = arith.constant
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_5:.*]] = arith.constant false
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant false
// CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
- %c0_i32 = arith.constant 0 : i32
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2En"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
- %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2En"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
- %2 = fir.load %1 : !fir.ref<i32>
// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_10]], %[[VAL_7]] : i32
- %3 = arith.cmpi sgt, %2, %c0_i32 : i32
// CHECK: %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_10]], %[[VAL_7]] : i32
- %4 = arith.select %3, %2, %c0_i32 : i32
// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) {
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
// CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: %[[VAL_16:.*]] = arith.cmpi eq, %[[VAL_15]], %[[VAL_6]] : i1
+// CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_18:.*]] = fir.is_present %[[VAL_17]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>) -> i1
+// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1
+// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_22:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_23:.*]] = fir.shape %[[VAL_21]]#1, %[[VAL_22]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,?>>(%[[VAL_12]] : i32), %[[VAL_21]]#1, %[[VAL_22]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_25:.*]] = fir.declare %[[VAL_24]](%[[VAL_23]]) typeparams %[[VAL_12]] {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_25]](%[[VAL_23]]) typeparams %[[VAL_12]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_31:.*]] = fir.shift %[[VAL_21]]#0, %[[VAL_22]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_32:.*]] = fir.rebox %[[VAL_26]](%[[VAL_31]]) : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_32]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
-// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.result %[[VAL_17]]#1, %[[VAL_18]]#1, %[[VAL_20]] : index, index, i1
+// CHECK: fir.result %[[VAL_1]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_16]]#0, %[[VAL_16]]#1, %[[VAL_16]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_22:.*]] = fir.if %[[VAL_14]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
-// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,?>>(%[[VAL_12]] : i32), %[[VAL_14]]#0, %[[VAL_14]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_25:.*]] = fir.shape %[[VAL_14]]#0, %[[VAL_14]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_24]](%[[VAL_25]]) typeparams %[[VAL_12]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>
-// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<none>
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_26]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: fir.result %[[VAL_31]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_20]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_1]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
- %5 = fir.pack_array %arg1 heap innermost typeparams %4 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_22]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.if %[[VAL_33]] {
-// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_38:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_37]] : index
-// CHECK: fir.if %[[VAL_38]] {
-// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_22]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_34]] : !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_33:.*]] = fir.declare %[[VAL_14]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_34]] {
+// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_39:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_38]] : index
+// CHECK: fir.if %[[VAL_39]] {
+// CHECK: %[[VAL_40:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_40]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_41]], %[[VAL_42]], %[[VAL_43]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_35]] : !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
// CHECK: }
- fir.unpack_array %5 to %arg1 heap : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test character array with dynamic length and stack allocation
+func.func @_QPtest2_stack(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+ %c0_i32 = arith.constant 0 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2_stackEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %2 = fir.load %1 : !fir.ref<i32>
+ %3 = arith.cmpi sgt, %2, %c0_i32 : i32
+ %4 = arith.select %3, %2, %c0_i32 : i32
+ %5 = fir.pack_array %arg1 stack innermost typeparams %4 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ fir.unpack_array %5 to %arg1 stack : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest2_stack(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref<i32> {fir.bindc_name = "n"},
// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest2_stack(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_3:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_2:.*]] = arith.constant
+// CHECK: %[[VAL_3:.*]] = arith.constant
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_5:.*]] = arith.constant false
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant false
// CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
- %c0_i32 = arith.constant 0 : i32
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.declare %[[VAL_0]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
- %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2_stackEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref<i32>
- %2 = fir.load %1 : !fir.ref<i32>
// CHECK: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_10]], %[[VAL_7]] : i32
- %3 = arith.cmpi sgt, %2, %c0_i32 : i32
// CHECK: %[[VAL_12:.*]] = arith.select %[[VAL_11]], %[[VAL_10]], %[[VAL_7]] : i32
- %4 = arith.select %3, %2, %c0_i32 : i32
// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) {
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
// CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_16:.*]]:3 = fir.if %[[VAL_15]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: %[[VAL_16:.*]] = arith.cmpi eq, %[[VAL_15]], %[[VAL_6]] : i1
+// CHECK: %[[VAL_17:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_18:.*]] = fir.is_present %[[VAL_17]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>) -> i1
+// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1
+// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_22:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_23:.*]] = fir.shape %[[VAL_21]]#1, %[[VAL_22]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_24:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[VAL_12]] : i32), %[[VAL_21]]#1, %[[VAL_22]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_25:.*]] = fir.declare %[[VAL_24]](%[[VAL_23]]) typeparams %[[VAL_12]] {uniq_name = ".repacked"} : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_25]](%[[VAL_23]]) typeparams %[[VAL_12]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_31:.*]] = fir.shift %[[VAL_21]]#0, %[[VAL_22]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_32:.*]] = fir.rebox %[[VAL_26]](%[[VAL_31]]) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_32]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
-// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.result %[[VAL_17]]#1, %[[VAL_18]]#1, %[[VAL_20]] : index, index, i1
+// CHECK: fir.result %[[VAL_1]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_16]]#0, %[[VAL_16]]#1, %[[VAL_16]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_22:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[VAL_12]] : i32), %[[VAL_14]]#0, %[[VAL_14]]#1 {bindc_name = ".repacked"}
-// CHECK: %[[VAL_24:.*]] = fir.shape %[[VAL_14]]#0, %[[VAL_14]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_22]](%[[VAL_24]]) typeparams %[[VAL_12]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_14]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
-// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_25]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: fir.result %[[VAL_31]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_20]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_1]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
- %5 = fir.pack_array %arg1 stack innermost typeparams %4 : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_26]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.if %[[VAL_33]] {
-// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_26]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_38:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_37]] : index
-// CHECK: fir.if %[[VAL_38]] {
-// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_26]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.declare %[[VAL_14]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, i32, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_34]] {
+// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_39:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_38]] : index
+// CHECK: fir.if %[[VAL_39]] {
+// CHECK: %[[VAL_40:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_40]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_41]], %[[VAL_42]], %[[VAL_43]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
// CHECK: }
// CHECK: }
- fir.unpack_array %5 to %arg1 stack : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test character array with assumed length and heap allocation.
+func.func @_QPtest3(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest3(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest3(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_8:.*]]:4 = fir.if %[[VAL_7]] -> (index, index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_10:.*]]:4 = fir.if %[[VAL_9]] -> (index, index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
+// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>) -> i1
+// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,?>>(%[[VAL_17]] : index), %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_20:.*]] = fir.declare %[[VAL_19]](%[[VAL_18]]) typeparams %[[VAL_17]] {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) typeparams %[[VAL_17]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.shift %[[VAL_15]]#0, %[[VAL_16]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_27:.*]] = fir.rebox %[[VAL_21]](%[[VAL_26]]) : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_27]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_13]], %[[VAL_15]] : index, index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2, %[[VAL_10]]#3 : index, index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_17:.*]] = fir.if %[[VAL_8]]#3 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
-// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,?>>(%[[VAL_8]]#2 : index), %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) typeparams %[[VAL_8]]#2 : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>
-// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,?>>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_14]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.if %[[VAL_28]] {
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
-// CHECK: fir.if %[[VAL_33]] {
-// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_29]] : !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_29]] {
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
+// CHECK: fir.if %[[VAL_34]] {
+// CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_30]] : !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test character array with assumed length and stack allocation.
+func.func @_QPtest3_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest3_stack(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest3_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_8:.*]]:4 = fir.if %[[VAL_7]] -> (index, index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: %[[VAL_10:.*]]:4 = fir.if %[[VAL_9]] -> (index, index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
+// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>
+// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,?>>>>) -> i1
+// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[VAL_17]] : index), %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_20:.*]] = fir.declare %[[VAL_19]](%[[VAL_18]]) typeparams %[[VAL_17]] {uniq_name = ".repacked"} : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) typeparams %[[VAL_17]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.shift %[[VAL_15]]#0, %[[VAL_16]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_27:.*]] = fir.rebox %[[VAL_21]](%[[VAL_26]]) : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_27]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_13]], %[[VAL_15]] : index, index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2, %[[VAL_10]]#3 : index, index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_17:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,?>>(%[[VAL_8]]#2 : index), %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked"}
-// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_17]](%[[VAL_19]]) typeparams %[[VAL_8]]#2 : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shape<2>, index) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_8]]#3 -> (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) {
-// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: fir.result %[[VAL_14]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
// CHECK: }
- %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
-// CHECK: fir.if %[[VAL_28]] {
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
-// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
-// CHECK: fir.if %[[VAL_33]] {
-// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
-// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
+// CHECK: fir.if %[[VAL_29]] {
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
+// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
+// CHECK: fir.if %[[VAL_34]] {
+// CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.box<none>
+// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.char<1,?>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test character array with constant length and heap allocation.
+func.func @_QPtest4(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
+ %c10 = arith.constant 10 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest4(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest4(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = arith.constant 10 : index
// CHECK: %[[VAL_7:.*]] = fir.dummy_scope : !fir.dscope
- %c10 = arith.constant 10 : index
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_8:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_8]] -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
// CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: %[[VAL_11:.*]]:3 = fir.if %[[VAL_10]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: %[[VAL_11:.*]] = arith.cmpi eq, %[[VAL_10]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,10>>>>
+// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,10>>>>) -> i1
+// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_13]] : i1
+// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_16]]#1, %[[VAL_17]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,10>>, %[[VAL_16]]#1, %[[VAL_17]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_20:.*]] = fir.declare %[[VAL_19]](%[[VAL_18]]) typeparams %[[VAL_6]] {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>, index) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.shift %[[VAL_16]]#0, %[[VAL_17]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_27:.*]] = fir.rebox %[[VAL_21]](%[[VAL_26]]) : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: fir.result %[[VAL_27]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: } else {
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: fir.result %[[VAL_12]]#1, %[[VAL_13]]#1, %[[VAL_15]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_11]]#0, %[[VAL_11]]#1, %[[VAL_11]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_17:.*]] = fir.if %[[VAL_9]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
-// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array<?x?x!fir.char<1,10>>, %[[VAL_9]]#0, %[[VAL_9]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_9]]#0, %[[VAL_9]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>
-// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.char<1,10>>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: fir.result %[[VAL_15]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
- %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: fir.if %[[VAL_28]] {
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
-// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
-// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
-// CHECK: fir.if %[[VAL_33]] {
-// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_29]] : !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_9]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4Ex"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: fir.if %[[VAL_29]] {
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
+// CHECK: fir.if %[[VAL_34]] {
+// CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_30]] : !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test character array with constant length and stack allocation.
+func.func @_QPtest4_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
+ %c10 = arith.constant 10 : index
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest4_stack(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest4_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = arith.constant 10 : index
// CHECK: %[[VAL_7:.*]] = fir.dummy_scope : !fir.dscope
- %c10 = arith.constant 10 : index
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_8:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) {
+// CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_8]] -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
// CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: %[[VAL_11:.*]]:3 = fir.if %[[VAL_10]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: %[[VAL_11:.*]] = arith.cmpi eq, %[[VAL_10]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,10>>>>
+// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.char<1,10>>>>) -> i1
+// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_13]] : i1
+// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_16]]#1, %[[VAL_17]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_19:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,10>>, %[[VAL_16]]#1, %[[VAL_17]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_20:.*]] = fir.declare %[[VAL_19]](%[[VAL_18]]) typeparams %[[VAL_6]] {uniq_name = ".repacked"} : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>, index) -> !fir.ref<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_26:.*]] = fir.shift %[[VAL_16]]#0, %[[VAL_17]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_27:.*]] = fir.rebox %[[VAL_21]](%[[VAL_26]]) : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: fir.result %[[VAL_27]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: } else {
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.ref<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: fir.result %[[VAL_12]]#1, %[[VAL_13]]#1, %[[VAL_15]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_11]]#0, %[[VAL_11]]#1, %[[VAL_11]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_17:.*]] = fir.alloca !fir.array<?x?x!fir.char<1,10>>, %[[VAL_9]]#0, %[[VAL_9]]#1 {bindc_name = ".repacked"}
-// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_9]]#0, %[[VAL_9]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_17]](%[[VAL_19]]) : (!fir.ref<!fir.array<?x?x!fir.char<1,10>>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_9]]#2 -> (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) {
-// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: fir.result %[[VAL_15]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
// CHECK: }
- %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
- %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
-// CHECK: fir.if %[[VAL_28]] {
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
-// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
-// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_32]] : index
-// CHECK: fir.if %[[VAL_33]] {
-// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
-// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_9]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4_stackEx"} : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>, index, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
+// CHECK: fir.if %[[VAL_29]] {
+// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
+// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
+// CHECK: fir.if %[[VAL_34]] {
+// CHECK: %[[VAL_35:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.box<none>
+// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.char<1,10>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test derived type array with heap allocation.
+func.func @_QPtest5(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest5(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest5(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> i1
+// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x?x!fir.type<_QMmTt>>, %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked", uniq_name = ""}
+// CHECK: %[[VAL_19:.*]] = fir.declare %[[VAL_18]](%[[VAL_17]]) {uniq_name = ".repacked"} : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.shift %[[VAL_15]]#0, %[[VAL_16]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]](%[[VAL_25]]) : (!fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
-// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array<?x?x!fir.type<_QMmTt>>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked", uniq_name = ""}
-// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
-// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_14]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.if %[[VAL_27]] {
-// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
-// CHECK: fir.if %[[VAL_32]] {
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_28]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5Ex"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_29]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test derived type array with stack allocation.
+func.func @_QPtest5_stack(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5_stackEx"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest5_stack(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest5_stack(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_4:.*]] = arith.constant false
-// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant false
// CHECK: %[[VAL_6:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) {
+// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
+// CHECK: %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_9]], %[[VAL_5]] : i1
+// CHECK: %[[VAL_11:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref<!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> i1
+// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
+// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_18:.*]] = fir.alloca !fir.array<?x?x!fir.type<_QMmTt>>, %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked"}
+// CHECK: %[[VAL_19:.*]] = fir.declare %[[VAL_18]](%[[VAL_17]]) {uniq_name = ".repacked"} : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.shift %[[VAL_15]]#0, %[[VAL_16]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]](%[[VAL_25]]) : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shift<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_26]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
-// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_10]]#0, %[[VAL_10]]#1, %[[VAL_10]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_5]], %[[VAL_5]], %[[VAL_4]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_16:.*]] = fir.alloca !fir.array<?x?x!fir.type<_QMmTt>>, %[[VAL_8]]#0, %[[VAL_8]]#1 {bindc_name = ".repacked"}
-// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_8]]#0, %[[VAL_8]]#1 : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_16]](%[[VAL_18]]) : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) {
-// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: fir.result %[[VAL_25]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_14]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
- %1 = fir.pack_array %arg0 stack innermost : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5_stackEx"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5_stackEx"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.if %[[VAL_27]] {
-// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_31]] : index
-// CHECK: fir.if %[[VAL_32]] {
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5_stackEx"} : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_28]] {
+// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
+// CHECK: fir.if %[[VAL_33]] {
+// CHECK: %[[VAL_34:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 stack : !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test polymorphic type array with heap allocation.
+func.func @_QPtest6(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6Ex"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ fir.unpack_array %1 to %arg0 heap : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest6(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest6(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_5:.*]] = arith.constant false
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant false
// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_6]] : i1
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> i1
+// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1
+// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".repacked"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_5]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_17]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_18]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.shift %[[VAL_17]]#0, %[[VAL_18]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_44:.*]] = fir.rebox %[[VAL_38]](%[[VAL_43]]) : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>, !fir.shift<2>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_44]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
-// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
-// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
-// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
-// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
-// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
-// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
-// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_16]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6Ex"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6Ex"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.if %[[VAL_45]] {
-// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
-// CHECK: fir.if %[[VAL_50]] {
-// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_46]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6Ex"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_46]] {
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
+// CHECK: fir.if %[[VAL_51]] {
+// CHECK: %[[VAL_52:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_47]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: return
+// CHECK: }
+
+// Test polymorphic type array with requested stack allocation.
+// The actual allocation is done in heap memory.
+func.func @_QPtest6_stack(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6_stackEx"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+ fir.unpack_array %1 to %arg0 stack : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
return
}
-
-// Test polymorphic type array with stack allocation.
// CHECK-LABEL: func.func @_QPtest6_stack(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-func.func @_QPtest6_stack(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_5:.*]] = arith.constant false
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant false
// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_6]] : i1
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> i1
+// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1
+// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
+// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
+// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".repacked"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_5]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_17]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_18]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.shift %[[VAL_17]]#0, %[[VAL_18]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_44:.*]] = fir.rebox %[[VAL_38]](%[[VAL_43]]) : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>, !fir.shift<2>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_44]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
-// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, index) -> (index, index, index)
-// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
-// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) {
-// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>
-// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
-// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
-// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>>
-// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.box<none>
-// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: fir.result %[[VAL_16]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
- %1 = fir.pack_array %arg0 stack innermost : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6_stackEx"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6_stackEx"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
-// CHECK: fir.if %[[VAL_45]] {
-// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
-// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
-// CHECK: fir.if %[[VAL_50]] {
-// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
-// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6_stackEx"} : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>, !fir.dscope) -> !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
+// CHECK: fir.if %[[VAL_46]] {
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
+// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
+// CHECK: fir.if %[[VAL_51]] {
+// CHECK: %[[VAL_52:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.box<none>
+// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_47]] : !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 stack : !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>
- return
-}
+// CHECK: return
+// CHECK: }
// Test unlimited polymorphic type array with heap allocation.
+func.func @_QPtest7(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 heap innermost : (!fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?x?xnone>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+ fir.unpack_array %1 to %arg0 heap : !fir.class<!fir.array<?x?xnone>>
+ return
+}
// CHECK-LABEL: func.func @_QPtest7(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
-func.func @_QPtest7(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_5:.*]] = arith.constant false
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant false
// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?xnone>>>
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class<!fir.array<?x?xnone>>) {
// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?xnone>>) -> i1
-// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_6]] : i1
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.class<!fir.array<?x?xnone>>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.class<!fir.array<?x?xnone>>>) -> i1
+// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1
+// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class<!fir.array<?x?xnone>>) {
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?x?xnone>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?xnone>>>
+// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".repacked"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_5]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_17]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_18]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.shift %[[VAL_17]]#0, %[[VAL_18]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_44:.*]] = fir.rebox %[[VAL_38]](%[[VAL_43]]) : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>, !fir.shift<2>) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: fir.result %[[VAL_44]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: } else {
-// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
-// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
-// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?xnone>>) -> i1
-// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: }
-// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?xnone>>) {
-// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?xnone>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?xnone>>>
-// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
-// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
-// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
-// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.box<none>
-// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.class<!fir.array<?x?xnone>>
-// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?xnone>>
+// CHECK: fir.result %[[VAL_16]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: }
- %1 = fir.pack_array %arg0 heap innermost : (!fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
-// CHECK: fir.if %[[VAL_45]] {
-// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
-// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
-// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
-// CHECK: fir.if %[[VAL_50]] {
-// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: fir.freemem %[[VAL_46]] : !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: fir.if %[[VAL_46]] {
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
+// CHECK: fir.if %[[VAL_51]] {
+// CHECK: %[[VAL_52:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_47]] : !fir.heap<!fir.array<?x?xnone>>
// CHECK: }
// CHECK: }
- fir.unpack_array %1 to %arg0 heap : !fir.class<!fir.array<?x?xnone>>
+// CHECK: return
+// CHECK: }
+
+// Test unlimited polymorphic type array with requested stack allocation.
+// The actual allocation is done in heap memory.
+func.func @_QPtest7_stack(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.pack_array %arg0 stack innermost : (!fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?x?xnone>>
+ %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+ fir.unpack_array %1 to %arg0 stack : !fir.class<!fir.array<?x?xnone>>
return
}
-
-// Test unlimited polymorphic type array with stack allocation.
// CHECK-LABEL: func.func @_QPtest7_stack(
// CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
-func.func @_QPtest7_stack(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x"}) {
-// CHECK: %[[VAL_1:.*]] = arith.constant {{.*}} : i32
-// CHECK: %[[VAL_2:.*]] = arith.constant {{.*}} : i32
+// CHECK: %[[VAL_1:.*]] = arith.constant
+// CHECK: %[[VAL_2:.*]] = arith.constant
// CHECK: %[[VAL_3:.*]] = arith.constant 2 : i32
// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index
-// CHECK: %[[VAL_5:.*]] = arith.constant false
-// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index
+// CHECK: %[[VAL_6:.*]] = arith.constant false
// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x?xnone>>>
// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope
- %0 = fir.dummy_scope : !fir.dscope
// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
-// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) {
+// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class<!fir.array<?x?xnone>>) {
// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class<!fir.array<?x?xnone>>) -> i1
-// CHECK: %[[VAL_12:.*]]:3 = fir.if %[[VAL_11]] -> (index, index, i1) {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
+// CHECK: %[[VAL_12:.*]] = arith.cmpi eq, %[[VAL_11]], %[[VAL_6]] : i1
+// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.class<!fir.array<?x?xnone>>>
+// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref<!fir.class<!fir.array<?x?xnone>>>) -> i1
+// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1
+// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class<!fir.array<?x?xnone>>) {
+// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
+// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2>
+// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?x?xnone>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?xnone>>>
+// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = ".repacked"} : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_5]] : (index) -> i32
+// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_17]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
+// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_18]]#1 : (index) -> i64
+// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
+// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
+// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
+// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.box<none>
+// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_43:.*]] = fir.shift %[[VAL_17]]#0, %[[VAL_18]]#0 : (index, index) -> !fir.shift<2>
+// CHECK: %[[VAL_44:.*]] = fir.rebox %[[VAL_38]](%[[VAL_43]]) : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>, !fir.shift<2>) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: fir.result %[[VAL_44]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: } else {
-// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
-// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class<!fir.array<?x?xnone>>, index) -> (index, index, index)
-// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.ref<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref<!fir.array<?x?xnone>>) -> i1
-// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1
+// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: }
-// CHECK: fir.result %[[VAL_12]]#0, %[[VAL_12]]#1, %[[VAL_12]]#2 : index, index, i1
-// CHECK: } else {
-// CHECK: fir.result %[[VAL_6]], %[[VAL_6]], %[[VAL_5]] : index, index, i1
-// CHECK: }
-// CHECK: %[[VAL_18:.*]] = fir.if %[[VAL_10]]#2 -> (!fir.class<!fir.array<?x?xnone>>) {
-// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2>
-// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_20]](%[[VAL_21]]) : (!fir.heap<!fir.array<?x?xnone>>, !fir.shape<2>) -> !fir.class<!fir.heap<!fir.array<?x?xnone>>>
-// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
-// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref<!fir.box<none>>, !fir.box<none>, i32) -> ()
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_6]] : (index) -> i32
-// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_10]]#0 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_25]], %[[VAL_26]], %[[VAL_27]], %[[VAL_28]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_4]] : (index) -> i32
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_4]] : (index) -> i64
-// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_10]]#1 : (index) -> i64
-// CHECK: fir.call @_FortranAAllocatableSetBounds(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_32]]) : (!fir.ref<!fir.box<none>>, i32, i64, i64) -> ()
-// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box<none>
-// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>) -> !fir.ref<!fir.box<none>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
-// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref<!fir.class<!fir.heap<!fir.array<?x?xnone>>>>
-// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.box<none>
-// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class<!fir.heap<!fir.array<?x?xnone>>>) -> !fir.class<!fir.array<?x?xnone>>
-// CHECK: fir.result %[[VAL_43]] : !fir.class<!fir.array<?x?xnone>>
+// CHECK: fir.result %[[VAL_16]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: } else {
// CHECK: fir.result %[[VAL_0]] : !fir.class<!fir.array<?x?xnone>>
// CHECK: }
- %1 = fir.pack_array %arg0 stack innermost : (!fir.class<!fir.array<?x?xnone>>) -> !fir.class<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
- %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
-// CHECK: fir.if %[[VAL_45]] {
-// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
-// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
-// CHECK: %[[VAL_50:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_49]] : index
-// CHECK: fir.if %[[VAL_50]] {
-// CHECK: %[[VAL_51:.*]] = fir.address_of(@{{_QQcl.*}}
-// CHECK: %[[VAL_52:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
-// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class<!fir.array<?x?xnone>>, !fir.dscope) -> !fir.class<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
+// CHECK: fir.if %[[VAL_46]] {
+// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
+// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
+// CHECK: fir.if %[[VAL_51]] {
+// CHECK: %[[VAL_52:.*]] = fir.address_of(@{{_QQcl.*}}
+// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.box<none>
+// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
+// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box<none>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+// CHECK: fir.freemem %[[VAL_47]] : !fir.heap<!fir.array<?x?xnone>>
// CHECK: }
// CHECK: }
// CHECK: return
// CHECK: }
- fir.unpack_array %1 to %arg0 stack : !fir.class<!fir.array<?x?xnone>>
- return
-}
>From a60ee69ddee770cea0432e3f8ff1c50868882d41 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 25 Mar 2025 11:37:10 -0700
Subject: [PATCH 4/7] cleanup
---
.../HLFIR/Transforms/BufferizeHLFIR.cpp | 53 -------------------
1 file changed, 53 deletions(-)
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
index 68d286aa29a6a..8a36214def167 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp
@@ -126,59 +126,6 @@ createArrayTemp(mlir::Location loc, fir::FirOpBuilder &builder,
loc, sequenceType, shape, extents, lenParams, genTempDeclareOp,
polymorphicMold ? polymorphicMold->getFirBase() : nullptr);
return {hlfir::Entity{base}, builder.createBool(loc, isHeapAlloc)};
-#if 0
- llvm::StringRef tmpName{".tmp.array"};
-
- if (polymorphicMold) {
- // Create *allocated* polymorphic temporary using the dynamic type
- // of the mold and the provided shape/extents. The created temporary
- // array will be written element per element, that is why it has to be
- // allocated.
- mlir::Type boxHeapType = fir::HeapType::get(sequenceType);
- mlir::Value alloc = fir::factory::genNullBoxStorage(
- builder, loc, fir::ClassType::get(boxHeapType));
- mlir::Value isHeapAlloc = builder.createBool(loc, true);
- fir::FortranVariableFlagsAttr declAttrs =
- fir::FortranVariableFlagsAttr::get(
- builder.getContext(), fir::FortranVariableFlagsEnum::allocatable);
-
- auto declareOp =
- builder.create<hlfir::DeclareOp>(loc, alloc, tmpName,
- /*shape=*/nullptr, lenParams,
- /*dummy_scope=*/nullptr, declAttrs);
-
- int rank = extents.size();
- fir::runtime::genAllocatableApplyMold(builder, loc, alloc,
- polymorphicMold->getFirBase(), rank);
- if (!extents.empty()) {
- mlir::Type idxTy = builder.getIndexType();
- mlir::Value one = builder.createIntegerConstant(loc, idxTy, 1);
- unsigned dim = 0;
- for (mlir::Value extent : extents) {
- mlir::Value dimIndex = builder.createIntegerConstant(loc, idxTy, dim++);
- fir::runtime::genAllocatableSetBounds(builder, loc, alloc, dimIndex,
- one, extent);
- }
- }
- if (!lenParams.empty()) {
- // We should call AllocatableSetDerivedLength() here.
- // TODO: does the mold provide the length parameters or
- // the operation itself or should they be in sync?
- TODO(loc, "polymorphic type with length parameters in HLFIR");
- }
- fir::runtime::genAllocatableAllocate(builder, loc, alloc);
-
- return {hlfir::Entity{declareOp.getBase()}, isHeapAlloc};
- }
-
- mlir::Value allocmem = builder.createHeapTemporary(loc, sequenceType, tmpName,
- extents, lenParams);
- auto declareOp = builder.create<hlfir::DeclareOp>(
- loc, allocmem, tmpName, shape, lenParams,
- /*dummy_scope=*/nullptr, fir::FortranVariableFlagsAttr{});
- mlir::Value trueVal = builder.createBool(loc, true);
- return {hlfir::Entity{declareOp.getBase()}, trueVal};
-#endif
}
/// Copy \p source into a new temporary and package the temporary into a
>From 4c2e937350a147bb1af331969f53422c017e0ee9 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 25 Mar 2025 11:53:54 -0700
Subject: [PATCH 5/7] Added genPtrCompare builder.
---
flang/include/flang/Optimizer/Builder/FIRBuilder.h | 9 +++++++++
flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp | 7 ++-----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/flang/include/flang/Optimizer/Builder/FIRBuilder.h b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
index 82f5785090699..1583cfb3f5b51 100644
--- a/flang/include/flang/Optimizer/Builder/FIRBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/FIRBuilder.h
@@ -630,6 +630,15 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
return result;
}
+ /// Compare two pointer-like values using the given predicate.
+ mlir::Value genPtrCompare(mlir::Location loc,
+ mlir::arith::CmpIPredicate predicate,
+ mlir::Value ptr1, mlir::Value ptr2) {
+ ptr1 = createConvert(loc, getIndexType(), ptr1);
+ ptr2 = createConvert(loc, getIndexType(), ptr2);
+ return create<mlir::arith::CmpIOp>(loc, predicate, ptr1, ptr2);
+ }
+
private:
/// Set attributes (e.g. FastMathAttr) to \p op operation
/// based on the current attributes setting.
diff --git a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
index 170e648d77fe4..76b505ea79750 100644
--- a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
+++ b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
@@ -284,14 +284,11 @@ UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op,
fir::HeapType::get(fir::extractSequenceType(tempBox.getType()));
mlir::Value tempAddr =
builder.create<fir::BoxAddrOp>(loc, addrType, tempBox);
- mlir::Value tempAddrAsIndex =
- builder.createConvert(loc, indexType, tempAddr);
mlir::Value originalAddr =
builder.create<fir::BoxAddrOp>(loc, addrType, originalBox);
- originalAddr = builder.createConvert(loc, indexType, originalAddr);
- auto isNotSame = builder.create<mlir::arith::CmpIOp>(
- loc, mlir::arith::CmpIPredicate::ne, tempAddrAsIndex, originalAddr);
+ auto isNotSame = builder.genPtrCompare(loc, mlir::arith::CmpIPredicate::ne,
+ tempAddr, originalAddr);
builder.genIfThen(loc, isNotSame).genThen([&]() {});
// Copy from temporary to the original.
if (!op.getNoCopy())
>From 160ded5536b7b10e8d1e85b80446c28f394fa068 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 25 Mar 2025 12:03:33 -0700
Subject: [PATCH 6/7] Fixed test after genPtrCompare change.
---
flang/test/Transforms/lower-repack-arrays.fir | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/flang/test/Transforms/lower-repack-arrays.fir b/flang/test/Transforms/lower-repack-arrays.fir
index c1db3e2ce9c05..7317d8f49f074 100644
--- a/flang/test/Transforms/lower-repack-arrays.fir
+++ b/flang/test/Transforms/lower-repack-arrays.fir
@@ -48,8 +48,8 @@ func.func @_QPtest1(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x"})
// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
// CHECK: fir.if %[[VAL_28]] {
// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
// CHECK: fir.if %[[VAL_33]] {
@@ -113,8 +113,8 @@ func.func @_QPtest1_whole(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name =
// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
// CHECK: fir.if %[[VAL_28]] {
// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
// CHECK: fir.if %[[VAL_33]] {
@@ -176,8 +176,8 @@ func.func @_QPtest1_in(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "x
// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
// CHECK: fir.if %[[VAL_27]] {
// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_31]] : index
// CHECK: fir.if %[[VAL_32]] {
@@ -230,8 +230,8 @@ func.func @_QPtest1_out(%arg0: !fir.box<!fir.array<?x?xf32>> {fir.bindc_name = "
// CHECK: %[[VAL_23:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> i1
// CHECK: fir.if %[[VAL_23]] {
// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
-// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_26:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?xf32>>) -> !fir.heap<!fir.array<?x?xf32>>
+// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.heap<!fir.array<?x?xf32>>) -> index
// CHECK: %[[VAL_28:.*]] = arith.cmpi ne, %[[VAL_25]], %[[VAL_27]] : index
// CHECK: fir.if %[[VAL_28]] {
@@ -306,8 +306,8 @@ func.func @_QPtest2(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.box
// CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
// CHECK: fir.if %[[VAL_34]] {
// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_39:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_38]] : index
// CHECK: fir.if %[[VAL_39]] {
@@ -382,8 +382,8 @@ func.func @_QPtest2_stack(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !f
// CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
// CHECK: fir.if %[[VAL_34]] {
// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_39:.*]] = arith.cmpi ne, %[[VAL_36]], %[[VAL_38]] : index
// CHECK: fir.if %[[VAL_39]] {
@@ -447,8 +447,8 @@ func.func @_QPtest3(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.bindc_n
// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
// CHECK: fir.if %[[VAL_29]] {
// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
// CHECK: fir.if %[[VAL_34]] {
@@ -513,8 +513,8 @@ func.func @_QPtest3_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,?>>> {fir.b
// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> i1
// CHECK: fir.if %[[VAL_29]] {
// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,?>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,?>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,?>>>) -> index
// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
// CHECK: fir.if %[[VAL_34]] {
@@ -579,8 +579,8 @@ func.func @_QPtest4(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.bindc_
// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
// CHECK: fir.if %[[VAL_29]] {
// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
// CHECK: fir.if %[[VAL_34]] {
@@ -646,8 +646,8 @@ func.func @_QPtest4_stack(%arg0: !fir.box<!fir.array<?x?x!fir.char<1,10>>> {fir.
// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> i1
// CHECK: fir.if %[[VAL_29]] {
// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
-// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x?x!fir.char<1,10>>>
+// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap<!fir.array<?x?x!fir.char<1,10>>>) -> index
// CHECK: %[[VAL_34:.*]] = arith.cmpi ne, %[[VAL_31]], %[[VAL_33]] : index
// CHECK: fir.if %[[VAL_34]] {
@@ -710,8 +710,8 @@ func.func @_QPtest5(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bind
// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
// CHECK: fir.if %[[VAL_28]] {
// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
// CHECK: fir.if %[[VAL_33]] {
@@ -775,8 +775,8 @@ func.func @_QPtest5_stack(%arg0: !fir.box<!fir.array<?x?x!fir.type<_QMmTt>>> {fi
// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
// CHECK: fir.if %[[VAL_28]] {
// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_33:.*]] = arith.cmpi ne, %[[VAL_30]], %[[VAL_32]] : index
// CHECK: fir.if %[[VAL_33]] {
@@ -861,8 +861,8 @@ func.func @_QPtest6(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {fir.bi
// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
// CHECK: fir.if %[[VAL_46]] {
// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
// CHECK: fir.if %[[VAL_51]] {
@@ -949,8 +949,8 @@ func.func @_QPtest6_stack(%arg0: !fir.class<!fir.array<?x?x!fir.type<_QMmTt>>> {
// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> i1
// CHECK: fir.if %[[VAL_46]] {
// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?x!fir.type<_QMmTt>>>) -> !fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?x!fir.type<_QMmTt>>>) -> index
// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
// CHECK: fir.if %[[VAL_51]] {
@@ -1036,8 +1036,8 @@ func.func @_QPtest7(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_name = "x
// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
// CHECK: fir.if %[[VAL_46]] {
// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
// CHECK: fir.if %[[VAL_51]] {
@@ -1124,8 +1124,8 @@ func.func @_QPtest7_stack(%arg0: !fir.class<!fir.array<?x?xnone>> {fir.bindc_nam
// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> i1
// CHECK: fir.if %[[VAL_46]] {
// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
-// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class<!fir.array<?x?xnone>>) -> !fir.heap<!fir.array<?x?xnone>>
+// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap<!fir.array<?x?xnone>>) -> index
// CHECK: %[[VAL_51:.*]] = arith.cmpi ne, %[[VAL_48]], %[[VAL_50]] : index
// CHECK: fir.if %[[VAL_51]] {
>From 24845f18d841b67b904edc4519d77fe343f96416 Mon Sep 17 00:00:00 2001
From: Slava Zakharin <szakharin at nvidia.com>
Date: Tue, 25 Mar 2025 12:06:41 -0700
Subject: [PATCH 7/7] Removed unused var.
---
flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
index 76b505ea79750..0acc034c47152 100644
--- a/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
+++ b/flang/lib/Optimizer/CodeGen/LowerRepackArrays.cpp
@@ -271,7 +271,6 @@ UnpackArrayConversion::matchAndRewrite(fir::UnpackArrayOp op,
mlir::Location loc = op.getLoc();
fir::FirOpBuilder builder(rewriter, op.getOperation());
mlir::Type predicateType = builder.getI1Type();
- mlir::Type indexType = builder.getIndexType();
mlir::Value tempBox = op.getTemp();
mlir::Value originalBox = op.getOriginal();
More information about the flang-commits
mailing list