From f92cee81489bf216d432fd9a66d303dc7dd2b202 Mon Sep 17 00:00:00 2001 From: Slava Zakharin 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 dataLayout) + : dataLayout(dataLayout) {} + +protected: + std::optional dataLayout; + + static bool canAllocateTempOnStack(mlir::Value box); +}; + +class PackArrayConversion : public mlir::OpRewritePattern, + RepackArrayConversion { +public: + using OpRewritePattern::OpRewritePattern; + + PackArrayConversion(mlir::MLIRContext *context, + std::optional 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 extents, + llvm::ArrayRef typeParams); +}; + +class UnpackArrayConversion : public mlir::OpRewritePattern, + RepackArrayConversion { +public: + using OpRewritePattern::OpRewritePattern; + + UnpackArrayConversion(mlir::MLIRContext *context, + std::optional 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 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 extents; + // if (IsPresent(box) && !IsContiguous[UpTo](box[, 1])) { + // isNotEmpty = box->base_addr != null; + // extents = SHAPE(box); + // } else { + // isNotEmpty = false; + // extents = vector(rank, 0); + // } + + unsigned numTypeParams = 0; + if (typeParams.size() == 0) { + if (auto recordType = mlir::dyn_cast(boxValue.getEleTy())) + if (recordType.getNumLenParams() != 0) + TODO(loc, + "allocating temporary for a parameterized derived type array"); + + if (auto charType = mlir::dyn_cast(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(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 ifTypes(rank + numTypeParams, indexType); + ifTypes.push_back(predicateType); + llvm::SmallVector negativeResult(rank + numTypeParams, zero); + negativeResult.push_back( + fir::factory::createZeroValue(builder, loc, predicateType)); + bool failedTypeParams = false; + llvm::SmallVector extentsAndPredicate = + builder + .genIfOp(loc, ifTypes, isPresent, + /*withElseRegion=*/true) + .genThen([&]() { + // The box is present. + auto isContiguous = builder.create( + loc, box, op.getInnermost()); + llvm::SmallVector extentsAndPredicate = + builder + .genIfOp(loc, ifTypes, isContiguous, + /*withElseRegion=*/true) + .genThen([&]() { + // Box is contiguous, return zero. + builder.create(loc, negativeResult); + }) + .genElse([&]() { + // Get the extents. + llvm::SmallVector results = + fir::factory::readExtents(builder, loc, boxValue); + + // Get the type parameters from the box, if needed. + llvm::SmallVector assumedTypeParams; + if (numTypeParams != 0) { + if (auto charType = mlir::dyn_cast( + 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( + loc, boxValue.getMemTy(), boxValue.getAddr()); + auto isNotEmpty = builder.create( + loc, predicateType, dataAddr); + results.push_back(isNotEmpty); + builder.create(loc, results); + }) + .getResults(); + + builder.create(loc, extentsAndPredicate); + }) + .genElse([&]() { + // Box is absent, nothing to do. + builder.create(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 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(loc, boxType, tempBox, shape, + /*slice=*/nullptr); + builder.create(loc, tempBox); + }) + .genElse([&]() { + // Return original box. + builder.create(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 extents, + llvm::ArrayRef typeParams) { + auto tempType = mlir::cast( + 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(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(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(loc, predicateType, originalBox); + + builder.genIfThen(loc, isPresent).genThen([&]() { + mlir::Type addrType = + fir::HeapType::get(fir::extractSequenceType(tempBox.getType())); + mlir::Value tempAddr = + builder.create(loc, addrType, tempBox); + mlir::Value tempAddrAsIndex = + builder.createConvert(loc, indexType, tempAddr); + mlir::Value originalAddr = + builder.create(loc, addrType, originalBox); + originalAddr = builder.createConvert(loc, indexType, originalAddr); + + auto isNotSame = builder.create( + 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(loc, tempAddr); + }); + rewriter.eraseOp(op); + return mlir::success(); +} + +namespace { +class LowerRepackArraysPass + : public fir::impl::LowerRepackArraysPassBase { +public: + using LowerRepackArraysPassBase< + LowerRepackArraysPass>::LowerRepackArraysPassBase; + + void runOnOperation() override final { + auto *context = &getContext(); + mlir::ModuleOp module = getOperation(); + std::optional dl = fir::support::getOrSetMLIRDataLayout( + module, /*allowDefaultLayout=*/false); + mlir::RewritePatternSet patterns(context); + patterns.insert(context, dl); + patterns.insert(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.bindc_name = "x"}) { +func.func @_QPtest1(%arg0: !fir.box> {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>) -> i1 +// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>) -> 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>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>) -> 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>) { +// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array, %[[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.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>) -> !fir.box> +// CHECK: fir.result %[[VAL_25]] : !fir.box> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1Ex"} : (!fir.box>, !fir.dscope) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1Ex"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_27]] { +// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_28]] : !fir.heap> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.box> + 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.bindc_name = "x"}) { +func.func @_QPtest1_whole(%arg0: !fir.box> {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>) -> i1 +// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] whole : (!fir.box>) -> 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>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>) -> 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, %[[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.shape<2>) -> !fir.box> +// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box>) { +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>) -> !fir.box> +// CHECK: fir.result %[[VAL_25]] : !fir.box> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box> +// CHECK: } + %1 = fir.pack_array %arg0 stack whole : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1_wholeEx"} : (!fir.box>, !fir.dscope) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1_wholeEx"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_27]] { +// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 stack : !fir.box> + 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.bindc_name = "x"}) { +func.func @_QPtest1_in(%arg0: !fir.box> {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>) -> i1 +// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>) -> 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>, index) -> (index, index, index) +// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> +// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>) -> 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>) { +// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array, %[[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.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_24:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>>) -> !fir.box> +// CHECK: fir.result %[[VAL_24]] : !fir.box> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_25:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_inEx"} : (!fir.box>, !fir.dscope) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_inEx"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_26:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_26]] { +// CHECK: %[[VAL_27:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (!fir.heap>) -> index +// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index +// CHECK: %[[VAL_31:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_30]] : index +// CHECK: fir.if %[[VAL_31]] { +// CHECK: fir.freemem %[[VAL_27]] : !fir.heap> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap no_copy : !fir.box> + 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.bindc_name = "x"}) { +func.func @_QPtest1_out(%arg0: !fir.box> {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>) -> i1 +// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>) -> 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>, index) -> (index, index, index) +// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> +// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>) -> 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>) { +// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array, %[[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.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>>) -> !fir.box> +// CHECK: fir.result %[[VAL_20]] : !fir.box> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost no_copy : (!fir.box>) -> !fir.box> +// CHECK: %[[VAL_21:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_outEx"} : (!fir.box>, !fir.dscope) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_outEx"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_22:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_22]] { +// CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_23]] : (!fir.heap>) -> index +// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_28]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_23]] : !fir.heap> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.box> + 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 {fir.bindc_name = "n"}, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { +func.func @_QPtest2(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box>> {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, !fir.dscope) -> !fir.ref + %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2En"} : (!fir.ref, !fir.dscope) -> !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref + %2 = fir.load %1 : !fir.ref +// 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>>) -> i1 +// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) { +// CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref>>) -> 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>>) { +// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array>(%[[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.shape<2>, i32) -> !fir.box>>> +// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_26]] : (!fir.box>>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_31]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_1]] : !fir.box>> +// CHECK: } + %5 = fir.pack_array %arg1 heap innermost typeparams %4 : (!fir.box>>, i32) -> !fir.box>> +// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_22]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2Ex"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> + %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2Ex"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_33]] { +// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_22]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_34]] : !fir.heap>> +// CHECK: } +// CHECK: } + fir.unpack_array %5 to %arg1 heap : !fir.box>> + 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 {fir.bindc_name = "n"}, +// CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { +func.func @_QPtest2_stack(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box>> {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, !fir.dscope) -> !fir.ref + %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2_stackEn"} : (!fir.ref, !fir.dscope) -> !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref + %2 = fir.load %1 : !fir.ref +// 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>>) -> i1 +// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) { +// CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref>>) -> 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>(%[[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.shape<2>, i32) -> !fir.box>> +// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_14]]#2 -> (!fir.box>>) { +// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_25]] : (!fir.box>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_31]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_1]] : !fir.box>> +// CHECK: } + %5 = fir.pack_array %arg1 stack innermost typeparams %4 : (!fir.box>>, i32) -> !fir.box>> +// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_26]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEx"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> + %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2_stackEx"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_33]] { +// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_26]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_26]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } + fir.unpack_array %5 to %arg1 stack : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest3(%arg0: !fir.box>> {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>>) -> 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>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index +// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> 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>>) { +// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array>(%[[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.shape<2>, index) -> !fir.box>>> +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box>>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box>> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest3_stack(%arg0: !fir.box>> {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>>) -> 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>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index +// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> 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>(%[[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.shape<2>, index) -> !fir.box>> +// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_8]]#3 -> (!fir.box>>) { +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box>> +// CHECK: } + %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 stack : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest4(%arg0: !fir.box>> {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>>) -> i1 +// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) { +// CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> 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>>) { +// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array>, %[[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.shape<2>) -> !fir.box>>> +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box>>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box>> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4Ex"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> + %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4Ex"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest4_stack(%arg0: !fir.box>> {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>>) -> i1 +// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) { +// CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> 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>, %[[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.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_9]]#2 -> (!fir.box>>) { +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box>> +// CHECK: } + %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4_stackEx"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> + %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4_stackEx"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 stack : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest5(%arg0: !fir.box>> {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>>) -> i1 +// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>) -> 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>>) { +// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array>, %[[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.shape<2>) -> !fir.box>>> +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_25]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box>> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_27]] { +// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_28]] : !fir.heap>> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest5_stack(%arg0: !fir.box>> {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>>) -> i1 +// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>) -> 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>, %[[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.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box>>) { +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>>) -> !fir.box>> +// CHECK: fir.result %[[VAL_25]] : !fir.box>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.box>> +// CHECK: } + %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> +// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_27]] { +// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 stack : !fir.box>> + 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.bindc_name = "x"}) { +func.func @_QPtest6(%arg0: !fir.class>> {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>>> +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope + %0 = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 +// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.ref>> +// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>>) -> 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>>) { +// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap>> +// 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.shape<2>) -> !fir.class>>> +// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>>) -> !fir.class>> +// CHECK: fir.result %[[VAL_43]] : !fir.class>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.class>> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.class>>) -> !fir.class>> +// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6Ex"} : (!fir.class>>, !fir.dscope) -> !fir.class>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6Ex"} : (!fir.class>>, !fir.dscope) -> !fir.class>> +// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 +// CHECK: fir.if %[[VAL_45]] { +// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_46]] : !fir.heap>> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.class>> + 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.bindc_name = "x"}) { +func.func @_QPtest6_stack(%arg0: !fir.class>> {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>>> +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope + %0 = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 +// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>>) -> 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>>, index) -> (index, index, index) +// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.ref>> +// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>>) -> 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>>) { +// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap>> +// 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.shape<2>) -> !fir.class>>> +// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>>) -> !fir.class>> +// CHECK: fir.result %[[VAL_43]] : !fir.class>> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.class>> +// CHECK: } + %1 = fir.pack_array %arg0 stack innermost : (!fir.class>>) -> !fir.class>> +// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6_stackEx"} : (!fir.class>>, !fir.dscope) -> !fir.class>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6_stackEx"} : (!fir.class>>, !fir.dscope) -> !fir.class>> +// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 +// CHECK: fir.if %[[VAL_45]] { +// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 stack : !fir.class>> + 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.bindc_name = "x"}) { +func.func @_QPtest7(%arg0: !fir.class> {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>> +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope + %0 = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 +// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>) -> 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>, index) -> (index, index, index) +// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.ref> +// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>) -> 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>) { +// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap> +// 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.shape<2>) -> !fir.class>> +// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>) -> !fir.class> +// CHECK: fir.result %[[VAL_43]] : !fir.class> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.class> +// CHECK: } + %1 = fir.pack_array %arg0 heap innermost : (!fir.class>) -> !fir.class> +// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> +// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 +// CHECK: fir.if %[[VAL_45]] { +// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>) -> index +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_46]] : !fir.heap> +// CHECK: } +// CHECK: } + fir.unpack_array %1 to %arg0 heap : !fir.class> + 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.bindc_name = "x"}) { +func.func @_QPtest7_stack(%arg0: !fir.class> {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>> +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope + %0 = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 +// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>) -> 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>, index) -> (index, index, index) +// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.ref> +// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>) -> 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>) { +// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap> +// 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.shape<2>) -> !fir.class>> +// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>) -> !fir.class> +// CHECK: fir.result %[[VAL_43]] : !fir.class> +// CHECK: } else { +// CHECK: fir.result %[[VAL_0]] : !fir.class> +// CHECK: } + %1 = fir.pack_array %arg0 stack innermost : (!fir.class>) -> !fir.class> +// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> +// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 +// CHECK: fir.if %[[VAL_45]] { +// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>) -> index +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: } +// CHECK: } +// CHECK: return +// CHECK: } + fir.unpack_array %1 to %arg0 stack : !fir.class> + return +} From fb56d9123bd8dfbd1ad6a814a9876298d897de3b Mon Sep 17 00:00:00 2001 From: Slava Zakharin 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 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 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> or !fir.ref>. + static mlir::Value genTempDeclareOp(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value memref, + llvm::StringRef name, mlir::Value shape, + llvm::ArrayRef 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> or !fir.ref>. + /// The second return value is true, if the actual allocation + /// was done in heap memory. + std::pair + createArrayTemp(mlir::Location loc, fir::SequenceType arrayType, + mlir::Value shape, llvm::ArrayRef extents, + llvm::ArrayRef typeParams, + const std::function &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 deduceOptimalExtents(mlir::ValueRange extents1, /// %result1 = arith.select %p4, %c0, %e1 : index llvm::SmallVector 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 *lbounds, + llvm::SmallVectorImpl *extents, + llvm::SmallVectorImpl *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 fir::FirOpBuilder::createArrayTemp( + mlir::Location loc, fir::SequenceType arrayType, mlir::Value shape, + llvm::ArrayRef extents, llvm::ArrayRef typeParams, + const std::function &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 typeParams, + fir::FortranVariableFlagsAttr fortranAttrs) { + auto nameAttr = mlir::StringAttr::get(builder.getContext(), name); + return builder.create(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 fir::factory::updateRuntimeExtentsForEmptyArrays( } return newExtents; } + +void fir::factory::genDimInfoFromBox( + fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value box, + llvm::SmallVectorImpl *lbounds, + llvm::SmallVectorImpl *extents, + llvm::SmallVectorImpl *strides) { + auto boxType = mlir::dyn_cast(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(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 &lbounds, - llvm::SmallVectorImpl *extents) { - assert(mlir::isa(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(loc, idxTy, idxTy, idxTy, - boxEntity, dim); - lbounds.push_back(dimInfo.getLowerBound()); - if (extents) - extents->push_back(dimInfo.getExtent()); - } -} - static llvm::SmallVector 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 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 dataLayout) - : dataLayout(dataLayout) {} - -protected: - std::optional dataLayout; - - static bool canAllocateTempOnStack(mlir::Value box); -}; - -class PackArrayConversion : public mlir::OpRewritePattern, - RepackArrayConversion { +class PackArrayConversion : public mlir::OpRewritePattern { public: using OpRewritePattern::OpRewritePattern; - PackArrayConversion(mlir::MLIRContext *context, - std::optional 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, 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 extents, llvm::ArrayRef 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 genRepackedBox(fir::FirOpBuilder &builder, + mlir::Location loc, + fir::PackArrayOp packOp); }; -class UnpackArrayConversion : public mlir::OpRewritePattern, - RepackArrayConversion { +class UnpackArrayConversion + : public mlir::OpRewritePattern { public: using OpRewritePattern::OpRewritePattern; - UnpackArrayConversion(mlir::MLIRContext *context, - std::optional 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 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 extents; - // if (IsPresent(box) && !IsContiguous[UpTo](box[, 1])) { - // isNotEmpty = box->base_addr != null; - // extents = SHAPE(box); - // } else { - // isNotEmpty = false; - // extents = vector(rank, 0); - // } - - unsigned numTypeParams = 0; - if (typeParams.size() == 0) { - if (auto recordType = mlir::dyn_cast(boxValue.getEleTy())) - if (recordType.getNumLenParams() != 0) - TODO(loc, - "allocating temporary for a parameterized derived type array"); - - if (auto charType = mlir::dyn_cast(boxValue.getEleTy())) - if (charType.hasDynamicLen()) - numTypeParams = 1; - } + auto boxType = mlir::cast(box.getType()); // For now we have to always check if the box is present. - mlir::Type predicateType = builder.getI1Type(); auto isPresent = - builder.create(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 ifTypes(rank + numTypeParams, indexType); - ifTypes.push_back(predicateType); - llvm::SmallVector negativeResult(rank + numTypeParams, zero); - negativeResult.push_back( - fir::factory::createZeroValue(builder, loc, predicateType)); - bool failedTypeParams = false; - llvm::SmallVector extentsAndPredicate = - builder - .genIfOp(loc, ifTypes, isPresent, - /*withElseRegion=*/true) - .genThen([&]() { - // The box is present. - auto isContiguous = builder.create( - loc, box, op.getInnermost()); - llvm::SmallVector extentsAndPredicate = - builder - .genIfOp(loc, ifTypes, isContiguous, - /*withElseRegion=*/true) - .genThen([&]() { - // Box is contiguous, return zero. - builder.create(loc, negativeResult); - }) - .genElse([&]() { - // Get the extents. - llvm::SmallVector results = - fir::factory::readExtents(builder, loc, boxValue); - - // Get the type parameters from the box, if needed. - llvm::SmallVector assumedTypeParams; - if (numTypeParams != 0) { - if (auto charType = mlir::dyn_cast( - 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( - loc, boxValue.getMemTy(), boxValue.getAddr()); - auto isNotEmpty = builder.create( - loc, predicateType, dataAddr); - results.push_back(isNotEmpty); - builder.create(loc, results); - }) - .getResults(); - - builder.create(loc, extentsAndPredicate); - }) - .genElse([&]() { - // Box is absent, nothing to do. - builder.create(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 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(loc, boxType, tempBox, shape, - /*slice=*/nullptr); - builder.create(loc, tempBox); - }) - .genElse([&]() { - // Return original box. - builder.create(loc, boxValue.getAddr()); - }) - .getResults()[0]; - - rewriter.replaceOp(op, newResult); + builder.create(loc, builder.getI1Type(), box); + + fir::IfOp ifOp = builder.create(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(loc, *newBox); + + // The box is not present. Return original box. + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + builder.create(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(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(base.getType())) + if (mlir::isa(baseType.getEleTy())) + return builder.create(loc, base); + + mlir::Type ptrType = base.getType(); mlir::Type tempBoxType = fir::BoxType::get(mlir::isa(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 +PackArrayConversion::genRepackedBox(fir::FirOpBuilder &builder, + mlir::Location loc, fir::PackArrayOp op) { + mlir::OpBuilder::InsertionGuard guard(builder); + mlir::Value box = op.getArray(); + llvm::SmallVector typeParams(op.getTypeparams().begin(), + op.getTypeparams().end()); + auto boxType = mlir::cast(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(boxType.unwrapInnerType())) + if (recordType.getNumLenParams() != 0) + TODO(loc, + "allocating temporary for a parameterized derived type array"); + + if (auto charType = + mlir::dyn_cast(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(loc, box, op.getInnermost())); + auto dataAddr = + builder.create(loc, fir::boxMemRefType(boxType), box); + auto isNotEmpty = + builder.create(loc, builder.getI1Type(), dataAddr); + auto doPack = + builder.create(loc, isNotContiguous, isNotEmpty); + + fir::IfOp ifOp = + builder.create(loc, boxType, doPack, /*withElseRegion=*/true); + + // Return original box. + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + builder.create(loc, box); + + // Create a new box. + builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + + // Get lower bounds and extents from the box. + llvm::SmallVector lbounds, extents; + fir::factory::genDimInfoFromBox(builder, loc, box, &lbounds, &extents, + /*strides=*/nullptr); + // Get the type parameters from the box, if needed. + llvm::SmallVector assumedTypeParams; + if (numTypeParams != 0) { + if (auto charType = + mlir::dyn_cast(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(loc, boxType, tempBox, shift, + /*slice=*/nullptr); + builder.create(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(loc, tempAddr); }); rewriter.eraseOp(op); @@ -408,11 +321,9 @@ class LowerRepackArraysPass void runOnOperation() override final { auto *context = &getContext(); mlir::ModuleOp module = getOperation(); - std::optional dl = fir::support::getOrSetMLIRDataLayout( - module, /*allowDefaultLayout=*/false); mlir::RewritePatternSet patterns(context); - patterns.insert(context, dl); - patterns.insert(context, dl); + patterns.insert(context); + patterns.insert(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 createArrayTemp(mlir::Location loc, fir::FirOpBuilder &builder, mlir::Type exprType, mlir::Value shape, - mlir::ValueRange extents, mlir::ValueRange lenParams, + llvm::ArrayRef extents, + llvm::ArrayRef lenParams, std::optional polymorphicMold) { - mlir::Type sequenceType = hlfir::getFortranElementOrSequenceType(exprType); + auto sequenceType = mlir::cast( + hlfir::getFortranElementOrSequenceType(exprType)); + + auto genTempDeclareOp = + [](fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value memref, + llvm::StringRef name, mlir::Value shape, + llvm::ArrayRef typeParams, + fir::FortranVariableFlagsAttr attrs) -> mlir::Value { + auto declareOp = + builder.create(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 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.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.shape<2>) -> !fir.class>>> // CHECK: fir.store %[[VAL_11]] to %[[VAL_4]] : !fir.ref>>>> -// CHECK: %[[VAL_12:.*]] = arith.constant true // CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs, uniq_name = ".tmp.array"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) // CHECK: %[[RANK:.*]] = arith.constant 2 : i32 // CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>>) -> !fir.ref> @@ -193,6 +192,7 @@ func.func @test_polymorphic(%arg0: !fir.class> {fir.bindc_ // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_31]] : (!fir.ref>) -> !fir.ref // CHECK: %[[VAL_38:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_36]], %[[VAL_34]], %[[VAL_35]], %[[VAL_37]], %[[VAL_33]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_12:.*]] = arith.constant true // CHECK: %[[VAL_39:.*]] = fir.load %[[VAL_13]]#0 : !fir.ref>>>> // 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.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.shape<2>) -> !fir.class>>> // CHECK: fir.store %[[VAL_12]] to %[[VAL_5]] : !fir.ref>>>> -// CHECK: %[[VAL_13:.*]] = arith.constant true // CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = ".tmp.array"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) // CHECK: %[[VAL_15:.*]] = arith.constant 2 : i32 // CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>>>>) -> !fir.ref> @@ -277,6 +276,7 @@ func.func @test_polymorphic_expr(%arg0: !fir.class> {fir.b // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_32]] : (!fir.ref>) -> !fir.ref // CHECK: %[[VAL_39:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_37]], %[[VAL_35]], %[[VAL_36]], %[[VAL_38]], %[[VAL_34]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_13:.*]] = arith.constant true // CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref>>>> // 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.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.shape<2>) -> !fir.class>>> // CHECK: fir.store %[[VAL_61]] to %[[VAL_4]] : !fir.ref>>>> -// CHECK: %[[VAL_62:.*]] = arith.constant true // CHECK: %[[VAL_63:.*]]:2 = hlfir.declare %[[VAL_4]] {fortran_attrs = #fir.var_attrs, uniq_name = ".tmp.array"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) // CHECK: %[[VAL_64:.*]] = arith.constant 2 : i32 // CHECK: %[[VAL_65:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>>) -> !fir.ref> @@ -330,6 +329,7 @@ func.func @test_polymorphic_expr(%arg0: !fir.class> {fir.b // CHECK: %[[VAL_86:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_87:.*]] = fir.convert %[[VAL_81]] : (!fir.ref>) -> !fir.ref // CHECK: %[[VAL_88:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_86]], %[[VAL_84]], %[[VAL_85]], %[[VAL_87]], %[[VAL_83]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_62:.*]] = arith.constant true // CHECK: %[[VAL_89:.*]] = fir.load %[[VAL_63]]#0 : !fir.ref>>>> // 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.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1Ex"} : (!fir.box>, !fir.dscope) -> !fir.box> + fir.unpack_array %1 to %arg0 heap : !fir.box> + return +} // CHECK-LABEL: func.func @_QPtest1( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box> {fir.bindc_name = "x"}) { -func.func @_QPtest1(%arg0: !fir.box> {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>) -> i1 -// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box>) { // CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>) -> 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.ref>> +// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>) -> i1 +// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>) { +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, 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, %[[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.shape<2>) -> !fir.heap> +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box> +// CHECK: fir.result %[[VAL_26]] : !fir.box> // CHECK: } else { -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> -// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>) -> i1 -// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box> // 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>) { -// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array, %[[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.shape<2>) -> !fir.box>> -// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>) -> !fir.box> -// CHECK: fir.result %[[VAL_25]] : !fir.box> +// CHECK: fir.result %[[VAL_14]] : !fir.box> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.box>) -> !fir.box> -// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1Ex"} : (!fir.box>, !fir.dscope) -> !fir.box> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1Ex"} : (!fir.box>, !fir.dscope) -> !fir.box> -// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 -// CHECK: fir.if %[[VAL_27]] { -// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> 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.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_28]] : !fir.heap> +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1Ex"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index +// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_29]] : !fir.heap> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.box> - return -} +// CHECK: return +// CHECK: } // Test 'stack whole' repacking. +func.func @_QPtest1_whole(%arg0: !fir.box> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 stack whole : (!fir.box>) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1_wholeEx"} : (!fir.box>, !fir.dscope) -> !fir.box> + fir.unpack_array %1 to %arg0 stack : !fir.box> + return +} // CHECK-LABEL: func.func @_QPtest1_whole( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box> {fir.bindc_name = "x"}) { -func.func @_QPtest1_whole(%arg0: !fir.box> {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>) -> i1 -// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box>) { // CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] whole : (!fir.box>) -> 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.ref>> +// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>) -> i1 +// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>) { +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, 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, %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked"} +// CHECK: %[[VAL_19:.*]] = fir.declare %[[VAL_18]](%[[VAL_17]]) {uniq_name = ".repacked"} : (!fir.ref>, !fir.shape<2>) -> !fir.ref> +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box> +// CHECK: fir.result %[[VAL_26]] : !fir.box> // CHECK: } else { -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> -// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>) -> i1 -// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box> // 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, %[[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.shape<2>) -> !fir.box> -// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box>) { -// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>) -> !fir.box> -// CHECK: fir.result %[[VAL_25]] : !fir.box> +// CHECK: fir.result %[[VAL_14]] : !fir.box> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box> // CHECK: } - %1 = fir.pack_array %arg0 stack whole : (!fir.box>) -> !fir.box> -// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1_wholeEx"} : (!fir.box>, !fir.dscope) -> !fir.box> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest1_wholeEx"} : (!fir.box>, !fir.dscope) -> !fir.box> -// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 -// CHECK: fir.if %[[VAL_27]] { -// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> 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.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest1_wholeEx"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index +// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 stack : !fir.box> - return -} +// CHECK: return +// CHECK: } // Test unpacking with no_copy. +func.func @_QPtest1_in(%arg0: !fir.box> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_inEx"} : (!fir.box>, !fir.dscope) -> !fir.box> + fir.unpack_array %1 to %arg0 heap no_copy : !fir.box> + return +} // CHECK-LABEL: func.func @_QPtest1_in( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box> {fir.bindc_name = "x"}) { -func.func @_QPtest1_in(%arg0: !fir.box> {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>) -> i1 -// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) { +// CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.box>) { // CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>) -> 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.ref>> +// CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref>>) -> i1 +// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1 +// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] -> (!fir.box>) { +// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, 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, %[[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.shape<2>) -> !fir.heap> +// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_18]](%[[VAL_16]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box> +// CHECK: fir.result %[[VAL_25]] : !fir.box> // CHECK: } else { -// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> -// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>) -> i1 -// CHECK: fir.result %[[VAL_10]]#1, %[[VAL_11]]#1, %[[VAL_13]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box> // 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>) { -// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array, %[[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.shape<2>) -> !fir.box>> -// CHECK: %[[VAL_20:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_0]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_24:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>>) -> !fir.box> -// CHECK: fir.result %[[VAL_24]] : !fir.box> +// CHECK: fir.result %[[VAL_13]] : !fir.box> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.box>) -> !fir.box> -// CHECK: %[[VAL_25:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_inEx"} : (!fir.box>, !fir.dscope) -> !fir.box> - %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_inEx"} : (!fir.box>, !fir.dscope) -> !fir.box> -// CHECK: %[[VAL_26:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 -// CHECK: fir.if %[[VAL_26]] { -// CHECK: %[[VAL_27:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_27]] : (!fir.heap>) -> index -// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index -// CHECK: %[[VAL_31:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_30]] : index -// CHECK: fir.if %[[VAL_31]] { -// CHECK: fir.freemem %[[VAL_27]] : !fir.heap> +// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_7]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_inEx"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_27]] { +// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>) -> index +// CHECK: %[[VAL_32:.*]] = arith.cmpi ne, %[[VAL_29]], %[[VAL_31]] : index +// CHECK: fir.if %[[VAL_32]] { +// CHECK: fir.freemem %[[VAL_28]] : !fir.heap> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap no_copy : !fir.box> - return -} +// CHECK: return +// CHECK: } // Test packing with no_copy. +func.func @_QPtest1_out(%arg0: !fir.box> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost no_copy : (!fir.box>) -> !fir.box> + %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_outEx"} : (!fir.box>, !fir.dscope) -> !fir.box> + fir.unpack_array %1 to %arg0 heap : !fir.box> + return +} // CHECK-LABEL: func.func @_QPtest1_out( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box> {fir.bindc_name = "x"}) { -func.func @_QPtest1_out(%arg0: !fir.box> {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>) -> i1 -// CHECK: %[[VAL_7:.*]]:3 = fir.if %[[VAL_6]] -> (index, index, i1) { +// CHECK: %[[VAL_7:.*]] = fir.if %[[VAL_6]] -> (!fir.box>) { // CHECK: %[[VAL_8:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>) -> 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.ref>> +// CHECK: %[[VAL_11:.*]] = fir.is_present %[[VAL_10]] : (!fir.ref>>) -> i1 +// CHECK: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1 +// CHECK: %[[VAL_13:.*]] = fir.if %[[VAL_12]] -> (!fir.box>) { +// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, 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, %[[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.shape<2>) -> !fir.heap> +// CHECK: %[[VAL_19:.*]] = fir.embox %[[VAL_18]](%[[VAL_16]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// 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.shift<2>) -> !fir.box> +// CHECK: fir.result %[[VAL_21]] : !fir.box> // CHECK: } else { -// CHECK: %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.ref> -// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>) -> i1 -// CHECK: fir.result %[[VAL_10]]#1, %[[VAL_11]]#1, %[[VAL_13]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box> // 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>) { -// CHECK: %[[VAL_17:.*]] = fir.allocmem !fir.array, %[[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.shape<2>) -> !fir.box>> -// CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>>) -> !fir.box> -// CHECK: fir.result %[[VAL_20]] : !fir.box> +// CHECK: fir.result %[[VAL_13]] : !fir.box> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost no_copy : (!fir.box>) -> !fir.box> -// CHECK: %[[VAL_21:.*]] = fir.declare %[[VAL_15]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_outEx"} : (!fir.box>, !fir.dscope) -> !fir.box> - %2 = fir.declare %1 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_outEx"} : (!fir.box>, !fir.dscope) -> !fir.box> -// CHECK: %[[VAL_22:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 -// CHECK: fir.if %[[VAL_22]] { -// CHECK: %[[VAL_23:.*]] = fir.box_addr %[[VAL_15]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_23]] : (!fir.heap>) -> index -// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> 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.box -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box>) -> !fir.box -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_28]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_29]], %[[VAL_30]], %[[VAL_31]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_23]] : !fir.heap> +// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] dummy_scope %[[VAL_5]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest1_outEx"} : (!fir.box>, !fir.dscope) -> !fir.box> +// CHECK: %[[VAL_23:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 +// CHECK: fir.if %[[VAL_23]] { +// CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> index +// CHECK: %[[VAL_26:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_7]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_29]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_30]], %[[VAL_31]], %[[VAL_32]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_24]] : !fir.heap> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.box> - return -} +// CHECK: return +// CHECK: } // Test character array with dynamic length and heap allocation +func.func @_QPtest2(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box>> {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, !fir.dscope) -> !fir.ref + %2 = fir.load %1 : !fir.ref + %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>>, i32) -> !fir.box>> + %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2Ex"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> + fir.unpack_array %5 to %arg1 heap : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest2( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref {fir.bindc_name = "n"}, // CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest2(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box>> {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, !fir.dscope) -> !fir.ref - %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2En"} : (!fir.ref, !fir.dscope) -> !fir.ref // CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref - %2 = fir.load %1 : !fir.ref // 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>>) -> i1 -// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { // CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_18:.*]] = fir.is_present %[[VAL_17]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1 +// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] -> (!fir.box>>) { +// CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_22:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, 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>(%[[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.shape<2>, i32) -> !fir.heap>> +// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_25]](%[[VAL_23]]) typeparams %[[VAL_12]] : (!fir.heap>>, !fir.shape<2>, i32) -> !fir.box>>> +// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_32]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_17]]#1, %[[VAL_18]]#1, %[[VAL_20]] : index, index, i1 +// CHECK: fir.result %[[VAL_1]] : !fir.box>> // 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>>) { -// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array>(%[[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.shape<2>, i32) -> !fir.box>>> -// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box>>>) -> !fir.box -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_26]] : (!fir.box>>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_31]] : !fir.box>> +// CHECK: fir.result %[[VAL_20]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_1]] : !fir.box>> // CHECK: } - %5 = fir.pack_array %arg1 heap innermost typeparams %4 : (!fir.box>>, i32) -> !fir.box>> -// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_22]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2Ex"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> - %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2Ex"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_33]] { -// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_22]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_22]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_34]] : !fir.heap>> +// CHECK: %[[VAL_33:.*]] = fir.declare %[[VAL_14]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2Ex"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_34]] { +// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_14]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_40]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_41]], %[[VAL_42]], %[[VAL_43]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_35]] : !fir.heap>> // CHECK: } // CHECK: } - fir.unpack_array %5 to %arg1 heap : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test character array with dynamic length and stack allocation +func.func @_QPtest2_stack(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box>> {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, !fir.dscope) -> !fir.ref + %2 = fir.load %1 : !fir.ref + %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>>, i32) -> !fir.box>> + %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2_stackEx"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> + fir.unpack_array %5 to %arg1 stack : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest2_stack( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.ref {fir.bindc_name = "n"}, // CHECK-SAME: %[[VAL_1:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest2_stack(%arg0: !fir.ref {fir.bindc_name = "n"}, %arg1: !fir.box>> {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, !fir.dscope) -> !fir.ref - %1 = fir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtest2_stackEn"} : (!fir.ref, !fir.dscope) -> !fir.ref // CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref - %2 = fir.load %1 : !fir.ref // 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>>) -> i1 -// CHECK: %[[VAL_14:.*]]:3 = fir.if %[[VAL_13]] -> (index, index, i1) { +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { // CHECK: %[[VAL_15:.*]] = fir.is_contiguous_box %[[VAL_1]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_18:.*]] = fir.is_present %[[VAL_17]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1 +// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_19]] -> (!fir.box>>) { +// CHECK: %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_22:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, 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>(%[[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.shape<2>, i32) -> !fir.ref>> +// CHECK: %[[VAL_26:.*]] = fir.embox %[[VAL_25]](%[[VAL_23]]) typeparams %[[VAL_12]] : (!fir.ref>>, !fir.shape<2>, i32) -> !fir.box>> +// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_32]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_19:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_20:.*]] = fir.is_present %[[VAL_19]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_17]]#1, %[[VAL_18]]#1, %[[VAL_20]] : index, index, i1 +// CHECK: fir.result %[[VAL_1]] : !fir.box>> // 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>(%[[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.shape<2>, i32) -> !fir.box>> -// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_14]]#2 -> (!fir.box>>) { -// CHECK: %[[VAL_27:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_1]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_3]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_31:.*]] = fir.rebox %[[VAL_25]] : (!fir.box>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_31]] : !fir.box>> +// CHECK: fir.result %[[VAL_20]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_1]] : !fir.box>> // CHECK: } - %5 = fir.pack_array %arg1 stack innermost typeparams %4 : (!fir.box>>, i32) -> !fir.box>> -// CHECK: %[[VAL_32:.*]] = fir.declare %[[VAL_26]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEx"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> - %6 = fir.declare %5 typeparams %4 dummy_scope %0 {uniq_name = "_QFtest2_stackEx"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_33:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_33]] { -// CHECK: %[[VAL_34:.*]] = fir.box_addr %[[VAL_26]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_34]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_26]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_33:.*]] = fir.declare %[[VAL_14]] typeparams %[[VAL_12]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest2_stackEx"} : (!fir.box>>, i32, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_34]] { +// CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_14]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_40]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_41]], %[[VAL_42]], %[[VAL_43]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () // CHECK: } // CHECK: } - fir.unpack_array %5 to %arg1 stack : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test character array with assumed length and heap allocation. +func.func @_QPtest3(%arg0: !fir.box>> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + fir.unpack_array %1 to %arg0 heap : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest3( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest3(%arg0: !fir.box>> {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>>) -> i1 -// CHECK: %[[VAL_8:.*]]:4 = fir.if %[[VAL_7]] -> (index, index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box>>) { // CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index +// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array>(%[[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.shape<2>, index) -> !fir.heap>> +// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) typeparams %[[VAL_17]] : (!fir.heap>>, !fir.shape<2>, index) -> !fir.box>>> +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_27]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index -// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> 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>> // 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>>) { -// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array>(%[[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.shape<2>, index) -> !fir.box>>> -// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box>>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: fir.result %[[VAL_14]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box>> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> -// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_28]] { -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> +// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_29]] { +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_30]] : !fir.heap>> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test character array with assumed length and stack allocation. +func.func @_QPtest3_stack(%arg0: !fir.box>> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + fir.unpack_array %1 to %arg0 stack : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest3_stack( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest3_stack(%arg0: !fir.box>> {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>>) -> i1 -// CHECK: %[[VAL_8:.*]]:4 = fir.if %[[VAL_7]] -> (index, index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box>>) { // CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_17:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index +// CHECK: %[[VAL_18:.*]] = fir.shape %[[VAL_15]]#1, %[[VAL_16]]#1 : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_19:.*]] = fir.alloca !fir.array>(%[[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.shape<2>, index) -> !fir.ref>> +// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) typeparams %[[VAL_17]] : (!fir.ref>>, !fir.shape<2>, index) -> !fir.box>> +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_27]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index -// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> 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>> // 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>(%[[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.shape<2>, index) -> !fir.box>> -// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_8]]#3 -> (!fir.box>>) { -// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: fir.result %[[VAL_14]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box>> // CHECK: } - %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> -// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest3_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_28]] { -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest3_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_29]] { +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 stack : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test character array with constant length and heap allocation. +func.func @_QPtest4(%arg0: !fir.box>> {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.box>> + %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4Ex"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> + fir.unpack_array %1 to %arg0 heap : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest4( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest4(%arg0: !fir.box>> {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>>) -> i1 -// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) { +// CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_8]] -> (!fir.box>>) { // CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_13]] : i1 +// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (!fir.box>>) { +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, 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>, %[[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.shape<2>, index) -> !fir.heap>> +// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) : (!fir.heap>>, !fir.shape<2>) -> !fir.box>>> +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_27]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_12]]#1, %[[VAL_13]]#1, %[[VAL_15]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box>> // 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>>) { -// CHECK: %[[VAL_19:.*]] = fir.allocmem !fir.array>, %[[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.shape<2>) -> !fir.box>>> -// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_21]] : (!fir.box>>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: fir.result %[[VAL_15]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box>> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> -// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_17]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4Ex"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> - %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4Ex"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_28]] { -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_17]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> +// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_9]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4Ex"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_29]] { +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_30]] : !fir.heap>> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test character array with constant length and stack allocation. +func.func @_QPtest4_stack(%arg0: !fir.box>> {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.box>> + %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4_stackEx"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> + fir.unpack_array %1 to %arg0 stack : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest4_stack( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest4_stack(%arg0: !fir.box>> {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>>) -> i1 -// CHECK: %[[VAL_9:.*]]:3 = fir.if %[[VAL_8]] -> (index, index, i1) { +// CHECK: %[[VAL_9:.*]] = fir.if %[[VAL_8]] -> (!fir.box>>) { // CHECK: %[[VAL_10:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_13:.*]] = fir.is_present %[[VAL_12]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_13]] : i1 +// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_14]] -> (!fir.box>>) { +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, 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>, %[[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.shape<2>, index) -> !fir.ref>> +// CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]](%[[VAL_18]]) : (!fir.ref>>, !fir.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_27]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_15:.*]] = fir.is_present %[[VAL_14]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_12]]#1, %[[VAL_13]]#1, %[[VAL_15]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box>> // 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>, %[[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.shape<2>) -> !fir.box>> -// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_9]]#2 -> (!fir.box>>) { -// CHECK: %[[VAL_22:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_22]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_26:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_26]] : !fir.box>> +// CHECK: fir.result %[[VAL_15]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box>> // CHECK: } - %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> -// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_21]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4_stackEx"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> - %2 = fir.declare %1 typeparams %c10 dummy_scope %0 {uniq_name = "_QFtest4_stackEx"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_28]] { -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_21]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_28:.*]] = fir.declare %[[VAL_9]] typeparams %[[VAL_6]] dummy_scope %[[VAL_7]] {uniq_name = "_QFtest4_stackEx"} : (!fir.box>>, index, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_29]] { +// CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_35]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_36]], %[[VAL_37]], %[[VAL_38]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 stack : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test derived type array with heap allocation. +func.func @_QPtest5(%arg0: !fir.box>> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + fir.unpack_array %1 to %arg0 heap : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest5( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest5(%arg0: !fir.box>> {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>>) -> i1 -// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box>>) { // CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, 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>, %[[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.shape<2>) -> !fir.heap>> +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.heap>>, !fir.shape<2>) -> !fir.box>>> +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_26]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box>> // 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>>) { -// CHECK: %[[VAL_18:.*]] = fir.allocmem !fir.array>, %[[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.shape<2>) -> !fir.box>>> -// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>>) -> !fir.box -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_20]] : (!fir.box>>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_25]] : !fir.box>> +// CHECK: fir.result %[[VAL_14]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box>> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.box>>) -> !fir.box>> -// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_16]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_27]] { -// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_16]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_28]] : !fir.heap>> +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5Ex"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_29]] : !fir.heap>> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test derived type array with stack allocation. +func.func @_QPtest5_stack(%arg0: !fir.box>> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> + fir.unpack_array %1 to %arg0 stack : !fir.box>> + return +} // CHECK-LABEL: func.func @_QPtest5_stack( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.box>> {fir.bindc_name = "x"}) { -func.func @_QPtest5_stack(%arg0: !fir.box>> {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>>) -> i1 -// CHECK: %[[VAL_8:.*]]:3 = fir.if %[[VAL_7]] -> (index, index, i1) { +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.box>>) { // CHECK: %[[VAL_9:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.box>>) -> 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.ref>>> +// CHECK: %[[VAL_12:.*]] = fir.is_present %[[VAL_11]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1 +// CHECK: %[[VAL_14:.*]] = fir.if %[[VAL_13]] -> (!fir.box>>) { +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_16:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, 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>, %[[VAL_15]]#1, %[[VAL_16]]#1 {bindc_name = ".repacked"} +// CHECK: %[[VAL_19:.*]] = fir.declare %[[VAL_18]](%[[VAL_17]]) {uniq_name = ".repacked"} : (!fir.ref>>, !fir.shape<2>) -> !fir.ref>> +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_19]](%[[VAL_17]]) : (!fir.ref>>, !fir.shape<2>) -> !fir.box>> +// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.box>> +// CHECK: fir.result %[[VAL_26]] : !fir.box>> // CHECK: } else { -// CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>>, index) -> (index, index, index) -// CHECK: %[[VAL_13:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.ref>> -// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_11]]#1, %[[VAL_12]]#1, %[[VAL_14]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.box>> // 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>, %[[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.shape<2>) -> !fir.box>> -// CHECK: %[[VAL_20:.*]] = fir.if %[[VAL_8]]#2 -> (!fir.box>>) { -// CHECK: %[[VAL_21:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_19]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_0]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_21]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.rebox %[[VAL_19]] : (!fir.box>>) -> !fir.box>> -// CHECK: fir.result %[[VAL_25]] : !fir.box>> +// CHECK: fir.result %[[VAL_14]] : !fir.box>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.box>> // CHECK: } - %1 = fir.pack_array %arg0 stack innermost : (!fir.box>>) -> !fir.box>> -// CHECK: %[[VAL_26:.*]] = fir.declare %[[VAL_20]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest5_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> -// CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 -// CHECK: fir.if %[[VAL_27]] { -// CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_20]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_20]] : (!fir.box>>) -> !fir.box -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_34]], %[[VAL_35]], %[[VAL_36]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_27:.*]] = fir.declare %[[VAL_8]] dummy_scope %[[VAL_6]] {uniq_name = "_QFtest5_stackEx"} : (!fir.box>>, !fir.dscope) -> !fir.box>> +// CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 +// CHECK: fir.if %[[VAL_28]] { +// CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_8]] : (!fir.box>>) -> !fir.box +// CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_34]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_35]], %[[VAL_36]], %[[VAL_37]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 stack : !fir.box>> - return -} +// CHECK: return +// CHECK: } // Test polymorphic type array with heap allocation. +func.func @_QPtest6(%arg0: !fir.class>> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost : (!fir.class>>) -> !fir.class>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6Ex"} : (!fir.class>>, !fir.dscope) -> !fir.class>> + fir.unpack_array %1 to %arg0 heap : !fir.class>> + return +} // CHECK-LABEL: func.func @_QPtest6( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class>> {fir.bindc_name = "x"}) { -func.func @_QPtest6(%arg0: !fir.class>> {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>>> // CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope - %0 = fir.dummy_scope : !fir.dscope // CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 -// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class>>) { // CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>>) -> 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.ref>>> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1 +// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class>>) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap>> +// 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.shape<2>) -> !fir.class>>> +// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref>>>> +// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs, uniq_name = ".repacked"} : (!fir.ref>>>>) -> !fir.ref>>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref>>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.class>> +// CHECK: fir.result %[[VAL_44]] : !fir.class>> // CHECK: } else { -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) -// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.ref>> -// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.class>> // 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>>) { -// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap>> -// 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.shape<2>) -> !fir.class>>> -// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>>> -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box -// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>>> -// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>>) -> !fir.box -// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box -// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>>) -> !fir.class>> -// CHECK: fir.result %[[VAL_43]] : !fir.class>> +// CHECK: fir.result %[[VAL_16]] : !fir.class>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.class>> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.class>>) -> !fir.class>> -// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6Ex"} : (!fir.class>>, !fir.dscope) -> !fir.class>> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6Ex"} : (!fir.class>>, !fir.dscope) -> !fir.class>> -// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 -// CHECK: fir.if %[[VAL_45]] { -// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>>) -> !fir.heap>> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> -// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>>) -> !fir.box -// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_46]] : !fir.heap>> +// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6Ex"} : (!fir.class>>, !fir.dscope) -> !fir.class>> +// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 +// CHECK: fir.if %[[VAL_46]] { +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_47]] : !fir.heap>> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.class>> +// 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.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 stack innermost : (!fir.class>>) -> !fir.class>> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6_stackEx"} : (!fir.class>>, !fir.dscope) -> !fir.class>> + fir.unpack_array %1 to %arg0 stack : !fir.class>> 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.bindc_name = "x"}) { -func.func @_QPtest6_stack(%arg0: !fir.class>> {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>>> // CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope - %0 = fir.dummy_scope : !fir.dscope // CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 -// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class>>) { // CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>>) -> 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.ref>>> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>>) -> i1 +// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1 +// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class>>) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap>> +// 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.shape<2>) -> !fir.class>>> +// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref>>>> +// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs, uniq_name = ".repacked"} : (!fir.ref>>>>) -> !fir.ref>>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref>>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.class>> +// CHECK: fir.result %[[VAL_44]] : !fir.class>> // CHECK: } else { -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class>>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>>, index) -> (index, index, index) -// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.ref>> -// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>>) -> i1 -// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.class>> // 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>>) { -// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap>> -// 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.shape<2>) -> !fir.class>>> -// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>>> -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box -// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>>) -> !fir.ref> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>>> -// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>>) -> !fir.box -// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>>) -> !fir.box -// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>>) -> !fir.class>> -// CHECK: fir.result %[[VAL_43]] : !fir.class>> +// CHECK: fir.result %[[VAL_16]] : !fir.class>> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.class>> // CHECK: } - %1 = fir.pack_array %arg0 stack innermost : (!fir.class>>) -> !fir.class>> -// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6_stackEx"} : (!fir.class>>, !fir.dscope) -> !fir.class>> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest6_stackEx"} : (!fir.class>>, !fir.dscope) -> !fir.class>> -// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 -// CHECK: fir.if %[[VAL_45]] { -// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>>) -> !fir.heap>> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>>) -> index -// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> -// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> 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.box -// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>>) -> !fir.box -// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest6_stackEx"} : (!fir.class>>, !fir.dscope) -> !fir.class>> +// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 +// CHECK: fir.if %[[VAL_46]] { +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> index +// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>>) -> 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.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_47]] : !fir.heap>> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 stack : !fir.class>> - return -} +// CHECK: return +// CHECK: } // Test unlimited polymorphic type array with heap allocation. +func.func @_QPtest7(%arg0: !fir.class> {fir.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 heap innermost : (!fir.class>) -> !fir.class> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> + fir.unpack_array %1 to %arg0 heap : !fir.class> + return +} // CHECK-LABEL: func.func @_QPtest7( // CHECK-SAME: %[[VAL_0:[0-9]+|[a-zA-Z$._-][a-zA-Z0-9$._-]*]]: !fir.class> {fir.bindc_name = "x"}) { -func.func @_QPtest7(%arg0: !fir.class> {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>> // CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope - %0 = fir.dummy_scope : !fir.dscope // CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 -// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class>) { // CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>) -> 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.ref>> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>) -> i1 +// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1 +// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class>) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap> +// 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.shape<2>) -> !fir.class>> +// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs, uniq_name = ".repacked"} : (!fir.ref>>>) -> !fir.ref>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.class> +// CHECK: fir.result %[[VAL_44]] : !fir.class> // CHECK: } else { -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>, index) -> (index, index, index) -// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.ref> -// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>) -> i1 -// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.class> // 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>) { -// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap> -// 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.shape<2>) -> !fir.class>> -// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>> -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box -// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>> -// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>) -> !fir.box -// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box -// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>) -> !fir.class> -// CHECK: fir.result %[[VAL_43]] : !fir.class> +// CHECK: fir.result %[[VAL_16]] : !fir.class> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.class> // CHECK: } - %1 = fir.pack_array %arg0 heap innermost : (!fir.class>) -> !fir.class> -// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> -// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 -// CHECK: fir.if %[[VAL_45]] { -// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>) -> !fir.heap> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>) -> index -// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> -// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> 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.box -// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>) -> !fir.box -// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: fir.freemem %[[VAL_46]] : !fir.heap> +// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> +// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 +// CHECK: fir.if %[[VAL_46]] { +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> index +// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_47]] : !fir.heap> // CHECK: } // CHECK: } - fir.unpack_array %1 to %arg0 heap : !fir.class> +// 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.bindc_name = "x"}) { + %0 = fir.dummy_scope : !fir.dscope + %1 = fir.pack_array %arg0 stack innermost : (!fir.class>) -> !fir.class> + %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> + fir.unpack_array %1 to %arg0 stack : !fir.class> 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.bindc_name = "x"}) { -func.func @_QPtest7_stack(%arg0: !fir.class> {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>> // CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope - %0 = fir.dummy_scope : !fir.dscope // CHECK: %[[VAL_9:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 -// CHECK: %[[VAL_10:.*]]:3 = fir.if %[[VAL_9]] -> (index, index, i1) { +// CHECK: %[[VAL_10:.*]] = fir.if %[[VAL_9]] -> (!fir.class>) { // CHECK: %[[VAL_11:.*]] = fir.is_contiguous_box %[[VAL_0]] innermost : (!fir.class>) -> 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.ref>> +// CHECK: %[[VAL_14:.*]] = fir.is_present %[[VAL_13]] : (!fir.ref>>) -> i1 +// CHECK: %[[VAL_15:.*]] = arith.andi %[[VAL_12]], %[[VAL_14]] : i1 +// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (!fir.class>) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.class>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]] = fir.zero_bits !fir.heap> +// 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.shape<2>) -> !fir.class>> +// CHECK: fir.store %[[VAL_21]] to %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_22:.*]] = fir.declare %[[VAL_7]] {fortran_attrs = #fir.var_attrs, uniq_name = ".repacked"} : (!fir.ref>>>) -> !fir.ref>>> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// 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>, i32, i64, i64) -> () +// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box +// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref +// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_6]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_22]] : !fir.ref>>> +// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>) -> !fir.box +// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, 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.shift<2>) -> !fir.class> +// CHECK: fir.result %[[VAL_44]] : !fir.class> // CHECK: } else { -// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.class>, index) -> (index, index, index) -// CHECK: %[[VAL_14:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.class>, index) -> (index, index, index) -// CHECK: %[[VAL_15:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.ref> -// CHECK: %[[VAL_16:.*]] = fir.is_present %[[VAL_15]] : (!fir.ref>) -> i1 -// CHECK: fir.result %[[VAL_13]]#1, %[[VAL_14]]#1, %[[VAL_16]] : index, index, i1 +// CHECK: fir.result %[[VAL_0]] : !fir.class> // 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>) { -// CHECK: %[[VAL_20:.*]] = fir.zero_bits !fir.heap> -// 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.shape<2>) -> !fir.class>> -// CHECK: fir.store %[[VAL_22]] to %[[VAL_7]] : !fir.ref>>> -// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box -// CHECK: fir.call @_FortranAAllocatableApplyMold(%[[VAL_23]], %[[VAL_24]], %[[VAL_3]]) : (!fir.ref>, !fir.box, i32) -> () -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// 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>, i32, i64, i64) -> () -// CHECK: %[[VAL_33:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_34:.*]] = fir.absent !fir.box -// CHECK: %[[VAL_35:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_33]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_37:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_35]], %[[VAL_5]], %[[VAL_34]], %[[VAL_36]], %[[VAL_2]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 -// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_7]] : !fir.ref>>> -// CHECK: %[[VAL_39:.*]] = fir.address_of(@{{_QQcl.*}} -// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_38]] : (!fir.class>>) -> !fir.box -// CHECK: %[[VAL_41:.*]] = fir.convert %[[VAL_0]] : (!fir.class>) -> !fir.box -// CHECK: %[[VAL_42:.*]] = fir.convert %[[VAL_39]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_40]], %[[VAL_41]], %[[VAL_42]], %[[VAL_2]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () -// CHECK: %[[VAL_43:.*]] = fir.rebox %[[VAL_38]] : (!fir.class>>) -> !fir.class> -// CHECK: fir.result %[[VAL_43]] : !fir.class> +// CHECK: fir.result %[[VAL_16]] : !fir.class> // CHECK: } else { // CHECK: fir.result %[[VAL_0]] : !fir.class> // CHECK: } - %1 = fir.pack_array %arg0 stack innermost : (!fir.class>) -> !fir.class> -// CHECK: %[[VAL_44:.*]] = fir.declare %[[VAL_18]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> - %2 = fir.declare %1 dummy_scope %0 {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> -// CHECK: %[[VAL_45:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 -// CHECK: fir.if %[[VAL_45]] { -// CHECK: %[[VAL_46:.*]] = fir.box_addr %[[VAL_18]] : (!fir.class>) -> !fir.heap> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_46]] : (!fir.heap>) -> index -// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> -// CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> 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.box -// CHECK: %[[VAL_53:.*]] = fir.convert %[[VAL_18]] : (!fir.class>) -> !fir.box -// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_51]] : (!fir.ref>) -> !fir.ref -// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: %[[VAL_45:.*]] = fir.declare %[[VAL_10]] dummy_scope %[[VAL_8]] {uniq_name = "_QFtest7Ex"} : (!fir.class>, !fir.dscope) -> !fir.class> +// CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 +// CHECK: fir.if %[[VAL_46]] { +// CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> index +// CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>) -> 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.box +// CHECK: %[[VAL_54:.*]] = fir.convert %[[VAL_10]] : (!fir.class>) -> !fir.box +// CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_52]] : (!fir.ref>) -> !fir.ref +// CHECK: fir.call @_FortranAShallowCopyDirect(%[[VAL_53]], %[[VAL_54]], %[[VAL_55]], %[[VAL_1]]) : (!fir.box, !fir.box, !fir.ref, i32) -> () +// CHECK: fir.freemem %[[VAL_47]] : !fir.heap> // CHECK: } // CHECK: } // CHECK: return // CHECK: } - fir.unpack_array %1 to %arg0 stack : !fir.class> - return -} From a60ee69ddee770cea0432e3f8ff1c50868882d41 Mon Sep 17 00:00:00 2001 From: Slava Zakharin 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(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( - 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 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(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(loc, addrType, tempBox); - mlir::Value tempAddrAsIndex = - builder.createConvert(loc, indexType, tempAddr); mlir::Value originalAddr = builder.create(loc, addrType, originalBox); - originalAddr = builder.createConvert(loc, indexType, originalAddr); - auto isNotSame = builder.create( - 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 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.bindc_name = "x"}) // CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 // CHECK: fir.if %[[VAL_28]] { // CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index // CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>) -> 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.bindc_name = // CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 // CHECK: fir.if %[[VAL_28]] { // CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index // CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>) -> 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.bindc_name = "x // CHECK: %[[VAL_27:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 // CHECK: fir.if %[[VAL_27]] { // CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index // CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (!fir.heap>) -> index // CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>) -> 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.bindc_name = " // CHECK: %[[VAL_23:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>) -> i1 // CHECK: fir.if %[[VAL_23]] { // CHECK: %[[VAL_24:.*]] = fir.box_addr %[[VAL_7]] : (!fir.box>) -> !fir.heap> -// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> index // CHECK: %[[VAL_26:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>) -> !fir.heap> +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.heap>) -> index // CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.heap>) -> 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 {fir.bindc_name = "n"}, %arg1: !fir.box // CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_34]] { // CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index // CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index // CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> 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 {fir.bindc_name = "n"}, %arg1: !f // CHECK: %[[VAL_34:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_34]] { // CHECK: %[[VAL_35:.*]] = fir.box_addr %[[VAL_14]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index // CHECK: %[[VAL_37:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (!fir.heap>>) -> index // CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (!fir.heap>>) -> 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.bindc_n // CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_29]] { // CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.b // CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_29]] { // CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.bindc_ // CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_29]] { // CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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. // CHECK: %[[VAL_29:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_29]] { // CHECK: %[[VAL_30:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (!fir.heap>>) -> index // CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (!fir.heap>>) -> 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.bind // CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_28]] { // CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index // CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>>) -> 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>> {fi // CHECK: %[[VAL_28:.*]] = fir.is_present %[[VAL_0]] : (!fir.box>>) -> i1 // CHECK: fir.if %[[VAL_28]] { // CHECK: %[[VAL_29:.*]] = fir.box_addr %[[VAL_8]] : (!fir.box>>) -> !fir.heap>> -// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index // CHECK: %[[VAL_31:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box>>) -> !fir.heap>> +// CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (!fir.heap>>) -> index // CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (!fir.heap>>) -> 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.bi // CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 // CHECK: fir.if %[[VAL_46]] { // CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>>) -> !fir.heap>> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> index // CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> index // CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>>) -> 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>> { // CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>>) -> i1 // CHECK: fir.if %[[VAL_46]] { // CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>>) -> !fir.heap>> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> index // CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>>) -> !fir.heap>> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>>) -> index // CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>>) -> 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.bindc_name = "x // CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 // CHECK: fir.if %[[VAL_46]] { // CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>) -> !fir.heap> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> index // CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> index // CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>) -> 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.bindc_nam // CHECK: %[[VAL_46:.*]] = fir.is_present %[[VAL_0]] : (!fir.class>) -> i1 // CHECK: fir.if %[[VAL_46]] { // CHECK: %[[VAL_47:.*]] = fir.box_addr %[[VAL_10]] : (!fir.class>) -> !fir.heap> -// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> index // CHECK: %[[VAL_49:.*]] = fir.box_addr %[[VAL_0]] : (!fir.class>) -> !fir.heap> +// CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (!fir.heap>) -> index // CHECK: %[[VAL_50:.*]] = fir.convert %[[VAL_49]] : (!fir.heap>) -> 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 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();