diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h index 5440b36c0c628..98d7de81c7f08 100644 --- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h @@ -26,6 +26,7 @@ #include "flang/Support/Fortran.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/MLIRContext.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include #include @@ -824,33 +825,23 @@ static mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc, return getRuntimeFunc(loc, builder, /*isIO=*/true); } -namespace helper { -template -void createArguments(llvm::SmallVectorImpl &result, - fir::FirOpBuilder &builder, mlir::Location loc, - mlir::FunctionType fTy, A arg) { - result.emplace_back( - builder.createConvertWithVolatileCast(loc, fTy.getInput(N), arg)); -} - -template -void createArguments(llvm::SmallVectorImpl &result, - fir::FirOpBuilder &builder, mlir::Location loc, - mlir::FunctionType fTy, A arg, As... args) { - result.emplace_back( - builder.createConvertWithVolatileCast(loc, fTy.getInput(N), arg)); - createArguments(result, builder, loc, fTy, args...); +inline llvm::SmallVector +createArguments(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::FunctionType fTy, llvm::ArrayRef args) { + return llvm::map_to_vector(llvm::zip_equal(fTy.getInputs(), args), + [&](const auto &pair) -> mlir::Value { + auto [type, argument] = pair; + return builder.createConvertWithVolatileCast( + loc, type, argument); + }); } -} // namespace helper /// Create a SmallVector of arguments for a runtime call. template llvm::SmallVector createArguments(fir::FirOpBuilder &builder, mlir::Location loc, mlir::FunctionType fTy, As... args) { - llvm::SmallVector result; - helper::createArguments<0>(result, builder, loc, fTy, args...); - return result; + return createArguments(builder, loc, fTy, {args...}); } } // namespace fir::runtime diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp index 8d0444a6e5bd4..7e32575caad9b 100644 --- a/flang/lib/Lower/Allocatable.cpp +++ b/flang/lib/Lower/Allocatable.cpp @@ -138,12 +138,10 @@ static void genRuntimeSetBounds(fir::FirOpBuilder &builder, mlir::Location loc, builder) : fir::runtime::getRuntimeFunc( loc, builder); - llvm::SmallVector args{box.getAddr(), dimIndex, lowerBound, - upperBound}; - llvm::SmallVector operands; - for (auto [fst, snd] : llvm::zip(args, callee.getFunctionType().getInputs())) - operands.emplace_back(builder.createConvert(loc, snd, fst)); - builder.create(loc, callee, operands); + const auto args = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), box.getAddr(), dimIndex, + lowerBound, upperBound); + builder.create(loc, callee, args); } /// Generate runtime call to set the lengths of a character allocatable or @@ -162,9 +160,7 @@ static void genRuntimeInitCharacter(fir::FirOpBuilder &builder, if (inputTypes.size() != 5) fir::emitFatalError( loc, "AllocatableInitCharacter runtime interface not as expected"); - llvm::SmallVector args; - args.push_back(builder.createConvert(loc, inputTypes[0], box.getAddr())); - args.push_back(builder.createConvert(loc, inputTypes[1], len)); + llvm::SmallVector args = {box.getAddr(), len}; if (kind == 0) kind = mlir::cast(box.getEleTy()).getFKind(); args.push_back(builder.createIntegerConstant(loc, inputTypes[2], kind)); @@ -173,7 +169,9 @@ static void genRuntimeInitCharacter(fir::FirOpBuilder &builder, // TODO: coarrays int corank = 0; args.push_back(builder.createIntegerConstant(loc, inputTypes[4], corank)); - builder.create(loc, callee, args); + const auto convertedArgs = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), args); + builder.create(loc, callee, convertedArgs); } /// Generate a sequence of runtime calls to allocate memory. @@ -194,10 +192,9 @@ static mlir::Value genRuntimeAllocate(fir::FirOpBuilder &builder, args.push_back(errorManager.errMsgAddr); args.push_back(errorManager.sourceFile); args.push_back(errorManager.sourceLine); - llvm::SmallVector operands; - for (auto [fst, snd] : llvm::zip(args, callee.getFunctionType().getInputs())) - operands.emplace_back(builder.createConvert(loc, snd, fst)); - return builder.create(loc, callee, operands).getResult(0); + const auto convertedArgs = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), args); + return builder.create(loc, callee, convertedArgs).getResult(0); } /// Generate a sequence of runtime calls to allocate memory and assign with the @@ -213,14 +210,11 @@ static mlir::Value genRuntimeAllocateSource(fir::FirOpBuilder &builder, loc, builder) : fir::runtime::getRuntimeFunc( loc, builder); - llvm::SmallVector args{ - box.getAddr(), fir::getBase(source), - errorManager.hasStat, errorManager.errMsgAddr, - errorManager.sourceFile, errorManager.sourceLine}; - llvm::SmallVector operands; - for (auto [fst, snd] : llvm::zip(args, callee.getFunctionType().getInputs())) - operands.emplace_back(builder.createConvert(loc, snd, fst)); - return builder.create(loc, callee, operands).getResult(0); + const auto args = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), box.getAddr(), + fir::getBase(source), errorManager.hasStat, errorManager.errMsgAddr, + errorManager.sourceFile, errorManager.sourceLine); + return builder.create(loc, callee, args).getResult(0); } /// Generate runtime call to apply mold to the descriptor. @@ -234,14 +228,12 @@ static void genRuntimeAllocateApplyMold(fir::FirOpBuilder &builder, builder) : fir::runtime::getRuntimeFunc( loc, builder); - llvm::SmallVector args{ + const auto args = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), fir::factory::getMutableIRBox(builder, loc, box), fir::getBase(mold), builder.createIntegerConstant( - loc, callee.getFunctionType().getInputs()[2], rank)}; - llvm::SmallVector operands; - for (auto [fst, snd] : llvm::zip(args, callee.getFunctionType().getInputs())) - operands.emplace_back(builder.createConvert(loc, snd, fst)); - builder.create(loc, callee, operands); + loc, callee.getFunctionType().getInputs()[2], rank)); + builder.create(loc, callee, args); } /// Generate a runtime call to deallocate memory. @@ -669,15 +661,13 @@ class AllocateStmtHelper { llvm::ArrayRef inputTypes = callee.getFunctionType().getInputs(); - llvm::SmallVector args; - args.push_back(builder.createConvert(loc, inputTypes[0], box.getAddr())); - args.push_back(builder.createConvert(loc, inputTypes[1], typeDescAddr)); mlir::Value rankValue = builder.createIntegerConstant(loc, inputTypes[2], rank); mlir::Value corankValue = builder.createIntegerConstant(loc, inputTypes[3], corank); - args.push_back(rankValue); - args.push_back(corankValue); + const auto args = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), box.getAddr(), typeDescAddr, + rankValue, corankValue); builder.create(loc, callee, args); } @@ -696,8 +686,6 @@ class AllocateStmtHelper { llvm::ArrayRef inputTypes = callee.getFunctionType().getInputs(); - llvm::SmallVector args; - args.push_back(builder.createConvert(loc, inputTypes[0], box.getAddr())); mlir::Value categoryValue = builder.createIntegerConstant( loc, inputTypes[1], static_cast(category)); mlir::Value kindValue = @@ -706,10 +694,9 @@ class AllocateStmtHelper { builder.createIntegerConstant(loc, inputTypes[3], rank); mlir::Value corankValue = builder.createIntegerConstant(loc, inputTypes[4], corank); - args.push_back(categoryValue); - args.push_back(kindValue); - args.push_back(rankValue); - args.push_back(corankValue); + const auto args = fir::runtime::createArguments( + builder, loc, callee.getFunctionType(), box.getAddr(), categoryValue, + kindValue, rankValue, corankValue); builder.create(loc, callee, args); } diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp index 04b63f92a1fb4..395f4518efb1e 100644 --- a/flang/lib/Lower/ConvertExprToHLFIR.cpp +++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp @@ -227,6 +227,12 @@ class HlfirDesignatorBuilder { isVolatile = true; } + // Check if the base type is volatile + if (partInfo.base.has_value()) { + mlir::Type baseType = partInfo.base.value().getType(); + isVolatile = isVolatile || fir::isa_volatile_type(baseType); + } + // Dynamic type of polymorphic base must be kept if the designator is // polymorphic. if (isPolymorphic(designatorNode)) @@ -238,12 +244,6 @@ class HlfirDesignatorBuilder { if (charType && charType.hasDynamicLen()) return fir::BoxCharType::get(charType.getContext(), charType.getFKind()); - // Check if the base type is volatile - if (partInfo.base.has_value()) { - mlir::Type baseType = partInfo.base.value().getType(); - isVolatile = isVolatile || fir::isa_volatile_type(baseType); - } - // Arrays with non default lower bounds or dynamic length or dynamic extent // need a fir.box to hold the dynamic or lower bound information. if (fir::hasDynamicSize(resultValueType) || diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp index eef1377f26961..711d5d1461b08 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -210,15 +210,14 @@ static bool hasExplicitLowerBounds(mlir::Value shape) { static std::pair updateDeclareInputTypeWithVolatility( mlir::Type inputType, mlir::Value memref, mlir::OpBuilder &builder, fir::FortranVariableFlagsAttr fortran_attrs) { - if (mlir::isa(inputType) && fortran_attrs && + if (fortran_attrs && bitEnumContainsAny(fortran_attrs.getFlags(), fir::FortranVariableFlagsEnum::fortran_volatile)) { const bool isPointer = bitEnumContainsAny( fortran_attrs.getFlags(), fir::FortranVariableFlagsEnum::pointer); auto updateType = [&](auto t) { using FIRT = decltype(t); - // If an entity is a pointer, the entity it points to is volatile, as far - // as consumers of the pointer are concerned. + // A volatile pointer's pointee is volatile. auto elementType = t.getEleTy(); const bool elementTypeIsVolatile = isPointer || fir::isa_volatile_type(elementType); @@ -227,8 +226,7 @@ static std::pair updateDeclareInputTypeWithVolatility( inputType = FIRT::get(newEleTy, true); }; llvm::TypeSwitch(inputType) - .Case(updateType) - .Default([](mlir::Type t) { return t; }); + .Case(updateType); memref = builder.create(memref.getLoc(), inputType, memref); } diff --git a/flang/test/Lower/allocatable-polymorphic.f90 b/flang/test/Lower/allocatable-polymorphic.f90 index dd8671daeaf8e..10e703210ea61 100644 --- a/flang/test/Lower/allocatable-polymorphic.f90 +++ b/flang/test/Lower/allocatable-polymorphic.f90 @@ -41,7 +41,7 @@ subroutine proc2_p2(this) end subroutine ! ------------------------------------------------------------------------------ -! Test lowering of ALLOCATE statement for polymoprhic pointer +! Test lowering of ALLOCATE statement for polymorphic pointer ! ------------------------------------------------------------------------------ subroutine test_pointer() @@ -98,10 +98,10 @@ subroutine test_pointer() ! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P_DESC]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_pointerEp"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[P_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[P_DESC_CAST:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[P_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 @@ -111,19 +111,19 @@ subroutine test_pointer() ! CHECK: fir.dispatch "proc1"(%[[P_LOAD]] : !fir.class>>) ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DECL:.*]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DECL:.*]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[C1_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[C1_DESC_CAST:.*]] = fir.convert %[[C1_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C1_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> -! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[C2_DESC_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[C2_DESC_CAST:.*]] = fir.convert %[[C2_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C2_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 @@ -147,10 +147,10 @@ subroutine test_pointer() ! CHECK: fir.dispatch "proc2"(%[[C2_REBOX]] : !fir.class>) (%[[C2_REBOX]] : !fir.class>) {pass_arg_pos = 0 : i32} ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[C3_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: fir.call @_FortranAPointerSetBounds(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i32, i64, i64) -> () @@ -158,10 +158,10 @@ subroutine test_pointer() ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[C4_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[CORANK]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: fir.call @_FortranAPointerSetBounds(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i32, i64, i64) -> () @@ -261,59 +261,59 @@ subroutine test_allocatable() ! CHECK-DAG: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatableEp"} : (!fir.ref>>>) -> (!fir.ref>>>, !fir.ref>>>) ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[P_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[P_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C1_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C1_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> -! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C2_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#0 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C2_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C3_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () -! CHECK: %[[C10:.*]] = arith.constant 10 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 -! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[C1_I64:.*]] = fir.convert %c1{{.*}} : (index) -> i64 -! CHECK: %[[C10_I64:.*]] = fir.convert %[[C10]] : (i32) -> i64 +! CHECK-DAG: %[[C10:.*]] = arith.constant 10 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> +! CHECK-DAG: %[[C1_I64:.*]] = fir.convert %c1{{.*}} : (index) -> i64 +! CHECK-DAG: %[[C10_I64:.*]] = fir.convert %[[C10]] : (i32) -> i64 ! CHECK: fir.call @_FortranAAllocatableSetBounds(%[[C3_CAST]], %[[C0]], %[[C1_I64]], %[[C10_I64]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> () ! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 1 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P2_CAST:.*]] = fir.convert %[[TYPE_DESC_P2]] : (!fir.tdesc,c:i32}>>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C4_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> () -! CHECK: %[[CST1:.*]] = arith.constant 1 : index -! CHECK: %[[C20:.*]] = arith.constant 20 : i32 -! CHECK: %[[C0:.*]] = arith.constant 0 : i32 -! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[C1_I64:.*]] = fir.convert %[[CST1]] : (index) -> i64 -! CHECK: %[[C20_I64:.*]] = fir.convert %[[C20]] : (i32) -> i64 +! CHECK-DAG: %[[CST1:.*]] = arith.constant 1 : index +! CHECK-DAG: %[[C20:.*]] = arith.constant 20 : i32 +! CHECK-DAG: %[[C0:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> +! CHECK-DAG: %[[C1_I64:.*]] = fir.convert %[[CST1]] : (index) -> i64 +! CHECK-DAG: %[[C20_I64:.*]] = fir.convert %[[C20]] : (i32) -> i64 ! CHECK: fir.call @_FortranAAllocatableSetBounds(%[[C4_CAST]], %[[C0]], %[[C1_I64]], %[[C20_I64]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> () ! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#0 : (!fir.ref>>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 @@ -383,20 +383,20 @@ subroutine test_unlimited_polymorphic_with_intrinsic_type_spec() ! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEp"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) ! CHECK: %[[PTR:.*]] = fir.alloca !fir.class> {bindc_name = "ptr", uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEptr"} ! CHECK: %[[PTR_DECL:.*]]:2 = hlfir.declare %[[PTR]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_unlimited_polymorphic_with_intrinsic_type_specEptr"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>) -> !fir.ref> -! CHECK: %[[CAT:.*]] = arith.constant 0 : i32 -! CHECK: %[[KIND:.*]] = arith.constant 4 : i32 -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[BOX_NONE:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>) -> !fir.ref> +! CHECK-DAG: %[[CAT:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[KIND:.*]] = arith.constant 4 : i32 +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%[[BOX_NONE]], %[[CAT]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i32, i32, i32, i32) -> () ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P_DECL]]#0 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 -! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#0 : (!fir.ref>>) -> !fir.ref> -! CHECK: %[[CAT:.*]] = arith.constant 2 : i32 -! CHECK: %[[KIND:.*]] = arith.constant 4 : i32 -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#0 : (!fir.ref>>) -> !fir.ref> +! CHECK-DAG: %[[CAT:.*]] = arith.constant 2 : i32 +! CHECK-DAG: %[[KIND:.*]] = arith.constant 4 : i32 +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyIntrinsic(%[[BOX_NONE]], %[[CAT]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i32, i32, i32, i32) -> () ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#0 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 @@ -431,10 +431,10 @@ subroutine test_type_with_polymorphic_pointer_component() ! CHECK: %[[ZERO_DESC:.*]] = fir.embox %[[ZERO]] : (!fir.ptr>) -> !fir.class>> ! CHECK: fir.store %[[ZERO_DESC]] to %[[ELEMENT]] : !fir.ref>>> ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> -! CHECK: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT]] : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[TYPE_DESC_P1_CAST:.*]] = fir.convert %[[TYPE_DESC_P1]] : (!fir.tdesc>) -> !fir.ref +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyDerived(%[[ELEMENT_DESC_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, !fir.ref, i32, i32) -> () ! CHECK: %[[ELEMENT_DESC_CAST:.*]] = fir.convert %[[ELEMENT]] : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAPointerAllocate(%[[ELEMENT_DESC_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 @@ -566,11 +566,11 @@ subroutine test_allocatable_up_character() ! CHECK-LABEL: func.func @_QMpolyPtest_allocatable_up_character() { ! CHECK: %[[A:.*]] = fir.alloca !fir.class> {bindc_name = "a", uniq_name = "_QMpolyFtest_allocatable_up_characterEa"} ! CHECK: %[[A_DECL:.*]]:2 = hlfir.declare %[[A]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QMpolyFtest_allocatable_up_characterEa"} : (!fir.ref>>) -> (!fir.ref>>, !fir.ref>>) -! CHECK: %[[LEN:.*]] = arith.constant 10 : i64 -! CHECK: %[[A_NONE:.*]] = fir.convert %[[A_DECL]]#0 : (!fir.ref>>) -> !fir.ref> -! CHECK: %[[KIND:.*]] = arith.constant 1 : i32 -! CHECK: %[[RANK:.*]] = arith.constant 0 : i32 -! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[LEN:.*]] = arith.constant 10 : i64 +! CHECK-DAG: %[[A_NONE:.*]] = fir.convert %[[A_DECL]]#0 : (!fir.ref>>) -> !fir.ref> +! CHECK-DAG: %[[KIND:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[RANK:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitCharacterForAllocate(%[[A_NONE]], %[[LEN]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i64, i32, i32, i32) -> () ! CHECK: %[[A_NONE:.*]] = fir.convert %[[A_DECL]]#0 : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 diff --git a/flang/test/Lower/allocate-source-allocatables-2.f90 b/flang/test/Lower/allocate-source-allocatables-2.f90 index a4014cc5662d9..d7aa365d1a1bb 100644 --- a/flang/test/Lower/allocate-source-allocatables-2.f90 +++ b/flang/test/Lower/allocate-source-allocatables-2.f90 @@ -13,26 +13,26 @@ subroutine test() character(2), allocatable :: c_shorter character(:), allocatable :: c_deferred character(7), allocatable :: c_longer -! CHECK: %[[VAL_18:.*]] = arith.constant false +! CHECK-DAG: %[[VAL_18:.*]] = arith.constant false ! CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_17]]#0 : (!fir.ref>) -> !fir.box> -! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_14]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box +! CHECK-DAG: %[[VAL_23:.*]] = fir.convert %[[VAL_14]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_24:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box ! CHECK: %[[VAL_26:.*]] = fir.call @_FortranAAllocatableAllocateSource(%[[VAL_23]], %[[VAL_24]], %[[VAL_18]] -! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_16]] : (index) -> i64 -! CHECK: %[[VAL_29:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_30:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_31:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[VAL_27:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_28:.*]] = fir.convert %[[VAL_16]] : (index) -> i64 +! CHECK-DAG: %[[VAL_29:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[VAL_30:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[VAL_31:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitCharacterForAllocate(%[[VAL_27]], %[[VAL_28]], %[[VAL_29]], %[[VAL_30]], %[[VAL_31]] -! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box +! CHECK-DAG: %[[VAL_33:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_34:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box ! CHECK: %[[VAL_36:.*]] = fir.call @_FortranAAllocatableAllocateSource(%[[VAL_33]], %[[VAL_34]], %[[VAL_18]], ! CHECK-NOT: AllocatableInitCharacterForAllocate -! CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_9]]#0 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box +! CHECK-DAG: %[[VAL_37:.*]] = fir.convert %[[VAL_9]]#0 : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_38:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box ! CHECK: %[[VAL_40:.*]] = fir.call @_FortranAAllocatableAllocateSource(%[[VAL_37]], %[[VAL_38]], %[[VAL_18]], allocate(c_shorter, c_deferred, c_longer, source=c_source) diff --git a/flang/test/Lower/allocate-source-allocatables.f90 b/flang/test/Lower/allocate-source-allocatables.f90 index 29b00b79a69d4..2143d2c61cda1 100644 --- a/flang/test/Lower/allocate-source-allocatables.f90 +++ b/flang/test/Lower/allocate-source-allocatables.f90 @@ -306,14 +306,14 @@ subroutine test_allocatable_chararray(n, a) ! CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_13]] typeparams %[[VAL_12]] : (!fir.heap>, index) -> !fir.box>> ! CHECK: fir.store %[[VAL_14]] to %[[VAL_3]] : !fir.ref>>> ! CHECK: %[[VAL_15:.*]] = fir.box_elesize %[[VAL_11]] : (!fir.box>) -> index -! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i64 -! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_19:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_20:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[VAL_16:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i64 +! CHECK-DAG: %[[VAL_18:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[VAL_19:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[VAL_20:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitCharacterForAllocate(%[[VAL_16]], %[[VAL_17]], %[[VAL_18]], %[[VAL_19]], %[[VAL_20]]) {{.*}}: (!fir.ref>, i64, i32, i32, i32) -> () -! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_11]] : (!fir.box>) -> !fir.box +! CHECK-DAG: %[[VAL_22:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_23:.*]] = fir.convert %[[VAL_11]] : (!fir.box>) -> !fir.box ! CHECK: %[[VAL_25:.*]] = fir.call @_FortranAAllocatableAllocateSource(%[[VAL_22]], %[[VAL_23]], %[[VAL_7]], %[[VAL_8]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 subroutine test_allocatable_char(n, a) diff --git a/flang/test/Lower/allocate-source-pointers.f90 b/flang/test/Lower/allocate-source-pointers.f90 index e6359dba81eb4..7e6ef0c049c06 100644 --- a/flang/test/Lower/allocate-source-pointers.f90 +++ b/flang/test/Lower/allocate-source-pointers.f90 @@ -285,11 +285,11 @@ subroutine test_pointer_chararray(n, a) ! CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_12]] typeparams %[[VAL_13]] : (!fir.ptr>, index) -> !fir.box>> ! CHECK: fir.store %[[VAL_14]] to %[[VAL_3]] : !fir.ref>>> ! CHECK: %[[VAL_15:.*]] = fir.box_elesize %[[VAL_11]] : (!fir.box>) -> index -! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i64 -! CHECK: %[[VAL_18:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_19:.*]] = arith.constant 0 : i32 -! CHECK: %[[VAL_20:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[VAL_16:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> +! CHECK-DAG: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i64 +! CHECK-DAG: %[[VAL_18:.*]] = arith.constant 1 : i32 +! CHECK-DAG: %[[VAL_19:.*]] = arith.constant 0 : i32 +! CHECK-DAG: %[[VAL_20:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAPointerNullifyCharacter(%[[VAL_16]], %[[VAL_17]], %[[VAL_18]], %[[VAL_19]], %[[VAL_20]]) {{.*}}: (!fir.ref>, i64, i32, i32, i32) -> () ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_11]] : (!fir.box>) -> !fir.box diff --git a/flang/test/Lower/volatile-allocatable.f90 b/flang/test/Lower/volatile-allocatable.f90 new file mode 100644 index 0000000000000..5f75a5425422a --- /dev/null +++ b/flang/test/Lower/volatile-allocatable.f90 @@ -0,0 +1,193 @@ +! RUN: bbc %s -o - --strict-fir-volatile-verifier | FileCheck %s + +! Check that class types, derived types, and polymorphic types can be volatile. +! Check their interaction with allocatable, pointer, and assumed-shape allocatable +! results in values with correctly designated or declared types. + +module derived_types + type :: base_type + integer :: i = 42 + end type + + type, extends(base_type) :: ext_type + integer :: j = 100 + end type + + type :: comp_type + character(10) :: str = "test" + integer :: arr(2) = [1, 2] + end type +end module + +subroutine test_scalar_volatile() + use derived_types + class(base_type), allocatable, volatile :: v1 + type(ext_type), allocatable, volatile :: v2 + type(comp_type), allocatable, volatile :: v3 + character(len=:), allocatable, volatile :: c1 + + ! Allocation without source + allocate(v1) + + ! Allocate polymorphic derived type with dynamic type + allocate(ext_type :: v1) + select type (v1) + type is (ext_type) + v1%j = 2 + end select + + ! Allocation with source + allocate(v2, source=ext_type()) + + ! Deferred-length characters + allocate(character(20) :: c1) + c1 = "volatile character" + + ! Allocation with components + allocate(v3) + deallocate(v1, v2, v3, c1) +end subroutine + +! Test with both volatile and asynchronous attributes +subroutine test_volatile_asynchronous() + use derived_types + class(base_type), allocatable, volatile, asynchronous :: v1(:) + integer, allocatable, volatile, asynchronous :: i1(:) + + allocate(v1(4)) + allocate(i1(4), source=[1, 2, 3, 4]) + + deallocate(v1, i1) +end subroutine + +subroutine test_select_base_type_volatile() + use derived_types + class(base_type), allocatable, volatile :: v(:) + + allocate(v(2)) + + select type(v) + class is (base_type) + v(1)%i = 100 + end select + + deallocate(v) +end subroutine + +! Test allocate with mold +subroutine test_mold_allocation() + use derived_types + type(comp_type) :: template + type(comp_type), allocatable, volatile :: v(:) + + template%str = "mold test" + template%arr = [5, 6] + + allocate(v(3), mold=template) + + deallocate(v) +end subroutine + +! Test unlimited polymorphic allocation +subroutine test_unlimited_polymorphic() + use derived_types + class(*), allocatable, volatile :: up + class(*), allocatable, volatile :: upa(:) + + ! Scalar allocation + allocate(integer :: up) + select type(up) + type is (integer) + up = 123 + end select + + ! Array allocation with source + allocate(character(10) :: up) + select type(up) + type is (character(*)) + up = "class(*)" + end select + + ! Array allocation + allocate(real :: upa(3)) + select type(upa) + type is (real) + upa = [1.1, 2.2, 3.3] + end select + + deallocate(up, upa) +end subroutine + +! CHECK-LABEL: func.func @_QPtest_scalar_volatile() { +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_scalar_volatileEc1"} : (!fir.ref>>, volatile>) -> (!fir.ref>>, volatile>, !fir.ref>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_scalar_volatileEv1"} : (!fir.ref>>, volatile>) -> (!fir.ref>>, volatile>, !fir.ref>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_scalar_volatileEv2"} : (!fir.ref>>, volatile>) -> (!fir.ref>>, volatile>, !fir.ref>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_scalar_volatileEv3"} : (!fir.ref>>, volatile>) -> (!fir.ref>>, volatile>, !fir.ref>>, volatile>) +! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_scalar_volatileEv1"} : (!fir.box>, volatile>) -> (!fir.box>, volatile>, !fir.box>, volatile>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"j"} : (!fir.box>, volatile>) -> !fir.ref +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QQro._QMderived_typesText_type.0"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocateSource(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QQclX766F6C6174696C6520636861726163746572"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK-LABEL: func.func @_QPtest_volatile_asynchronous() { +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_volatile_asynchronousEi1"} : (!fir.ref>>, volatile>) -> (!fir.ref>>, volatile>, !fir.ref>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_volatile_asynchronousEv1"} : (!fir.ref>>>, volatile>) -> (!fir.ref>>>, volatile>, !fir.ref>>>, volatile>) +! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () +! CHECK: fir.call @_FortranAAllocatableSetBounds(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i64, i64) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QQro.4xi4.1"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: fir.call @_FortranAAllocatableSetBounds(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i64, i64) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocateSource(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.box, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK-LABEL: func.func @_QPtest_select_base_type_volatile() { +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_select_base_type_volatileEv"} : (!fir.ref>>>, volatile>) -> (!fir.ref>>>, volatile>, !fir.ref>>>, volatile>) +! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i32, i32) -> () +! CHECK: fir.call @_FortranAAllocatableSetBounds(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i64, i64) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_select_base_type_volatileEv"} : (!fir.class>>, volatile>, !fir.shift<1>) -> (!fir.class>>, volatile>, !fir.class>>, volatile>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0 (%{{.+}}) : (!fir.class>>, volatile>, index) -> !fir.class, volatile> +! CHECK: %{{.+}} = hlfir.designate %{{.+}}{"i"} : (!fir.class, volatile>) -> !fir.ref +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK-LABEL: func.func @_QPtest_mold_allocation() { +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {uniq_name = "_QFtest_mold_allocationEtemplate"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_mold_allocationEv"} : (!fir.ref>>>, volatile>) -> (!fir.ref>>>, volatile>, !fir.ref>>>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QQclX6D6F6C642074657374"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"str"} typeparams %{{.+}} : (!fir.ref>, index) -> !fir.ref> +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QQro.2xi4.2"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = hlfir.designate %{{.+}}#0{"arr"} shape %{{.+}} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> +! CHECK: fir.call @_FortranAAllocatableApplyMold(%{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.box, i32) -> () +! CHECK: fir.call @_FortranAAllocatableSetBounds(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i64, i64) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK-LABEL: func.func @_QPtest_unlimited_polymorphic() { +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.ref>, volatile>) -> (!fir.ref>, volatile>, !fir.ref>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_unlimited_polymorphicEupa"} : (!fir.ref>>, volatile>) -> (!fir.ref>>, volatile>, !fir.ref>>, volatile>) +! CHECK: fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i32, i32, i32) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.heap) -> (!fir.heap, !fir.heap) +! CHECK: fir.call @_FortranAAllocatableInitCharacterForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i32, i32, i32) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_unlimited_polymorphicEup"} : (!fir.heap>, index) -> (!fir.boxchar<1>, !fir.heap>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}} typeparams %{{.+}} {fortran_attrs = #fir.var_attrs, uniq_name = "_QQclX636C617373282A29"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +! CHECK: fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i32, i32, i32) -> () +! CHECK: fir.call @_FortranAAllocatableSetBounds(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i32, i64, i64) -> () +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableAllocate(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_unlimited_polymorphicEupa"} : (!fir.box>, volatile>, !fir.shift<1>) -> (!fir.box>, volatile>, !fir.box>, volatile>) +! CHECK: %{{.+}}:2 = hlfir.declare %{{.+}}(%{{.+}}) {fortran_attrs = #fir.var_attrs, uniq_name = "_QQro.3xr4.3"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.+}} = fir.call @_FortranAAllocatableDeallocatePolymorphic(%{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}, %{{.+}}) fastmath : (!fir.ref>, !fir.ref, i1, !fir.box, !fir.ref, i32) -> i32