[flang-commits] [flang] de35293 - [flang][lowering] Implement component-wise initialization for derived types (#187465)
via flang-commits
flang-commits at lists.llvm.org
Mon Jun 1 05:47:21 PDT 2026
Author: hcx
Date: 2026-06-01T14:47:16+02:00
New Revision: de3529386e1e773f0186755b83bbc12e7884f863
URL: https://github.com/llvm/llvm-project/commit/de3529386e1e773f0186755b83bbc12e7884f863
DIFF: https://github.com/llvm/llvm-project/commit/de3529386e1e773f0186755b83bbc12e7884f863.diff
LOG: [flang][lowering] Implement component-wise initialization for derived types (#187465)
Currently, the compiler defaults to a full `memcpy` when initializing
derived types.
This patch introduces component-wise initialization for pointer /
allocatable components, avoiding unnecessary initialization data
generation and redundant copies.
Ineligible cases continue to use the existing `memcpy` initialization
path.
RFC: https://discourse.llvm.org/t/rfc-automatic-static-promotion-of-large-local-variables-in-flang/89539
Key changes:
- In `flang/lib/Lower/ConvertVariable.cpp`:
- Add `genDerivedTypeComponentInit` for component-wise derived type
initialization.
- Add `isEligibleForComponentWiseInit` to guard the new initialization
path.
- Add `genInlinedInitWithMemcpy` to factor out the existing full
`memcpy` initialization logic.
- Update `defaultInitializeAtRuntime` to select the appropriate
initialization path.
- Add and update regression tests.
---------
Co-authored-by: ict-ql <168183727+ict-ql at users.noreply.github.com>
Co-authored-by: buggfg <wangyingying at bosc.ac.cn>
Added:
flang/test/Lower/component-wise-init.f90
Modified:
flang/lib/Lower/ConvertVariable.cpp
flang/test/Lower/HLFIR/structure-constructor.f90
flang/test/Lower/OpenMP/private-derived-type.f90
flang/test/Lower/call-copy-in-out.f90
flang/test/Lower/default-initialization.f90
flang/test/Lower/derived-type-finalization.f90
flang/test/Lower/derived-type-temp.f90
flang/test/Lower/forall/forall-allocatable-2.f90
flang/test/Lower/pointer-default-init.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index f972ce8c3a0c3..0cbc80cc94285 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -37,6 +37,7 @@
#include "flang/Optimizer/Dialect/FIRAttr.h"
#include "flang/Optimizer/Dialect/FIRDialect.h"
#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/MIF/MIFOps.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
@@ -46,7 +47,9 @@
#include "flang/Runtime/allocator-registry-consts.h"
#include "flang/Semantics/runtime-type-info.h"
#include "flang/Semantics/tools.h"
+#include "flang/Semantics/type.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include <optional>
@@ -830,6 +833,164 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
return Fortran::lower::hasDefaultInitialization(sym);
}
+/// Performs component-wise initialization for \p derivedSpec,
+/// selectively generating IR only for components that require it.
+static void genDerivedTypeComponentInit(
+ Fortran::lower::AbstractConverter &converter, mlir::Location loc,
+ const Fortran::semantics::DerivedTypeSpec &derivedSpec,
+ mlir::Value baseAddr, fir::RecordType recTy) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ // Flattened DFS traversal to visit only the leaf components.
+ Fortran::semantics::UltimateComponentIterator ultimateIter{derivedSpec};
+ for (auto it = ultimateIter.begin(); it != ultimateIter.end(); ++it) {
+ const Fortran::semantics::Symbol &comp = *it;
+ const auto *objDetails =
+ comp.detailsIf<Fortran::semantics::ObjectEntityDetails>();
+ const auto *procDetails =
+ comp.detailsIf<Fortran::semantics::ProcEntityDetails>();
+ if ((!objDetails && !procDetails) ||
+ !Fortran::semantics::IsAllocatableOrPointer(comp))
+ continue;
+ // Retrieve the nested symbol path from the root type to this ultimate
+ // component.
+ auto path = it.GetComponentPath();
+ mlir::Value currentAddr = baseAddr;
+ fir::RecordType currentRecTy = recTy;
+ // Traverse the path and calculate memory coordinates.
+ for (const Fortran::semantics::Symbol &pathSym : path) {
+ const Fortran::semantics::Symbol *symPtr = &pathSym;
+ // Generate coordinate for this nesting level.
+ std::string name = converter.getRecordTypeFieldName(*symPtr);
+ mlir::Type compFirTy = currentRecTy.getType(name);
+ assert(compFirTy && "Component field type not found in RecordType");
+ auto fieldIdx = fir::FieldIndexOp::create(
+ builder, loc, fir::FieldType::get(currentRecTy.getContext()), name,
+ currentRecTy, mlir::ValueRange{});
+ currentAddr =
+ fir::CoordinateOp::create(builder, loc, builder.getRefType(compFirTy),
+ currentAddr, mlir::ValueRange{fieldIdx});
+ currentRecTy = mlir::dyn_cast<fir::RecordType>(compFirTy);
+ }
+ mlir::Type finalCompFirTy = fir::unwrapPassByRefType(currentAddr.getType());
+ mlir::Value initVal;
+ if (objDetails) {
+ initVal = fir::factory::createUnallocatedBox(builder, loc, finalCompFirTy,
+ mlir::ValueRange{});
+ } else {
+ initVal = fir::factory::createNullBoxProc(builder, loc, finalCompFirTy);
+ }
+ fir::StoreOp::create(builder, loc, initVal, currentAddr);
+ }
+}
+
+/// Initializes a derived type via a bulk memory copy (memcpy).
+/// This method generates a global constant containing the default
+/// initialized state of the type, and copies it directly into the
+/// target memory location.
+static void
+genInlinedInitWithMemcpy(Fortran::lower::AbstractConverter &converter,
+ const Fortran::semantics::Symbol &sym,
+ mlir::Type symTy, const fir::ExtendedValue &exv,
+ const Fortran::semantics::ObjectEntityDetails *details,
+ const Fortran::semantics::DeclTypeSpec *declTy) {
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ mlir::Location symLoc = genLocation(converter, sym);
+ std::string globalName = fir::NameUniquer::doGenerated(
+ (converter.mangleName(*declTy->AsDerived()) + fir::kNameSeparator +
+ fir::kDerivedTypeInitSuffix)
+ .str());
+ mlir::StringAttr linkage = builder.createInternalLinkage();
+ fir::GlobalOp global = builder.getNamedGlobal(globalName);
+ if (!global && details->init()) {
+ global = builder.createGlobal(symLoc, symTy, globalName, linkage,
+ mlir::Attribute{},
+ /*isConst=*/true,
+ /*isTarget=*/false,
+ /*dataAttr=*/{});
+ createGlobalInitialization(
+ builder, global, [&](fir::FirOpBuilder &builder) {
+ Fortran::lower::StatementContext stmtCtx(
+ /*cleanupProhibited=*/true);
+ fir::ExtendedValue initVal = genInitializerExprValue(
+ converter, symLoc, details->init().value(), stmtCtx);
+ mlir::Value castTo =
+ builder.createConvert(symLoc, symTy, fir::getBase(initVal));
+ fir::HasValueOp::create(builder, symLoc, castTo);
+ });
+ } else if (!global) {
+ global = builder.createGlobal(symLoc, symTy, globalName, linkage,
+ mlir::Attribute{},
+ /*isConst=*/true,
+ /*isTarget=*/false,
+ /*dataAttr=*/{});
+ createGlobalInitialization(
+ builder, global, [&](fir::FirOpBuilder &builder) {
+ Fortran::lower::StatementContext stmtCtx(
+ /*cleanupProhibited=*/true);
+ mlir::Value initVal = genDefaultInitializerValue(converter, symLoc,
+ sym, symTy, stmtCtx);
+ mlir::Value castTo = builder.createConvert(symLoc, symTy, initVal);
+ fir::HasValueOp::create(builder, symLoc, castTo);
+ });
+ }
+ auto addrOf = fir::AddrOfOp::create(builder, symLoc, global.resultType(),
+ global.getSymbol());
+ fir::CopyOp::create(builder, symLoc, addrOf, fir::getBase(exv),
+ /*noOverlap=*/true);
+}
+
+/// Checks if a derived type is eligible for component-wise initialization.
+/// This is preferred over a bulk memcpy when the type contains at least
+/// one pointer/allocatable component, but no components with default
+/// initializers.
+static bool isEligibleForComponentWiseInit(
+ const Fortran::semantics::DerivedTypeSpec &derivedSpec) {
+ bool hasPtrOrAlloc = false;
+ // Worklist for iterative traversal of the derived type tree.
+ llvm::SmallVector<const Fortran::semantics::DerivedTypeSpec *> worklist;
+ worklist.push_back(&derivedSpec);
+ while (!worklist.empty()) {
+ const Fortran::semantics::DerivedTypeSpec *currentSpec =
+ worklist.pop_back_val();
+ const Fortran::semantics::Scope *scope = currentSpec->scope();
+ assert(scope && "derived type has no scope");
+ const auto &typeDetails =
+ currentSpec->typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
+ for (const auto &compName : typeDetails.componentNames()) {
+ auto scopeIter = scope->find(compName);
+ assert(scopeIter != scope->cend() &&
+ "component name must exist in its scope");
+ const Fortran::semantics::Symbol &comp = scopeIter->second.get();
+ // Return false if any component has a default initializer.
+ const auto *objDetails =
+ comp.detailsIf<Fortran::semantics::ObjectEntityDetails>();
+ const auto *procDetails =
+ comp.detailsIf<Fortran::semantics::ProcEntityDetails>();
+ if ((objDetails && objDetails->init()) ||
+ (procDetails && procDetails->init()))
+ return false;
+ if (Fortran::semantics::IsAllocatableOrPointer(comp)) {
+ hasPtrOrAlloc = true;
+ continue;
+ }
+ // Traverse nested derived types.
+ if (const Fortran::semantics::DeclTypeSpec *declTy = comp.GetType()) {
+ if (const Fortran::semantics::DerivedTypeSpec *nestedSpec =
+ declTy->AsDerived()) {
+ if (Fortran::lower::hasDefaultInitialization(comp)) {
+ // Return false for arrays of derived types requiring
+ // initialization.
+ if (comp.Rank() > 0)
+ return false;
+ worklist.push_back(nestedSpec);
+ }
+ }
+ }
+ }
+ }
+ return hasPtrOrAlloc;
+}
+
/// Call default initialization runtime routine to initialize \p var.
void Fortran::lower::defaultInitializeAtRuntime(
Fortran::lower::AbstractConverter &converter,
@@ -857,56 +1018,27 @@ void Fortran::lower::defaultInitializeAtRuntime(
mlir::Type symTy = converter.genType(sym);
const auto *details =
sym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
- if (details && !Fortran::semantics::IsPolymorphic(sym) &&
+ bool isDerivedTypeScalar =
+ details && !Fortran::semantics::IsPolymorphic(sym) &&
declTy->category() ==
Fortran::semantics::DeclTypeSpec::Category::TypeDerived &&
!mlir::isa<fir::SequenceType>(symTy) &&
!sym.test(Fortran::semantics::Symbol::Flag::OmpPrivate) &&
!sym.test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate) &&
- !Fortran::semantics::HasCUDAComponent(sym)) {
- std::string globalName = fir::NameUniquer::doGenerated(
- (converter.mangleName(*declTy->AsDerived()) + fir::kNameSeparator +
- fir::kDerivedTypeInitSuffix)
- .str());
- mlir::Location loc = genLocation(converter, sym);
- mlir::StringAttr linkage = builder.createInternalLinkage();
- fir::GlobalOp global = builder.getNamedGlobal(globalName);
- if (!global && details->init()) {
- global = builder.createGlobal(loc, symTy, globalName, linkage,
- mlir::Attribute{},
- /*isConst=*/true,
- /*isTarget=*/false,
- /*dataAttr=*/{});
- createGlobalInitialization(
- builder, global, [&](fir::FirOpBuilder &builder) {
- Fortran::lower::StatementContext stmtCtx(
- /*cleanupProhibited=*/true);
- fir::ExtendedValue initVal = genInitializerExprValue(
- converter, loc, details->init().value(), stmtCtx);
- mlir::Value castTo =
- builder.createConvert(loc, symTy, fir::getBase(initVal));
- fir::HasValueOp::create(builder, loc, castTo);
- });
- } else if (!global) {
- global = builder.createGlobal(loc, symTy, globalName, linkage,
- mlir::Attribute{},
- /*isConst=*/true,
- /*isTarget=*/false,
- /*dataAttr=*/{});
- createGlobalInitialization(
- builder, global, [&](fir::FirOpBuilder &builder) {
- Fortran::lower::StatementContext stmtCtx(
- /*cleanupProhibited=*/true);
- mlir::Value initVal = genDefaultInitializerValue(
- converter, loc, sym, symTy, stmtCtx);
- mlir::Value castTo = builder.createConvert(loc, symTy, initVal);
- fir::HasValueOp::create(builder, loc, castTo);
- });
+ !Fortran::semantics::HasCUDAComponent(sym);
+ if (isDerivedTypeScalar) {
+ const auto &derivedSpec = *declTy->AsDerived();
+ if (isEligibleForComponentWiseInit(derivedSpec)) {
+ // Component-wise initialization.
+ mlir::Value baseAddr = fir::getBase(exv);
+ auto recTy = mlir::cast<fir::RecordType>(
+ fir::unwrapPassByRefType(baseAddr.getType()));
+ genDerivedTypeComponentInit(converter, loc, derivedSpec, baseAddr,
+ recTy);
+ } else {
+ // Initialize via bulk memory copy from a global constant.
+ genInlinedInitWithMemcpy(converter, sym, symTy, exv, details, declTy);
}
- auto addrOf = fir::AddrOfOp::create(builder, loc, global.resultType(),
- global.getSymbol());
- fir::CopyOp::create(builder, loc, addrOf, fir::getBase(exv),
- /*noOverlap=*/true);
} else {
mlir::Value box = builder.createBox(loc, exv);
fir::runtime::genDerivedTypeInitialize(builder, loc, box);
diff --git a/flang/test/Lower/HLFIR/structure-constructor.f90 b/flang/test/Lower/HLFIR/structure-constructor.f90
index 094aeaa14f682..f2d2c094198b3 100644
--- a/flang/test/Lower/HLFIR/structure-constructor.f90
+++ b/flang/test/Lower/HLFIR/structure-constructor.f90
@@ -98,8 +98,12 @@ end subroutine test3
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}> {bindc_name = "res", uniq_name = "_QFtest3Eres"}
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest3Eres"} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt3.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_3]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
+! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_3]]#0, r : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xf32>>
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest3Ex"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>)
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>)
! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
@@ -130,8 +134,12 @@ end subroutine test4
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}> {bindc_name = "res", uniq_name = "_QFtest4Eres"}
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest4Eres"} : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt4.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_3]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
+! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_3]]#0, c : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.char<1,2>>>
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.heap<!fir.array<?x!fir.char<1,2>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
! CHECK: %[[VAL_10:.*]] = arith.constant 2 : index
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_10]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest4Ex"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>, index, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>)
! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, !fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>)
@@ -170,8 +178,12 @@ end subroutine test5
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>
! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}> {bindc_name = "res", uniq_name = "_QFtest5Eres"}
! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest5Eres"} : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt5.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_3]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
+! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_3]]#0, t5m : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
+! CHECK: %[[VAL_5:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>
+! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_8:.*]] = fir.embox %[[VAL_5]](%[[VAL_7]]) : (!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>
+! CHECK: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest5Ex"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>)
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>, !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>)
! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.box<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
@@ -217,8 +229,13 @@ end subroutine test6
! CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]] typeparams %[[VAL_9]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest6Ec"} : (!fir.ref<!fir.char<1,4>>, index, !fir.dscope) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
! CHECK: %[[VAL_11:.*]] = fir.alloca !fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}> {bindc_name = "res", uniq_name = "_QFtest6Eres"}
! CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_11]] {uniq_name = "_QFtest6Eres"} : (!fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt6.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_12]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>
+! CHECK: %[[VAL_13:.*]] = fir.coordinate_of %[[VAL_12]]#0, t5 : (!fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> !fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>
+! CHECK: %[[VAL_14:.*]] = fir.coordinate_of %[[VAL_13]], t5m : (!fir.ref<!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
+! CHECK: %[[VAL_15:.*]] = fir.zero_bits !fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>
+! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_16]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_18:.*]] = fir.embox %[[VAL_15]](%[[VAL_17]]) : (!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>
+! CHECK: fir.store %[[VAL_18]] to %[[VAL_14]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>
! CHECK: %[[VAL_19:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtest6Ex"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>>)
! CHECK: %[[VAL_20:.*]]:2 = hlfir.declare %[[VAL_6]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>, !fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>)
! CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]]#0 : (!fir.ref<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>) -> !fir.box<!fir.type<_QMtypesTt6{t5:!fir.type<_QMtypesTt5{t5m:!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>}>,t6m:!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>}>>
@@ -302,8 +319,12 @@ end subroutine test7
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest7En"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}> {bindc_name = "x", uniq_name = "_QFtest7Ex"}
! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]] {uniq_name = "_QFtest7Ex"} : (!fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt7.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_4]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+! CHECK: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_4]]#0, c2 : (!fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK: %[[VAL_6:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+! CHECK: %[[VAL_7:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_9:.*]] = fir.embox %[[VAL_6]](%[[VAL_8]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: fir.store %[[VAL_9]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>)
! CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
! CHECK: %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -315,6 +336,8 @@ end subroutine test7
! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<i32>
! CHECK: hlfir.assign %[[VAL_19]] to %[[VAL_18]] temporary_lhs : i32, !fir.ref<i32>
! CHECK: hlfir.assign %[[VAL_11]]#0 to %[[VAL_4]]#0 : !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranADestroyWithoutFinalization(%[[VAL_20]])
! CHECK: return
! CHECK: }
@@ -330,8 +353,10 @@ end subroutine test8
! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}> {bindc_name = "res", uniq_name = "_QFtest8Eres"}
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest8Eres"} : (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt8.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_2]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_2]]#0, c : (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
+! CHECK: %[[VAL_4:.*]] = fir.zero_bits !fir.heap<!fir.char<1,11>>
+! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_4]] : (!fir.heap<!fir.char<1,11>>) -> !fir.box<!fir.heap<!fir.char<1,11>>>
+! CHECK: fir.store %[[VAL_5]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
! CHECK: %[[VAL_9:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,12>>> {bindc_name = "x", uniq_name = "_QFtest8Ex"}
! CHECK: %[[VAL_10:.*]] = arith.constant 12 : index
! CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap<!fir.char<1,12>>
@@ -375,8 +400,10 @@ end subroutine test9
! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>
! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}> {bindc_name = "res", uniq_name = "_QFtest9Eres"}
! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest9Eres"} : (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>)
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtypesTt8.DerivedInit) : !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_2]]#0 no_overlap : !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>, !fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>
+! CHECK: %[[VAL_3:.*]] = fir.coordinate_of %[[VAL_2]]#0, c : (!fir.ref<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
+! CHECK: %[[VAL_4:.*]] = fir.zero_bits !fir.heap<!fir.char<1,11>>
+! CHECK: %[[VAL_5:.*]] = fir.embox %[[VAL_4]] : (!fir.heap<!fir.char<1,11>>) -> !fir.box<!fir.heap<!fir.char<1,11>>>
+! CHECK: fir.store %[[VAL_5]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
! CHECK: %[[VAL_9:.*]] = arith.constant 12 : index
! CHECK: %[[VAL_10:.*]] = fir.alloca !fir.char<1,12> {bindc_name = "x", uniq_name = "_QFtest9Ex"}
! CHECK: %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_10]] typeparams %[[VAL_9]] {uniq_name = "_QFtest9Ex"} : (!fir.ref<!fir.char<1,12>>, index) -> (!fir.ref<!fir.char<1,12>>, !fir.ref<!fir.char<1,12>>)
diff --git a/flang/test/Lower/OpenMP/private-derived-type.f90 b/flang/test/Lower/OpenMP/private-derived-type.f90
index 3947a0d68b58c..c286ea29c62aa 100644
--- a/flang/test/Lower/OpenMP/private-derived-type.f90
+++ b/flang/test/Lower/OpenMP/private-derived-type.f90
@@ -29,8 +29,10 @@ end subroutine s4
! Example of how the lowering for regular derived type variables:
! CHECK: %[[VAL_DERIVED_ALLOCA:.*]] = fir.alloca !fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}> {bindc_name = "v", uniq_name = "_QFs4Ev"}
! CHECK: %[[VAL_DERIVED_DECLARE:.*]]:2 = hlfir.declare %[[VAL_DERIVED_ALLOCA]] {{.*}}
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QFs4Ty3.DerivedInit) : !fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[VAL_DERIVED_DECLARE]]#0 no_overlap : {{.*}}
+! CHECK: %[[VAL_COORD:.*]] = fir.coordinate_of %[[VAL_DERIVED_DECLARE]]#0, x : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[VAL_ZERO:.*]] = fir.zero_bits !fir.heap<i32>
+! CHECK: %[[VAL_EMBOX:.*]] = fir.embox %[[VAL_ZERO]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+! CHECK: fir.store %[[VAL_EMBOX]] to %[[VAL_COORD]] : !fir.ref<!fir.box<!fir.heap<i32>>>
! CHECK: omp.parallel {
! CHECK: omp.wsloop private(@[[DERIVED_PRIV]] %{{.*}}#0 -> %{{.*}}, @{{.*}} %{{.*}}#0 -> %{{.*}} : !fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>, !fir.ref<i32>) {
! CHECK: }
diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90
index 5d754d8a9ac28..15feb390171bf 100644
--- a/flang/test/Lower/call-copy-in-out.f90
+++ b/flang/test/Lower/call-copy-in-out.f90
@@ -80,7 +80,7 @@ subroutine bar_intent_in(x)
! CHECK: hlfir.copy_in
! CHECK: fir.call @_QPbar_intent_in
! CHECK: hlfir.copy_out
-! CHECK-SAME: ) -> ()
+! CHECK-SAME: %{{.*}}, %{{.*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1) -> ()
call bar_intent_in(x)
end subroutine
diff --git a/flang/test/Lower/component-wise-init.f90 b/flang/test/Lower/component-wise-init.f90
new file mode 100644
index 0000000000000..413c7144f5043
--- /dev/null
+++ b/flang/test/Lower/component-wise-init.f90
@@ -0,0 +1,152 @@
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
+
+! Test for component-wise initialization of derived types to avoid
+! generating large, fully-initialized global templates.
+
+module my_types
+ ! Clean internal type: contains only allocatable and pointer components,
+ ! without any default initialization.
+ type :: InnerClean
+ real, pointer :: p
+ real, allocatable :: arr(:)
+ end type InnerClean
+
+ ! ============================================================================
+ ! Test Case 1: Type meeting all criteria for component-wise init (Target)
+ ! No arrays of derived types, no default initialization.
+ ! ============================================================================
+ type :: TargetType
+ real, pointer :: q
+ real(8) :: uninit_buffer(80, 100)
+ type(InnerClean) :: nested_scalar
+ end type TargetType
+
+ ! ============================================================================
+ ! Test Case 2: Type triggering fallback A (contains an array of derived type)
+ ! ============================================================================
+ type :: FallbackArrayType
+ type(InnerClean) :: nested_arr(10)
+ end type FallbackArrayType
+
+ ! ============================================================================
+ ! Test Case 3: Type triggering fallback B (contains default initialization)
+ ! ============================================================================
+ type :: FallbackDefaultInitType
+ real, pointer :: p
+ integer :: flag = 999
+ end type FallbackDefaultInitType
+
+ ! ============================================================================
+ ! Test Case 4: Type triggering fallback C (contains default initialization)
+ ! ============================================================================
+ type :: ProcPointerType
+ real, pointer :: p
+ procedure(), pointer, nopass :: pp => null()
+ end type ProcPointerType
+
+ ! ============================================================================
+ ! Test Case 5: Type with uninitialized procedure pointer.
+ ! ============================================================================
+ type :: ProcPointerNoInitType
+ real, pointer :: p
+ procedure(), pointer, nopass :: pp
+ end type ProcPointerNoInitType
+end module my_types
+
+
+! ------------------------------------------------------------------------------
+! Test 1: FIR generation for component-wise initialization
+! ------------------------------------------------------------------------------
+subroutine test_target()
+ use my_types
+ type(TargetType) :: my_var
+ call do_something_target(my_var)
+end subroutine test_target
+
+! CHECK-LABEL: func.func @_QPtest_target()
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTtargettype{{.*}}>
+! CHECK: %[[MY_VAR:.*]] = fir.declare %[[ALLOCA]]
+! CHECK: %[[Q_ADDR:.*]] = fir.coordinate_of %[[MY_VAR]], q
+! CHECK: fir.store %{{.*}} to %[[Q_ADDR]]
+! CHECK: %[[NESTED_ADDR:.*]] = fir.coordinate_of %[[MY_VAR]], nested_scalar
+! CHECK: %[[P_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], p
+! CHECK: fir.store %{{.*}} to %[[P_ADDR]]
+! CHECK: %[[ARR_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], arr
+! CHECK: fir.store %{{.*}} to %[[ARR_ADDR]]
+! CHECK-NOT: fir.call @_FortranAInitialize
+! CHECK-NOT: fir.global internal @_QQ_QMmy_typesTtargettype.DerivedInit
+
+
+! ------------------------------------------------------------------------------
+! Test 2: Fallback mechanism for arrays of derived types
+! ------------------------------------------------------------------------------
+subroutine test_fallback_array()
+ use my_types
+ type(FallbackArrayType) :: var_array
+ call do_something_array(var_array)
+end subroutine test_fallback_array
+
+! CHECK-LABEL: func.func @_QPtest_fallback_array()
+! CHECK: %[[ALLOCA_ARR:.*]] = fir.alloca !fir.type<_QMmy_typesTfallbackarraytype{{.*}}>
+! CHECK: %[[VAR_ARRAY:.*]] = fir.declare %[[ALLOCA_ARR]]
+! CHECK: %[[GLOBAL_INIT_ARR:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackarraytype.DerivedInit)
+! CHECK: fir.copy %[[GLOBAL_INIT_ARR]] to %[[VAR_ARRAY]]
+
+
+! ------------------------------------------------------------------------------
+! Test 3: Fallback mechanism for default initialization
+! ------------------------------------------------------------------------------
+subroutine test_fallback_default_init()
+ use my_types
+ type(FallbackDefaultInitType) :: var_default_init
+ call do_something_default_init(var_default_init)
+end subroutine test_fallback_default_init
+
+! CHECK-LABEL: func.func @_QPtest_fallback_default_init()
+! CHECK: %[[ALLOCA_DEFAULT:.*]] = fir.alloca !fir.type<_QMmy_typesTfallbackdefaultinittype{{.*}}>
+! CHECK: %[[VAR_DEFAULT:.*]] = fir.declare %[[ALLOCA_DEFAULT]]
+! CHECK: %[[GLOBAL_INIT_DEFAULT:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackdefaultinittype.DerivedInit)
+! CHECK: fir.copy %[[GLOBAL_INIT_DEFAULT]] to %[[VAR_DEFAULT]]
+
+
+! ------------------------------------------------------------------------------
+! Test 4: Procedure pointers
+! Procedure pointers default initialized with '=> null()' trigger the
+! default-initialization fallback safely.
+! ------------------------------------------------------------------------------
+subroutine test_proc_pointer()
+ use my_types
+ type(ProcPointerType) :: var_proc
+ call do_something_proc(var_proc)
+end subroutine test_proc_pointer
+
+! CHECK-LABEL: func.func @_QPtest_proc_pointer()
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTprocpointertype{{.*}}>
+! CHECK: %[[VAR_DECL:.*]] = fir.declare %[[ALLOCA]] {{.*}}
+! CHECK: %[[GLOBAL_INIT_PROC:.*]] = fir.address_of(@_QQ_QMmy_typesTprocpointertype.DerivedInit)
+! CHECK: fir.copy %[[GLOBAL_INIT_PROC]] to %[[VAR_DECL]]
+
+
+! ------------------------------------------------------------------------------
+! Test 5: Procedure pointers
+! Procedure pointers without default initialization should be initialized
+! component-wise, without falling back to template copy initialization.
+! ------------------------------------------------------------------------------
+subroutine test_proc_pointer_no_init()
+ use my_types
+ type(ProcPointerNoInitType) :: var_proc
+ call do_something_proc_no_init(var_proc)
+end subroutine test_proc_pointer_no_init
+
+! CHECK-LABEL: func.func @_QPtest_proc_pointer_no_init()
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTprocpointernoinittype{{.*}}>
+! CHECK: %[[VAR_DECL:.*]] = fir.declare %[[ALLOCA]] {{.*}}
+! CHECK: %[[COORD_P:.*]] = fir.coordinate_of %[[VAR_DECL]], p
+! CHECK: %[[NULL_P:.*]] = fir.zero_bits !fir.ptr<f32>
+! CHECK: %[[BOX_P:.*]] = fir.embox %[[NULL_P]] : (!fir.ptr<f32>) -> !fir.box<!fir.ptr<f32>>
+! CHECK: fir.store %[[BOX_P]] to %[[COORD_P]]
+! CHECK: %[[COORD_PP:.*]] = fir.coordinate_of %[[VAR_DECL]], pp
+! CHECK: %[[NULL_FUNC:.*]] = fir.zero_bits () -> ()
+! CHECK: %[[BOX_PP:.*]] = fir.emboxproc %[[NULL_FUNC]] : (() -> ()) -> !fir.boxproc<() -> ()>
+! CHECK: fir.store %[[BOX_PP]] to %[[COORD_PP]]
+! CHECK-NOT: fir.copy
diff --git a/flang/test/Lower/default-initialization.f90 b/flang/test/Lower/default-initialization.f90
index e396ca853d71a..3a5f761c05e61 100644
--- a/flang/test/Lower/default-initialization.f90
+++ b/flang/test/Lower/default-initialization.f90
@@ -47,8 +47,11 @@ subroutine local_array()
subroutine local_alloc_comp
!CHECK: %[[xalloc:.*]] = fir.alloca !fir.type<_QMtest_dinitTt_alloc_comp{{(,sequence)?}}{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocal_alloc_compEx"}
!CHECK: %[[x:.*]]:2 = hlfir.declare %[[xalloc]] {uniq_name = "_QMtest_dinitFlocal_alloc_compEx"}
- !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt_alloc_comp.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt_alloc_comp{{(,sequence)?}}{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
- !CHECK: fir.copy %[[ADDR]] to %[[x]]#0 no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt_alloc_comp{{(,sequence)?}}{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtest_dinitTt_alloc_comp{{(,sequence)?}}{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+ !CHECK: %[[COORD:.*]] = fir.coordinate_of %[[x]]#0, i : (!fir.ref<!fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ !CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+ !CHECK: %[[SHAPE:.*]] = fir.shape %c0{{.*}} : (index) -> !fir.shape<1>
+ !CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+ !CHECK: fir.store %[[EMBOX]] to %[[COORD]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
type(t_alloc_comp) :: x
end subroutine
diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90
index 352bc64c72945..3bd68168f796f 100644
--- a/flang/test/Lower/derived-type-finalization.f90
+++ b/flang/test/Lower/derived-type-finalization.f90
@@ -186,9 +186,8 @@ subroutine test_avoid_double_finalization(a)
! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_avoid_double_finalization(
! CHECK: %[[b:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt3{t:!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>}> {bindc_name = "b", uniq_name = "_QMderived_type_finalizationFtest_avoid_double_finalizationEb"}
! CHECK: %[[b_DECL:.*]]:2 = hlfir.declare %[[b]]
-! CHECK: fir.copy %{{.*}} to %[[b_DECL]]#0
+! CHECK: hlfir.assign %{{.*}} to %[[b_DECL]]#0
! CHECK-NOT: fir.call @_FortranADestroy
-! CHECK: hlfir.assign
! CHECK: fir.call @_FortranADestroy
function no_func_ret_finalize() result(ty)
diff --git a/flang/test/Lower/derived-type-temp.f90 b/flang/test/Lower/derived-type-temp.f90
index b6363c2b8636f..c2ee34e53ba7f 100644
--- a/flang/test/Lower/derived-type-temp.f90
+++ b/flang/test/Lower/derived-type-temp.f90
@@ -15,5 +15,7 @@ program derived_temp_init
! CHECK: %[[ALLOC:.*]] = fir.alloca !fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}> {bindc_name = "x", uniq_name = "_QFEx"}
! CHECK: %[[x:.*]]:2 = hlfir.declare %[[ALLOC]] {{.*}}
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QFTt1.DerivedInit) : !fir.ref<!fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[x]]#0 no_overlap : !fir.ref<!fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}>>, !fir.ref<!fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}>>
+! CHECK: %[[COOR:.*]] = fir.coordinate_of %[[x]]#0, i : (!fir.ref<!fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<i32>
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+! CHECK: fir.store %[[EMBOX]] to %[[COOR]] : !fir.ref<!fir.box<!fir.heap<i32>>>
diff --git a/flang/test/Lower/forall/forall-allocatable-2.f90 b/flang/test/Lower/forall/forall-allocatable-2.f90
index 3fb4aa17f45e6..513d2f6731f1d 100644
--- a/flang/test/Lower/forall/forall-allocatable-2.f90
+++ b/flang/test/Lower/forall/forall-allocatable-2.f90
@@ -20,8 +20,12 @@ end subroutine forall_with_allocatable2
! CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_1]] arg 1 {uniq_name = "_QFforall_with_allocatable2Ea1"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
! CHECK: %[[VAL_8:.*]] = fir.alloca !fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}> {bindc_name = "thing", uniq_name = "_QFforall_with_allocatable2Ething"}
! CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_8]] {uniq_name = "_QFforall_with_allocatable2Ething"} : (!fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> (!fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>)
-! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QQ_QFforall_with_allocatable2Tt.DerivedInit) : !fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
-! CHECK: fir.copy %[[VAL_10]] to %[[VAL_9]]#0 no_overlap : !fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+! CHECK: %[[VAL_2:.*]] = fir.coordinate_of %[[VAL_9]]#0, arr : (!fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK: %[[VAL_3:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+! CHECK: %[[VAL_4:.*]] = arith.constant 0 : index
+! CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_3]](%[[VAL_5]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK: fir.store %[[VAL_6]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
! CHECK: %[[VAL_11:.*]] = arith.constant 5 : i32
! CHECK: %[[VAL_12:.*]] = arith.constant 15 : i32
! CHECK: hlfir.forall lb {
@@ -45,5 +49,8 @@ end subroutine forall_with_allocatable2
! CHECK: hlfir.yield %[[VAL_23]] : !fir.ref<f32>
! CHECK: }
! CHECK: }
+! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_9]]#0 : (!fir.ref<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>
+! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (!fir.box<!fir.type<_QFforall_with_allocatable2Tt{i:i32,arr:!fir.box<!fir.heap<!fir.array<?xf32>>>}>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranADestroy(%[[VAL_25]]) fastmath<contract> : (!fir.box<none>) -> ()
! CHECK: return
! CHECK: }
diff --git a/flang/test/Lower/pointer-default-init.f90 b/flang/test/Lower/pointer-default-init.f90
index b4a57c1f74640..5344156b67ba9 100644
--- a/flang/test/Lower/pointer-default-init.f90
+++ b/flang/test/Lower/pointer-default-init.f90
@@ -21,8 +21,12 @@ subroutine test_local()
! CHECK-LABEL: func.func @_QPtest_local() {
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}> {bindc_name = "x", uniq_name = "_QFtest_localEx"}
! CHECK: %[[x:.*]]:2 = hlfir.declare %[[ALLOCA]]
-! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtestTt.DerivedInit) : !fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
-! CHECK: fir.copy %[[ADDR]] to %[[x]]#0 no_overlap : !fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>
+! CHECK: %[[x_comp:.*]] = fir.coordinate_of %[[x]]#0, x : (!fir.ref<!fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xf32>>
+! CHECK: %[[c0:.*]] = arith.constant 0 : index
+! CHECK: %[[shape:.*]] = fir.shape %[[c0]] : (index) -> !fir.shape<1>
+! CHECK: %[[embox:.*]] = fir.embox %[[zero]](%[[shape]]) : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK: fir.store %[[embox]] to %[[x_comp]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
subroutine test_saved()
use test, only : t
More information about the flang-commits
mailing list