[flang-commits] [flang] [flang][lowering] Implement component-wise initialization for derived types (PR #187465)

via flang-commits flang-commits at lists.llvm.org
Wed Apr 15 23:27:30 PDT 2026


https://github.com/refuseno updated https://github.com/llvm/llvm-project/pull/187465

>From d1c9fb4cb033bbc5b9e8e5fb95dfa902b7f79496 Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Thu, 19 Mar 2026 16:27:03 +0800
Subject: [PATCH 1/7] component-wise-init

Co-authored-by: ict-ql <168183727+ict-ql at users.noreply.github.com>
Co-authored-by: buggfg <wangyingying at bosc.ac.cn>
---
 flang/lib/Lower/ConvertVariable.cpp      | 369 +++++++++++++++++++----
 flang/test/Lower/component-wise-init.f90 |  94 ++++++
 2 files changed, 407 insertions(+), 56 deletions(-)
 create mode 100644 flang/test/Lower/component-wise-init.f90

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 0ededb364bfea..16509b855ce9e 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -10,7 +10,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/AbstractConverter.h"
 #include "flang/Lower/Allocatable.h"
 #include "flang/Lower/BoxAnalyzer.h"
@@ -20,6 +19,7 @@
 #include "flang/Lower/ConvertExpr.h"
 #include "flang/Lower/ConvertExprToHLFIR.h"
 #include "flang/Lower/ConvertProcedureDesignator.h"
+#include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/Mangler.h"
 #include "flang/Lower/PFTBuilder.h"
 #include "flang/Lower/StatementContext.h"
@@ -32,12 +32,15 @@
 #include "flang/Optimizer/Builder/IntrinsicCall.h"
 #include "flang/Optimizer/Builder/Runtime/Derived.h"
 #include "flang/Optimizer/Builder/Todo.h"
+#include "flang/Optimizer/CodeGen/TypeConverter.h"
 #include "flang/Optimizer/Dialect/CUF/CUFOps.h"
 #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/Support/FIRContext.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
+#include "flang/Optimizer/Support/DataLayout.h"
 #include "flang/Optimizer/Support/FatalError.h"
 #include "flang/Optimizer/Support/InternalNames.h"
 #include "flang/Optimizer/Support/Utils.h"
@@ -48,6 +51,11 @@
 #include "llvm/Support/Debug.h"
 #include <optional>
 
+static llvm::cl::opt<bool> enablePreciseInit(
+    "enable-precise-init",
+    llvm::cl::desc("Enable precise component initialization for derived types"),
+    llvm::cl::init(false));
+
 static llvm::cl::opt<bool>
     allowAssumedRank("allow-assumed-rank",
                      llvm::cl::desc("Enable assumed rank lowering"),
@@ -585,15 +593,14 @@ fir::GlobalOp Fortran::lower::defineGlobal(
     if (details && details->init()) {
       auto sym{*details->init()};
       if (sym) // Has a procedure target.
-        createGlobalInitialization(
-            builder, global, [&](fir::FirOpBuilder &b) {
-              Fortran::lower::StatementContext stmtCtx(
-                  /*cleanupProhibited=*/true);
-              auto box{Fortran::lower::convertProcedureDesignatorInitialTarget(
-                  converter, loc, *sym)};
-              auto castTo{builder.createConvert(loc, symTy, box)};
-              fir::HasValueOp::create(b, loc, castTo);
-            });
+        createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
+          Fortran::lower::StatementContext stmtCtx(
+              /*cleanupProhibited=*/true);
+          auto box{Fortran::lower::convertProcedureDesignatorInitialTarget(
+              converter, loc, *sym)};
+          auto castTo{builder.createConvert(loc, symTy, box)};
+          fir::HasValueOp::create(b, loc, castTo);
+        });
       else { // Has NULL() target.
         createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
           auto box{fir::factory::createNullBoxProc(b, loc, symTy)};
@@ -812,6 +819,244 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
   return Fortran::lower::hasDefaultInitialization(sym);
 }
 
+namespace {
+/// Determines if \p sym represents a complex derived type.
+/// A derived type is considered complex if it contains allocatable, pointer,
+/// or procedure pointer components, or nested complex derived types.
+static bool isComplexDerivedType(const Fortran::semantics::Symbol &sym) {
+  const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType();
+  if (!declTy || !declTy->AsDerived())
+    return false;
+  const Fortran::semantics::DerivedTypeSpec &derivedSpec = *declTy->AsDerived();
+  const Fortran::semantics::Scope *scope = derivedSpec.GetScope();
+  if (!scope)
+    return false;
+  const auto &typeDetails =
+      derivedSpec.typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
+  for (const auto &compName : typeDetails.componentNames()) {
+    auto iter = scope->find(compName);
+    if (iter == scope->cend())
+      continue;
+    const Fortran::semantics::Symbol &compSym = iter->second.get();
+    const auto *objDetails =
+        compSym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
+    const auto *procDetails =
+        compSym.detailsIf<Fortran::semantics::ProcEntityDetails>();
+    if (Fortran::semantics::IsAllocatableOrPointer(compSym)) {
+      return true;
+    } else if (procDetails && procDetails->init().has_value()) {
+      return true;
+    } else if (objDetails && objDetails->init() && compSym.Rank() > 0) {
+      return true;
+    } else if (isComplexDerivedType(compSym)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+/// Performs precise, 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();
+  const Fortran::semantics::Scope *scope = derivedSpec.GetScope();
+  if (!scope)
+    return;
+  const auto &typeDetails =
+      derivedSpec.typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
+  for (const auto &compName : typeDetails.componentNames()) {
+    auto scopeIter = scope->find(compName);
+    if (scopeIter == scope->cend())
+      continue;
+    const Fortran::semantics::Symbol &compSym = scopeIter->second.get();
+    const auto *objDetails =
+        compSym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
+    const auto *procDetails =
+        compSym.detailsIf<Fortran::semantics::ProcEntityDetails>();
+    // Determine if the component requires initialization.
+    // Dynamic descriptors (pointers/allocatables) and explicitly initialized
+    // entities must be processed.
+    bool needsInit = Fortran::semantics::IsAllocatableOrPointer(compSym) ||
+                     (objDetails && objDetails->init()) ||
+                     (procDetails && procDetails->init().has_value());
+    if (!needsInit && !Fortran::lower::hasDefaultInitialization(compSym))
+      continue;
+    std::string name = converter.getRecordTypeFieldName(compSym);
+    mlir::Type compFirTy = recTy.getType(name);
+    if (!compFirTy)
+      continue;
+    // Compute the memory coordinate of the current component.
+    auto fieldIdx = builder.create<fir::FieldIndexOp>(
+        loc, fir::FieldType::get(recTy.getContext()), name, recTy,
+        mlir::ValueRange{});
+    auto compAddr =
+        builder.create<fir::CoordinateOp>(loc, builder.getRefType(compFirTy),
+                                          baseAddr, mlir::ValueRange{fieldIdx});
+
+    // Case A: Standard data components (ObjectEntityDetails).
+    if (objDetails) {
+      if (objDetails->init()) {
+        // Subcase A.1: Component has explicit initialization.
+        if (Fortran::semantics::IsPointer(compSym)) {
+          // Subcase A.1.1: Pointer with explicit target.
+          std::string globalName = fir::NameUniquer::doGenerated(
+              (converter.mangleName(derivedSpec) + fir::kNameSeparator + name +
+               fir::kNameSeparator + "init")
+                  .str());
+          fir::GlobalOp global = builder.getNamedGlobal(globalName);
+          if (!global) {
+            global = builder.createGlobal(loc, compFirTy, globalName,
+                                          builder.createInternalLinkage(),
+                                          mlir::Attribute{}, true);
+            createGlobalInitialization(
+                builder, global, [&](fir::FirOpBuilder &b) {
+                  mlir::Value initBox = Fortran::lower::genInitialDataTarget(
+                      converter, loc, compFirTy, *objDetails->init());
+                  b.create<fir::HasValueOp>(loc, initBox);
+                });
+          }
+          auto srcAddr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
+                                                       global.getSymbol());
+          mlir::Value loadedBox = builder.create<fir::LoadOp>(loc, srcAddr);
+          builder.create<fir::StoreOp>(loc, loadedBox, compAddr);
+        } else {
+          // Subcase A.1.2: Non-pointer components with explicit initialization.
+          Fortran::lower::StatementContext stmtCtx(/*cleanupProhibited=*/true);
+          if (mlir::isa<fir::SequenceType>(compFirTy)) {
+            std::string globalName = fir::NameUniquer::doGenerated(
+                (converter.mangleName(derivedSpec) + fir::kNameSeparator +
+                 name + fir::kNameSeparator + "arr_init")
+                    .str());
+            fir::GlobalOp global = builder.getNamedGlobal(globalName);
+            if (!global) {
+              const auto &initExpr = objDetails->init().value();
+              cuf::DataAttributeAttr dataAttr = {};
+              global = Fortran::lower::tryCreatingDenseGlobal(
+                  builder, loc, compFirTy, globalName,
+                  builder.createInternalLinkage(), /*isConst=*/true, initExpr,
+                  dataAttr);
+            }
+            if (global) {
+              auto srcAddr = builder.create<fir::AddrOfOp>(
+                  loc, global.resultType(), global.getSymbol());
+              builder.create<fir::CopyOp>(loc, srcAddr, compAddr,
+                                          /*noOverlap=*/true);
+            } else {
+              Fortran::lower::StatementContext inlineCtx;
+              Fortran::lower::SymMap emptyMap;
+              hlfir::Entity lhs{compAddr};
+              hlfir::Entity rhs = Fortran::lower::convertExprToHLFIR(
+                  loc, converter, objDetails->init().value(), emptyMap,
+                  inlineCtx);
+              builder.create<hlfir::AssignOp>(loc, rhs, lhs);
+            }
+          } else {
+            // Scalar component: Evaluate the expression and store directly.
+            fir::ExtendedValue exInitVal = genInitializerExprValue(
+                converter, loc, objDetails->init().value(), stmtCtx);
+            mlir::Value initVal = fir::getBase(exInitVal);
+            if (fir::isa_ref_type(initVal.getType()) &&
+                !fir::isa_ref_type(compFirTy))
+              initVal = builder.create<fir::LoadOp>(loc, initVal);
+            mlir::Value castVal =
+                builder.createConvert(loc, compFirTy, initVal);
+            builder.create<fir::StoreOp>(loc, castVal, compAddr);
+          }
+        }
+      } else if (Fortran::semantics::IsAllocatableOrPointer(compSym)) {
+        // Subcase A.2: Pointer or allocatable without initialization.
+        // Create deallocated/disassociated value.
+        std::string globalName = fir::NameUniquer::doGenerated(
+            (converter.mangleName(derivedSpec) + fir::kNameSeparator + name +
+             fir::kNameSeparator + "null_box")
+                .str());
+        fir::GlobalOp global = builder.getNamedGlobal(globalName);
+        if (!global) {
+          global = builder.createGlobal(loc, compFirTy, globalName,
+                                        builder.createInternalLinkage(),
+                                        mlir::Attribute{}, true);
+          createGlobalInitialization(
+              builder, global, [&](fir::FirOpBuilder &b) {
+                mlir::Value nullBox = fir::factory::createUnallocatedBox(
+                    b, loc, compFirTy, mlir::ValueRange{});
+                b.create<fir::HasValueOp>(loc, nullBox);
+              });
+        }
+        auto srcAddr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
+                                                     global.getSymbol());
+        mlir::Value loadedBox = builder.create<fir::LoadOp>(loc, srcAddr);
+        builder.create<fir::StoreOp>(loc, loadedBox, compAddr);
+      } else if (Fortran::lower::hasDefaultInitialization(compSym)) {
+        // Subcase A.3: Nested derived type requires initialization.
+        // Derived type has no explicit initialization but contains
+        // components requiring initialization.
+        if (mlir::isa<fir::SequenceType>(compFirTy) &&
+            isComplexDerivedType(compSym)) {
+          // Complex derived type arrays.
+          mlir::Value box =
+              builder.createBox(loc, fir::ExtendedValue(compAddr));
+          fir::runtime::genDerivedTypeInitialize(builder, loc, box);
+        } else if (isComplexDerivedType(compSym)) {
+          // Complex derived type scalars.
+          const Fortran::semantics::DeclTypeSpec *compDeclTy =
+              compSym.GetType();
+          auto nestedRecTy = mlir::dyn_cast<fir::RecordType>(compFirTy);
+          genDerivedTypeComponentInit(converter, loc, *compDeclTy->AsDerived(),
+                                      compAddr, nestedRecTy);
+        } else {
+          // Simple derived type scalars.
+          Fortran::lower::StatementContext stmtCtx;
+          mlir::Value initVal = genDefaultInitializerValue(
+              converter, loc, compSym, compFirTy, stmtCtx);
+          mlir::Value castVal = builder.createConvert(loc, compFirTy, initVal);
+          builder.create<fir::StoreOp>(loc, castVal, compAddr);
+        }
+      }
+    }
+    // Case B: Procedure pointers (ProcEntityDetails).
+    else if (procDetails) {
+      if (procDetails->init().has_value()) {
+        // Has a procedure or NULL() target.
+        std::string globalName = fir::NameUniquer::doGenerated(
+            (converter.mangleName(derivedSpec) + fir::kNameSeparator + name +
+             fir::kNameSeparator + "init")
+                .str());
+        fir::GlobalOp global = builder.getNamedGlobal(globalName);
+        if (!global) {
+          global = builder.createGlobal(loc, compFirTy, globalName,
+                                        builder.createInternalLinkage(),
+                                        mlir::Attribute{}, true);
+          createGlobalInitialization(
+              builder, global, [&](fir::FirOpBuilder &b) {
+                mlir::Value procBox;
+                auto targetSym = *procDetails->init();
+                if (targetSym) {
+                  procBox =
+                      Fortran::lower::convertProcedureDesignatorInitialTarget(
+                          converter, loc, *targetSym);
+                  procBox = b.createConvert(loc, compFirTy, procBox);
+                } else {
+                  procBox = fir::factory::createNullBoxProc(b, loc, compFirTy);
+                }
+                b.create<fir::HasValueOp>(loc, procBox);
+              });
+        }
+        auto srcAddr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
+                                                     global.getSymbol());
+        mlir::Value loadedBox = builder.create<fir::LoadOp>(loc, srcAddr);
+        builder.create<fir::StoreOp>(loc, loadedBox, compAddr);
+      } else {
+        // Has no initialization.
+        continue;
+      }
+    }
+  }
+}
+} // namespace
+
 /// Call default initialization runtime routine to initialize \p var.
 void Fortran::lower::defaultInitializeAtRuntime(
     Fortran::lower::AbstractConverter &converter,
@@ -823,8 +1068,8 @@ void Fortran::lower::defaultInitializeAtRuntime(
     // 15.5.2.12 point 3, absent optional dummies are not initialized.
     // Creating descriptor/passing null descriptor to the runtime would
     // create runtime crashes.
-    auto isPresent = fir::IsPresentOp::create(builder, loc, builder.getI1Type(),
-                                              fir::getBase(exv));
+    auto isPresent = builder.create<fir::IsPresentOp>(loc, builder.getI1Type(),
+                                                      fir::getBase(exv));
     builder.genIfThen(loc, isPresent)
         .genThen([&]() {
           auto box = builder.createBox(loc, exv);
@@ -839,56 +1084,68 @@ 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 useFastInit =
+        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 (useFastInit) {
+      if (enablePreciseInit) {
+        // Precise initialization
+        mlir::Value baseAddr = fir::getBase(exv);
+        const auto &derivedSpec = *sym.GetType()->AsDerived();
+        auto recTy = mlir::cast<fir::RecordType>(
+            fir::unwrapPassByRefType(baseAddr.getType()));
+        genDerivedTypeComponentInit(converter, loc, derivedSpec, baseAddr,
+                                    recTy);
+      } else {
+        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));
+                builder.create<fir::HasValueOp>(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);
+                builder.create<fir::HasValueOp>(loc, castTo);
+              });
+        }
+        auto addrOf = builder.create<fir::AddrOfOp>(loc, global.resultType(),
+                                                    global.getSymbol());
+        builder.create<fir::CopyOp>(loc, addrOf, fir::getBase(exv),
+                                    /*noOverlap=*/true);
       }
-      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/component-wise-init.f90 b/flang/test/Lower/component-wise-init.f90
new file mode 100644
index 0000000000000..2b751e784dc47
--- /dev/null
+++ b/flang/test/Lower/component-wise-init.f90
@@ -0,0 +1,94 @@
+! RUN: bbc -emit-fir -enable-precise-init %s -o - | FileCheck %s
+
+! Test for precise component-wise initialization of derived types
+! to avoid generating large, fully-initialized global templates (sparse initialization).
+
+module my_types
+  type :: InnerType
+    integer :: flag = 42
+    real, pointer :: p
+    real, allocatable :: arr(:)
+  end type InnerType
+
+  type :: OuterType
+    real, pointer :: q
+    integer :: explicit_arr(3) = [10, 20, 30]
+    real(8) :: uninit_buffer(80, 100, 100)
+    type(InnerType) :: nested
+    type(InnerType) :: nested_arr(2)
+  end type OuterType
+end module my_types
+
+subroutine test_complex_init()
+  use my_types
+  type(OuterType) :: my_var
+  call do_something(my_var)
+end subroutine test_complex_init
+
+! ==============================================================================
+! FileCheck Assertions
+! ==============================================================================
+
+! CHECK-LABEL: func.func @_QPtest_complex_init()
+
+! Ensure we allocate the local variable
+! CHECK: %[[MY_VAR:.*]] = fir.alloca !fir.type<_QMmy_typesToutertype{{.*}}>
+
+! ------------------------------------------------------------------------------
+! 1. Check pointer 'q' initialization (First component, offset 0, no coordinate_of needed)
+! ------------------------------------------------------------------------------
+! CHECK: %[[Q_NULL_BOX_ADDR:.*]] = fir.address_of(@_QQ_QMmy_typesToutertype.q.{{(null_box|init)}})
+! CHECK: %[[Q_NULL_BOX:.*]] = fir.load %[[Q_NULL_BOX_ADDR]]
+! CHECK: fir.store %[[Q_NULL_BOX]] to %{{.*}}
+
+! ------------------------------------------------------------------------------
+! 2. Check explicit array initialization
+! ------------------------------------------------------------------------------
+! CHECK: %[[EXPLICIT_ARR_ADDR:.*]] = fir.coordinate_of %{{.*}}, explicit_arr
+! CHECK: %[[EXPLICIT_ARR_INIT:.*]] = fir.address_of(@_QQ_QMmy_typesToutertype.explicit_arr.arr_init)
+! CHECK: fir.copy %[[EXPLICIT_ARR_INIT]] to %[[EXPLICIT_ARR_ADDR]]
+
+! ------------------------------------------------------------------------------
+! 3. Check scalar derived type 'nested' component-wise precise initialization
+! ------------------------------------------------------------------------------
+! CHECK: %[[NESTED_ADDR:.*]] = fir.coordinate_of %{{.*}}, nested
+
+! -> Check 'flag' (integer = 42)
+! CHECK: %[[FLAG_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], flag
+! CHECK: fir.store %c42{{.*}} to %[[FLAG_ADDR]]
+
+! -> Check 'p' (pointer)
+! CHECK: %[[P_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], p
+! CHECK: %[[P_INIT_ADDR:.*]] = fir.address_of(@_QQ_QMmy_typesTinnertype.p.{{(null_box|init)}})
+! CHECK: %[[P_INIT_VAL:.*]] = fir.load %[[P_INIT_ADDR]]
+! CHECK: fir.store %[[P_INIT_VAL]] to %[[P_ADDR]]
+
+! -> Check 'arr' (allocatable)
+! CHECK: %[[ARR_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], arr
+! CHECK: %[[ARR_INIT_ADDR:.*]] = fir.address_of(@_QQ_QMmy_typesTinnertype.arr.null_box)
+! CHECK: %[[ARR_INIT_VAL:.*]] = fir.load %[[ARR_INIT_ADDR]]
+! CHECK: fir.store %[[ARR_INIT_VAL]] to %[[ARR_ADDR]]
+
+! ------------------------------------------------------------------------------
+! 4. Check derived type array 'nested_arr' initialization (Runtime call)
+! ------------------------------------------------------------------------------
+! CHECK: %[[NESTED_ARR_ADDR:.*]] = fir.coordinate_of %{{.*}}, nested_arr
+! CHECK: %[[NESTED_ARR_BOX:.*]] = fir.embox %[[NESTED_ARR_ADDR]]
+! CHECK: %[[NESTED_ARR_PTR:.*]] = fir.convert %[[NESTED_ARR_BOX]]
+! CHECK: fir.call @_FortranAInitialize(%[[NESTED_ARR_PTR]], {{.*}})
+
+
+! ------------------------------------------------------------------------------
+! Global Variables Check
+! ------------------------------------------------------------------------------
+
+! CRITICAL: Ensure NO full derived type initialization templates are generated!
+! We should NOT see fir.global for the entire DerivedInit.
+! CHECK-NOT: fir.global internal @_QQ_QMmy_typesToutertype.DerivedInit
+! CHECK-NOT: fir.global internal @_QQ_QMmy_typesTinnertype.DerivedInit
+
+! Verify the fine-grained component global constants exist
+! CHECK-DAG: fir.global internal @_QQ_QMmy_typesToutertype.explicit_arr.arr_init(dense<[10, 20, 30]> : tensor<3xi32>)
+! CHECK-DAG: fir.global internal @_QQ_QMmy_typesToutertype.q.{{(null_box|init)}}
+! CHECK-DAG: fir.global internal @_QQ_QMmy_typesTinnertype.p.{{(null_box|init)}}
+! CHECK-DAG: fir.global internal @_QQ_QMmy_typesTinnertype.arr.null_box
\ No newline at end of file

>From 2013a119c00f304f8f6dde15129338376e0f59b2 Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Fri, 20 Mar 2026 16:08:44 +0800
Subject: [PATCH 2/7] Fix deprecated MLIR builder.create usages

---
 flang/lib/Lower/ConvertVariable.cpp | 91 ++++++++++++++---------------
 1 file changed, 45 insertions(+), 46 deletions(-)

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 16509b855ce9e..c114643d89e5a 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/AbstractConverter.h"
 #include "flang/Lower/Allocatable.h"
 #include "flang/Lower/BoxAnalyzer.h"
@@ -19,7 +20,6 @@
 #include "flang/Lower/ConvertExpr.h"
 #include "flang/Lower/ConvertExprToHLFIR.h"
 #include "flang/Lower/ConvertProcedureDesignator.h"
-#include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/Mangler.h"
 #include "flang/Lower/PFTBuilder.h"
 #include "flang/Lower/StatementContext.h"
@@ -32,7 +32,6 @@
 #include "flang/Optimizer/Builder/IntrinsicCall.h"
 #include "flang/Optimizer/Builder/Runtime/Derived.h"
 #include "flang/Optimizer/Builder/Todo.h"
-#include "flang/Optimizer/CodeGen/TypeConverter.h"
 #include "flang/Optimizer/Dialect/CUF/CUFOps.h"
 #include "flang/Optimizer/Dialect/FIRAttr.h"
 #include "flang/Optimizer/Dialect/FIRDialect.h"
@@ -40,7 +39,6 @@
 #include "flang/Optimizer/Dialect/FIRType.h"
 #include "flang/Optimizer/Dialect/Support/FIRContext.h"
 #include "flang/Optimizer/HLFIR/HLFIROps.h"
-#include "flang/Optimizer/Support/DataLayout.h"
 #include "flang/Optimizer/Support/FatalError.h"
 #include "flang/Optimizer/Support/InternalNames.h"
 #include "flang/Optimizer/Support/Utils.h"
@@ -593,14 +591,15 @@ fir::GlobalOp Fortran::lower::defineGlobal(
     if (details && details->init()) {
       auto sym{*details->init()};
       if (sym) // Has a procedure target.
-        createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
-          Fortran::lower::StatementContext stmtCtx(
-              /*cleanupProhibited=*/true);
-          auto box{Fortran::lower::convertProcedureDesignatorInitialTarget(
-              converter, loc, *sym)};
-          auto castTo{builder.createConvert(loc, symTy, box)};
-          fir::HasValueOp::create(b, loc, castTo);
-        });
+        createGlobalInitialization(
+            builder, global, [&](fir::FirOpBuilder &b) {
+              Fortran::lower::StatementContext stmtCtx(
+                  /*cleanupProhibited=*/true);
+              auto box{Fortran::lower::convertProcedureDesignatorInitialTarget(
+                  converter, loc, *sym)};
+              auto castTo{builder.createConvert(loc, symTy, box)};
+              fir::HasValueOp::create(b, loc, castTo);
+            });
       else { // Has NULL() target.
         createGlobalInitialization(builder, global, [&](fir::FirOpBuilder &b) {
           auto box{fir::factory::createNullBoxProc(b, loc, symTy)};
@@ -889,12 +888,12 @@ static void genDerivedTypeComponentInit(
     if (!compFirTy)
       continue;
     // Compute the memory coordinate of the current component.
-    auto fieldIdx = builder.create<fir::FieldIndexOp>(
-        loc, fir::FieldType::get(recTy.getContext()), name, recTy,
+    auto fieldIdx = fir::FieldIndexOp::create(
+        builder, loc, fir::FieldType::get(recTy.getContext()), name, recTy,
         mlir::ValueRange{});
     auto compAddr =
-        builder.create<fir::CoordinateOp>(loc, builder.getRefType(compFirTy),
-                                          baseAddr, mlir::ValueRange{fieldIdx});
+        fir::CoordinateOp::create(builder, loc, builder.getRefType(compFirTy),
+                                  baseAddr, mlir::ValueRange{fieldIdx});
 
     // Case A: Standard data components (ObjectEntityDetails).
     if (objDetails) {
@@ -915,13 +914,13 @@ static void genDerivedTypeComponentInit(
                 builder, global, [&](fir::FirOpBuilder &b) {
                   mlir::Value initBox = Fortran::lower::genInitialDataTarget(
                       converter, loc, compFirTy, *objDetails->init());
-                  b.create<fir::HasValueOp>(loc, initBox);
+                  fir::HasValueOp::create(b, loc, initBox);
                 });
           }
-          auto srcAddr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
-                                                       global.getSymbol());
-          mlir::Value loadedBox = builder.create<fir::LoadOp>(loc, srcAddr);
-          builder.create<fir::StoreOp>(loc, loadedBox, compAddr);
+          auto srcAddr = fir::AddrOfOp::create(builder, loc, global.resultType(),
+                                               global.getSymbol());
+          mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
+          fir::StoreOp::create(builder, loc, loadedBox, compAddr);
         } else {
           // Subcase A.1.2: Non-pointer components with explicit initialization.
           Fortran::lower::StatementContext stmtCtx(/*cleanupProhibited=*/true);
@@ -940,10 +939,10 @@ static void genDerivedTypeComponentInit(
                   dataAttr);
             }
             if (global) {
-              auto srcAddr = builder.create<fir::AddrOfOp>(
-                  loc, global.resultType(), global.getSymbol());
-              builder.create<fir::CopyOp>(loc, srcAddr, compAddr,
-                                          /*noOverlap=*/true);
+              auto srcAddr = fir::AddrOfOp::create(
+                  builder, loc, global.resultType(), global.getSymbol());
+              fir::CopyOp::create(builder, loc, srcAddr, compAddr,
+                                  /*noOverlap=*/true);
             } else {
               Fortran::lower::StatementContext inlineCtx;
               Fortran::lower::SymMap emptyMap;
@@ -951,7 +950,7 @@ static void genDerivedTypeComponentInit(
               hlfir::Entity rhs = Fortran::lower::convertExprToHLFIR(
                   loc, converter, objDetails->init().value(), emptyMap,
                   inlineCtx);
-              builder.create<hlfir::AssignOp>(loc, rhs, lhs);
+              hlfir::AssignOp::create(builder, loc, rhs, lhs);
             }
           } else {
             // Scalar component: Evaluate the expression and store directly.
@@ -960,10 +959,10 @@ static void genDerivedTypeComponentInit(
             mlir::Value initVal = fir::getBase(exInitVal);
             if (fir::isa_ref_type(initVal.getType()) &&
                 !fir::isa_ref_type(compFirTy))
-              initVal = builder.create<fir::LoadOp>(loc, initVal);
+              initVal = fir::LoadOp::create(builder, loc, initVal);
             mlir::Value castVal =
                 builder.createConvert(loc, compFirTy, initVal);
-            builder.create<fir::StoreOp>(loc, castVal, compAddr);
+            fir::StoreOp::create(builder, loc, castVal, compAddr);
           }
         }
       } else if (Fortran::semantics::IsAllocatableOrPointer(compSym)) {
@@ -982,13 +981,13 @@ static void genDerivedTypeComponentInit(
               builder, global, [&](fir::FirOpBuilder &b) {
                 mlir::Value nullBox = fir::factory::createUnallocatedBox(
                     b, loc, compFirTy, mlir::ValueRange{});
-                b.create<fir::HasValueOp>(loc, nullBox);
+                fir::HasValueOp::create(b, loc, nullBox);
               });
         }
-        auto srcAddr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
-                                                     global.getSymbol());
-        mlir::Value loadedBox = builder.create<fir::LoadOp>(loc, srcAddr);
-        builder.create<fir::StoreOp>(loc, loadedBox, compAddr);
+        auto srcAddr = fir::AddrOfOp::create(builder, loc, global.resultType(),
+                                             global.getSymbol());
+        mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
+        fir::StoreOp::create(builder, loc, loadedBox, compAddr);
       } else if (Fortran::lower::hasDefaultInitialization(compSym)) {
         // Subcase A.3: Nested derived type requires initialization.
         // Derived type has no explicit initialization but contains
@@ -1012,7 +1011,7 @@ static void genDerivedTypeComponentInit(
           mlir::Value initVal = genDefaultInitializerValue(
               converter, loc, compSym, compFirTy, stmtCtx);
           mlir::Value castVal = builder.createConvert(loc, compFirTy, initVal);
-          builder.create<fir::StoreOp>(loc, castVal, compAddr);
+          fir::StoreOp::create(builder, loc, castVal, compAddr);
         }
       }
     }
@@ -1041,13 +1040,13 @@ static void genDerivedTypeComponentInit(
                 } else {
                   procBox = fir::factory::createNullBoxProc(b, loc, compFirTy);
                 }
-                b.create<fir::HasValueOp>(loc, procBox);
+                fir::HasValueOp::create(b, loc, procBox);
               });
         }
-        auto srcAddr = builder.create<fir::AddrOfOp>(loc, global.resultType(),
-                                                     global.getSymbol());
-        mlir::Value loadedBox = builder.create<fir::LoadOp>(loc, srcAddr);
-        builder.create<fir::StoreOp>(loc, loadedBox, compAddr);
+        auto srcAddr = fir::AddrOfOp::create(builder, loc, global.resultType(),
+                                             global.getSymbol());
+        mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
+        fir::StoreOp::create(builder, loc, loadedBox, compAddr);
       } else {
         // Has no initialization.
         continue;
@@ -1068,8 +1067,8 @@ void Fortran::lower::defaultInitializeAtRuntime(
     // 15.5.2.12 point 3, absent optional dummies are not initialized.
     // Creating descriptor/passing null descriptor to the runtime would
     // create runtime crashes.
-    auto isPresent = builder.create<fir::IsPresentOp>(loc, builder.getI1Type(),
-                                                      fir::getBase(exv));
+    auto isPresent = fir::IsPresentOp::create(builder, loc, builder.getI1Type(),
+                                              fir::getBase(exv));
     builder.genIfThen(loc, isPresent)
         .genThen([&]() {
           auto box = builder.createBox(loc, exv);
@@ -1123,7 +1122,7 @@ void Fortran::lower::defaultInitializeAtRuntime(
                     converter, loc, details->init().value(), stmtCtx);
                 mlir::Value castTo =
                     builder.createConvert(loc, symTy, fir::getBase(initVal));
-                builder.create<fir::HasValueOp>(loc, castTo);
+                fir::HasValueOp::create(builder, loc, castTo);
               });
         } else if (!global) {
           global = builder.createGlobal(loc, symTy, globalName, linkage,
@@ -1138,13 +1137,13 @@ void Fortran::lower::defaultInitializeAtRuntime(
                 mlir::Value initVal = genDefaultInitializerValue(
                     converter, loc, sym, symTy, stmtCtx);
                 mlir::Value castTo = builder.createConvert(loc, symTy, initVal);
-                builder.create<fir::HasValueOp>(loc, castTo);
+                fir::HasValueOp::create(builder, loc, castTo);
               });
         }
-        auto addrOf = builder.create<fir::AddrOfOp>(loc, global.resultType(),
-                                                    global.getSymbol());
-        builder.create<fir::CopyOp>(loc, addrOf, fir::getBase(exv),
-                                    /*noOverlap=*/true);
+        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);

>From a09c761d8498644dd4e95603dd2a451a6acf7b3c Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Fri, 20 Mar 2026 20:04:00 +0800
Subject: [PATCH 3/7] Correct the format.

---
 flang/lib/Lower/ConvertVariable.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index c114643d89e5a..8f2320729cfdd 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -917,8 +917,8 @@ static void genDerivedTypeComponentInit(
                   fir::HasValueOp::create(b, loc, initBox);
                 });
           }
-          auto srcAddr = fir::AddrOfOp::create(builder, loc, global.resultType(),
-                                               global.getSymbol());
+          auto srcAddr = fir::AddrOfOp::create(
+              builder, loc, global.resultType(), global.getSymbol());
           mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
           fir::StoreOp::create(builder, loc, loadedBox, compAddr);
         } else {
@@ -1141,7 +1141,7 @@ void Fortran::lower::defaultInitializeAtRuntime(
               });
         }
         auto addrOf = fir::AddrOfOp::create(builder, loc, global.resultType(),
-                                          global.getSymbol());
+                                            global.getSymbol());
         fir::CopyOp::create(builder, loc, addrOf, fir::getBase(exv),
                             /*noOverlap=*/true);
       }

>From d9d8c06d4fad7f46af1a89c00b1318ce3309e192 Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Thu, 26 Mar 2026 15:47:12 +0800
Subject: [PATCH 4/7] New component-wise initialization logic.

---
 flang/lib/Lower/ConvertVariable.cpp      | 296 ++++++++---------------
 flang/test/Lower/component-wise-init.f90 | 149 +++++++-----
 2 files changed, 181 insertions(+), 264 deletions(-)

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 8f2320729cfdd..91b21e80621f3 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -49,11 +49,6 @@
 #include "llvm/Support/Debug.h"
 #include <optional>
 
-static llvm::cl::opt<bool> enablePreciseInit(
-    "enable-precise-init",
-    llvm::cl::desc("Enable precise component initialization for derived types"),
-    llvm::cl::init(false));
-
 static llvm::cl::opt<bool>
     allowAssumedRank("allow-assumed-rank",
                      llvm::cl::desc("Enable assumed rank lowering"),
@@ -818,43 +813,39 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
   return Fortran::lower::hasDefaultInitialization(sym);
 }
 
-namespace {
-/// Determines if \p sym represents a complex derived type.
-/// A derived type is considered complex if it contains allocatable, pointer,
-/// or procedure pointer components, or nested complex derived types.
-static bool isComplexDerivedType(const Fortran::semantics::Symbol &sym) {
+/// Determines whether a derived type component requires non-trivial
+/// initialization. A component requires non-trivial initialization if it is an
+/// allocatable or pointer data component, or if it is a nested derived type
+/// that contains such components.
+static bool RequiresNonTrivialComponentInitialization(
+    const Fortran::semantics::Symbol &sym) {
   const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType();
   if (!declTy || !declTy->AsDerived())
     return false;
   const Fortran::semantics::DerivedTypeSpec &derivedSpec = *declTy->AsDerived();
   const Fortran::semantics::Scope *scope = derivedSpec.GetScope();
-  if (!scope)
-    return false;
+  assert(scope && "derived type has no scope");
   const auto &typeDetails =
       derivedSpec.typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
+
   for (const auto &compName : typeDetails.componentNames()) {
     auto iter = scope->find(compName);
-    if (iter == scope->cend())
-      continue;
+    assert(iter != scope->cend() && "component symbol not found in scope");
     const Fortran::semantics::Symbol &compSym = iter->second.get();
     const auto *objDetails =
         compSym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
-    const auto *procDetails =
-        compSym.detailsIf<Fortran::semantics::ProcEntityDetails>();
-    if (Fortran::semantics::IsAllocatableOrPointer(compSym)) {
-      return true;
-    } else if (procDetails && procDetails->init().has_value()) {
-      return true;
-    } else if (objDetails && objDetails->init() && compSym.Rank() > 0) {
-      return true;
-    } else if (isComplexDerivedType(compSym)) {
+    // If data component is an allocatable/pointer,
+    // or a nested derived type that requires initialization,
+    // return true.
+    if (objDetails && (Fortran::semantics::IsAllocatableOrPointer(compSym) ||
+                       RequiresNonTrivialComponentInitialization(compSym))) {
       return true;
     }
   }
   return false;
 }
 
-/// Performs precise, component-wise initialization for \p derivedSpec,
+/// 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,
@@ -862,31 +853,34 @@ static void genDerivedTypeComponentInit(
     mlir::Value baseAddr, fir::RecordType recTy) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
   const Fortran::semantics::Scope *scope = derivedSpec.GetScope();
-  if (!scope)
-    return;
+  assert(scope && "derived type has no scope");
   const auto &typeDetails =
       derivedSpec.typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
+
   for (const auto &compName : typeDetails.componentNames()) {
     auto scopeIter = scope->find(compName);
-    if (scopeIter == scope->cend())
-      continue;
+    assert(scopeIter != scope->cend() &&
+           "component name must exist in its scope");
     const Fortran::semantics::Symbol &compSym = scopeIter->second.get();
+    // Only process data components; procedure pointers are ignored.
     const auto *objDetails =
         compSym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
-    const auto *procDetails =
-        compSym.detailsIf<Fortran::semantics::ProcEntityDetails>();
-    // Determine if the component requires initialization.
-    // Dynamic descriptors (pointers/allocatables) and explicitly initialized
-    // entities must be processed.
-    bool needsInit = Fortran::semantics::IsAllocatableOrPointer(compSym) ||
-                     (objDetails && objDetails->init()) ||
-                     (procDetails && procDetails->init().has_value());
-    if (!needsInit && !Fortran::lower::hasDefaultInitialization(compSym))
+    if (!objDetails)
+      continue;
+
+    bool isPtrOrAlloc = Fortran::semantics::IsAllocatableOrPointer(compSym);
+    const Fortran::semantics::DeclTypeSpec *declTy = compSym.GetType();
+    bool isNestedDerived = declTy && declTy->AsDerived();
+    // Targets are pointer or allocatable components, or nested derived types
+    // containing them.
+    bool isTargetComponent =
+        isPtrOrAlloc ||
+        (isNestedDerived && RequiresNonTrivialComponentInitialization(compSym));
+    if (!isTargetComponent)
       continue;
     std::string name = converter.getRecordTypeFieldName(compSym);
     mlir::Type compFirTy = recTy.getType(name);
-    if (!compFirTy)
-      continue;
+    assert(compFirTy && "Component field type not found in RecordType");
     // Compute the memory coordinate of the current component.
     auto fieldIdx = fir::FieldIndexOp::create(
         builder, loc, fir::FieldType::get(recTy.getContext()), name, recTy,
@@ -894,167 +888,73 @@ static void genDerivedTypeComponentInit(
     auto compAddr =
         fir::CoordinateOp::create(builder, loc, builder.getRefType(compFirTy),
                                   baseAddr, mlir::ValueRange{fieldIdx});
+    if (isPtrOrAlloc) {
+      // Target 1: pointer or allocatable component.
+      mlir::Value nullBox = fir::factory::createUnallocatedBox(
+          builder, loc, compFirTy, mlir::ValueRange{});
+      fir::StoreOp::create(builder, loc, nullBox, compAddr);
+    } else if (isNestedDerived) {
+      // Target 2: Nested derived type containing pointer/allocatable
+      // components.
+      auto nestedRecTy = mlir::cast<fir::RecordType>(compFirTy);
+      genDerivedTypeComponentInit(converter, loc, *declTy->AsDerived(),
+                                  compAddr, nestedRecTy);
+    }
+  }
+}
 
-    // Case A: Standard data components (ObjectEntityDetails).
-    if (objDetails) {
-      if (objDetails->init()) {
-        // Subcase A.1: Component has explicit initialization.
-        if (Fortran::semantics::IsPointer(compSym)) {
-          // Subcase A.1.1: Pointer with explicit target.
-          std::string globalName = fir::NameUniquer::doGenerated(
-              (converter.mangleName(derivedSpec) + fir::kNameSeparator + name +
-               fir::kNameSeparator + "init")
-                  .str());
-          fir::GlobalOp global = builder.getNamedGlobal(globalName);
-          if (!global) {
-            global = builder.createGlobal(loc, compFirTy, globalName,
-                                          builder.createInternalLinkage(),
-                                          mlir::Attribute{}, true);
-            createGlobalInitialization(
-                builder, global, [&](fir::FirOpBuilder &b) {
-                  mlir::Value initBox = Fortran::lower::genInitialDataTarget(
-                      converter, loc, compFirTy, *objDetails->init());
-                  fir::HasValueOp::create(b, loc, initBox);
-                });
+/// Checks if a derived type meets the criteria for component-wise
+/// initialization. The type must contain at least one pointer/allocatable
+/// component, and strictly NO explicit initialization anywhere in its
+/// hierarchy.
+static bool isEligibleForComponentWiseInit(
+    const Fortran::semantics::DerivedTypeSpec &derivedSpec) {
+  bool hasPtrOrAlloc = false;
+  auto checkImpl = [&](const Fortran::semantics::DerivedTypeSpec &spec,
+                       auto &self) -> bool {
+    const Fortran::semantics::Scope *scope = spec.scope();
+    assert(scope && "derived type has no scope");
+    const auto &typeDetails =
+        spec.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();
+      const auto *objDetails =
+          comp.detailsIf<Fortran::semantics::ObjectEntityDetails>();
+      const auto *procDetails =
+          comp.detailsIf<Fortran::semantics::ProcEntityDetails>();
+      // If any data component or procedure pointer has explicit
+      // initialization, abort and fall back to the global memcpy approach.
+      if ((objDetails && objDetails->init()) ||
+          (procDetails && procDetails->init())) {
+        return false;
+      }
+      if (Fortran::semantics::IsAllocatableOrPointer(comp)) {
+        hasPtrOrAlloc = true;
+        continue;
+      }
+      // Recursively traverse nested derived types.
+      if (const Fortran::semantics::DeclTypeSpec *declTy = comp.GetType()) {
+        if (const Fortran::semantics::DerivedTypeSpec *nestedSpec =
+                declTy->AsDerived()) {
+          // If it is an array of derived types that requires initialization,
+          // fall back to memcpy to avoid generating expensive runtime loops.
+          if (comp.Rank() > 0 &&
+              RequiresNonTrivialComponentInitialization(comp)) {
+            return false;
           }
-          auto srcAddr = fir::AddrOfOp::create(
-              builder, loc, global.resultType(), global.getSymbol());
-          mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
-          fir::StoreOp::create(builder, loc, loadedBox, compAddr);
-        } else {
-          // Subcase A.1.2: Non-pointer components with explicit initialization.
-          Fortran::lower::StatementContext stmtCtx(/*cleanupProhibited=*/true);
-          if (mlir::isa<fir::SequenceType>(compFirTy)) {
-            std::string globalName = fir::NameUniquer::doGenerated(
-                (converter.mangleName(derivedSpec) + fir::kNameSeparator +
-                 name + fir::kNameSeparator + "arr_init")
-                    .str());
-            fir::GlobalOp global = builder.getNamedGlobal(globalName);
-            if (!global) {
-              const auto &initExpr = objDetails->init().value();
-              cuf::DataAttributeAttr dataAttr = {};
-              global = Fortran::lower::tryCreatingDenseGlobal(
-                  builder, loc, compFirTy, globalName,
-                  builder.createInternalLinkage(), /*isConst=*/true, initExpr,
-                  dataAttr);
-            }
-            if (global) {
-              auto srcAddr = fir::AddrOfOp::create(
-                  builder, loc, global.resultType(), global.getSymbol());
-              fir::CopyOp::create(builder, loc, srcAddr, compAddr,
-                                  /*noOverlap=*/true);
-            } else {
-              Fortran::lower::StatementContext inlineCtx;
-              Fortran::lower::SymMap emptyMap;
-              hlfir::Entity lhs{compAddr};
-              hlfir::Entity rhs = Fortran::lower::convertExprToHLFIR(
-                  loc, converter, objDetails->init().value(), emptyMap,
-                  inlineCtx);
-              hlfir::AssignOp::create(builder, loc, rhs, lhs);
-            }
-          } else {
-            // Scalar component: Evaluate the expression and store directly.
-            fir::ExtendedValue exInitVal = genInitializerExprValue(
-                converter, loc, objDetails->init().value(), stmtCtx);
-            mlir::Value initVal = fir::getBase(exInitVal);
-            if (fir::isa_ref_type(initVal.getType()) &&
-                !fir::isa_ref_type(compFirTy))
-              initVal = fir::LoadOp::create(builder, loc, initVal);
-            mlir::Value castVal =
-                builder.createConvert(loc, compFirTy, initVal);
-            fir::StoreOp::create(builder, loc, castVal, compAddr);
+          if (!self(*nestedSpec, self)) {
+            return false;
           }
         }
-      } else if (Fortran::semantics::IsAllocatableOrPointer(compSym)) {
-        // Subcase A.2: Pointer or allocatable without initialization.
-        // Create deallocated/disassociated value.
-        std::string globalName = fir::NameUniquer::doGenerated(
-            (converter.mangleName(derivedSpec) + fir::kNameSeparator + name +
-             fir::kNameSeparator + "null_box")
-                .str());
-        fir::GlobalOp global = builder.getNamedGlobal(globalName);
-        if (!global) {
-          global = builder.createGlobal(loc, compFirTy, globalName,
-                                        builder.createInternalLinkage(),
-                                        mlir::Attribute{}, true);
-          createGlobalInitialization(
-              builder, global, [&](fir::FirOpBuilder &b) {
-                mlir::Value nullBox = fir::factory::createUnallocatedBox(
-                    b, loc, compFirTy, mlir::ValueRange{});
-                fir::HasValueOp::create(b, loc, nullBox);
-              });
-        }
-        auto srcAddr = fir::AddrOfOp::create(builder, loc, global.resultType(),
-                                             global.getSymbol());
-        mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
-        fir::StoreOp::create(builder, loc, loadedBox, compAddr);
-      } else if (Fortran::lower::hasDefaultInitialization(compSym)) {
-        // Subcase A.3: Nested derived type requires initialization.
-        // Derived type has no explicit initialization but contains
-        // components requiring initialization.
-        if (mlir::isa<fir::SequenceType>(compFirTy) &&
-            isComplexDerivedType(compSym)) {
-          // Complex derived type arrays.
-          mlir::Value box =
-              builder.createBox(loc, fir::ExtendedValue(compAddr));
-          fir::runtime::genDerivedTypeInitialize(builder, loc, box);
-        } else if (isComplexDerivedType(compSym)) {
-          // Complex derived type scalars.
-          const Fortran::semantics::DeclTypeSpec *compDeclTy =
-              compSym.GetType();
-          auto nestedRecTy = mlir::dyn_cast<fir::RecordType>(compFirTy);
-          genDerivedTypeComponentInit(converter, loc, *compDeclTy->AsDerived(),
-                                      compAddr, nestedRecTy);
-        } else {
-          // Simple derived type scalars.
-          Fortran::lower::StatementContext stmtCtx;
-          mlir::Value initVal = genDefaultInitializerValue(
-              converter, loc, compSym, compFirTy, stmtCtx);
-          mlir::Value castVal = builder.createConvert(loc, compFirTy, initVal);
-          fir::StoreOp::create(builder, loc, castVal, compAddr);
-        }
-      }
-    }
-    // Case B: Procedure pointers (ProcEntityDetails).
-    else if (procDetails) {
-      if (procDetails->init().has_value()) {
-        // Has a procedure or NULL() target.
-        std::string globalName = fir::NameUniquer::doGenerated(
-            (converter.mangleName(derivedSpec) + fir::kNameSeparator + name +
-             fir::kNameSeparator + "init")
-                .str());
-        fir::GlobalOp global = builder.getNamedGlobal(globalName);
-        if (!global) {
-          global = builder.createGlobal(loc, compFirTy, globalName,
-                                        builder.createInternalLinkage(),
-                                        mlir::Attribute{}, true);
-          createGlobalInitialization(
-              builder, global, [&](fir::FirOpBuilder &b) {
-                mlir::Value procBox;
-                auto targetSym = *procDetails->init();
-                if (targetSym) {
-                  procBox =
-                      Fortran::lower::convertProcedureDesignatorInitialTarget(
-                          converter, loc, *targetSym);
-                  procBox = b.createConvert(loc, compFirTy, procBox);
-                } else {
-                  procBox = fir::factory::createNullBoxProc(b, loc, compFirTy);
-                }
-                fir::HasValueOp::create(b, loc, procBox);
-              });
-        }
-        auto srcAddr = fir::AddrOfOp::create(builder, loc, global.resultType(),
-                                             global.getSymbol());
-        mlir::Value loadedBox = fir::LoadOp::create(builder, loc, srcAddr);
-        fir::StoreOp::create(builder, loc, loadedBox, compAddr);
-      } else {
-        // Has no initialization.
-        continue;
       }
     }
-  }
+    return true;
+  };
+  return checkImpl(derivedSpec, checkImpl) && hasPtrOrAlloc;
 }
-} // namespace
 
 /// Call default initialization runtime routine to initialize \p var.
 void Fortran::lower::defaultInitializeAtRuntime(
@@ -1083,7 +983,7 @@ void Fortran::lower::defaultInitializeAtRuntime(
     mlir::Type symTy = converter.genType(sym);
     const auto *details =
         sym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
-    bool useFastInit =
+    bool isDerivedTypeScalar =
         details && !Fortran::semantics::IsPolymorphic(sym) &&
         declTy->category() ==
             Fortran::semantics::DeclTypeSpec::Category::TypeDerived &&
@@ -1091,11 +991,11 @@ void Fortran::lower::defaultInitializeAtRuntime(
         !sym.test(Fortran::semantics::Symbol::Flag::OmpPrivate) &&
         !sym.test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate) &&
         !Fortran::semantics::HasCUDAComponent(sym);
-    if (useFastInit) {
-      if (enablePreciseInit) {
-        // Precise initialization
+    if (isDerivedTypeScalar) {
+      const auto &derivedSpec = *declTy->AsDerived();
+      if (isEligibleForComponentWiseInit(derivedSpec)) {
+        // Component-wise initialization
         mlir::Value baseAddr = fir::getBase(exv);
-        const auto &derivedSpec = *sym.GetType()->AsDerived();
         auto recTy = mlir::cast<fir::RecordType>(
             fir::unwrapPassByRefType(baseAddr.getType()));
         genDerivedTypeComponentInit(converter, loc, derivedSpec, baseAddr,
diff --git a/flang/test/Lower/component-wise-init.f90 b/flang/test/Lower/component-wise-init.f90
index 2b751e784dc47..99633062c7619 100644
--- a/flang/test/Lower/component-wise-init.f90
+++ b/flang/test/Lower/component-wise-init.f90
@@ -1,94 +1,111 @@
-! RUN: bbc -emit-fir -enable-precise-init %s -o - | FileCheck %s
+! RUN: bbc -emit-fir %s -o - | FileCheck %s
 
 ! Test for precise component-wise initialization of derived types
 ! to avoid generating large, fully-initialized global templates (sparse initialization).
 
 module my_types
-  type :: InnerType
-    integer :: flag = 42
+  ! Clean internal type: contains only allocatable and pointer components, 
+  ! without any explicit initialization.
+  type :: InnerClean
     real, pointer :: p
     real, allocatable :: arr(:)
-  end type InnerType
+  end type InnerClean
 
-  type :: OuterType
+  ! ============================================================================
+  ! Test Case 1: Type meeting all criteria for precise component-wise init (Target)
+  ! No arrays of derived types, no explicit initialization.
+  ! ============================================================================
+  type :: TargetType
     real, pointer :: q
-    integer :: explicit_arr(3) = [10, 20, 30]
-    real(8) :: uninit_buffer(80, 100, 100)
-    type(InnerType) :: nested
-    type(InnerType) :: nested_arr(2)
-  end type OuterType
+    real(8) :: uninit_buffer(80, 100)      ! Large uninitialized array; should be bypassed.
+    type(InnerClean) :: nested_scalar      ! Scalar derived type; should be expanded recursively.
+  end type TargetType
+
+  ! ============================================================================
+  ! Test Case 2: Type triggering fallback A (contains an array of derived type)
+  ! ============================================================================
+  type :: FallbackArrayType
+    type(InnerClean) :: nested_arr(10)     ! Array of derived type; must trigger fallback.
+  end type FallbackArrayType
+
+  ! ============================================================================
+  ! Test Case 3: Type triggering fallback B (contains explicit initialization)
+  ! ============================================================================
+  type :: FallbackExplicitType
+    real, pointer :: p
+    integer :: flag = 999                  ! Explicit initialization; must trigger gatekeeper!
+  end type FallbackExplicitType
 end module my_types
 
-subroutine test_complex_init()
-  use my_types
-  type(OuterType) :: my_var
-  call do_something(my_var)
-end subroutine test_complex_init
-
-! ==============================================================================
-! FileCheck Assertions
-! ==============================================================================
-
-! CHECK-LABEL: func.func @_QPtest_complex_init()
-
-! Ensure we allocate the local variable
-! CHECK: %[[MY_VAR:.*]] = fir.alloca !fir.type<_QMmy_typesToutertype{{.*}}>
 
 ! ------------------------------------------------------------------------------
-! 1. Check pointer 'q' initialization (First component, offset 0, no coordinate_of needed)
+! Test 1: FIR generation for precise component-wise initialization
 ! ------------------------------------------------------------------------------
-! CHECK: %[[Q_NULL_BOX_ADDR:.*]] = fir.address_of(@_QQ_QMmy_typesToutertype.q.{{(null_box|init)}})
-! CHECK: %[[Q_NULL_BOX:.*]] = fir.load %[[Q_NULL_BOX_ADDR]]
-! CHECK: fir.store %[[Q_NULL_BOX]] to %{{.*}}
+subroutine test_target()
+  use my_types
+  type(TargetType) :: my_var
+  call do_something_target(my_var)
+end subroutine test_target
 
-! ------------------------------------------------------------------------------
-! 2. Check explicit array initialization
-! ------------------------------------------------------------------------------
-! CHECK: %[[EXPLICIT_ARR_ADDR:.*]] = fir.coordinate_of %{{.*}}, explicit_arr
-! CHECK: %[[EXPLICIT_ARR_INIT:.*]] = fir.address_of(@_QQ_QMmy_typesToutertype.explicit_arr.arr_init)
-! CHECK: fir.copy %[[EXPLICIT_ARR_INIT]] to %[[EXPLICIT_ARR_ADDR]]
+! CHECK-LABEL: func.func @_QPtest_target()
+! Match the alloca and the subsequent declare
+! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.type<_QMmy_typesTtargettype{{.*}}>
+! CHECK: %[[MY_VAR:.*]] = fir.declare %[[ALLOCA]]
 
-! ------------------------------------------------------------------------------
-! 3. Check scalar derived type 'nested' component-wise precise initialization
-! ------------------------------------------------------------------------------
-! CHECK: %[[NESTED_ADDR:.*]] = fir.coordinate_of %{{.*}}, nested
+! 1. Check initialization of the outermost pointer 'q'
+! CHECK: %[[Q_ADDR:.*]] = fir.coordinate_of %[[MY_VAR]], q
+! CHECK: fir.store %{{.*}} to %[[Q_ADDR]]
 
-! -> Check 'flag' (integer = 42)
-! CHECK: %[[FLAG_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], flag
-! CHECK: fir.store %c42{{.*}} to %[[FLAG_ADDR]]
+! 2. Check recursive precise initialization of the scalar derived type 'nested_scalar'
+! CHECK: %[[NESTED_ADDR:.*]] = fir.coordinate_of %[[MY_VAR]], nested_scalar
 
-! -> Check 'p' (pointer)
+! -> Check internal pointer 'p'
 ! CHECK: %[[P_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], p
-! CHECK: %[[P_INIT_ADDR:.*]] = fir.address_of(@_QQ_QMmy_typesTinnertype.p.{{(null_box|init)}})
-! CHECK: %[[P_INIT_VAL:.*]] = fir.load %[[P_INIT_ADDR]]
-! CHECK: fir.store %[[P_INIT_VAL]] to %[[P_ADDR]]
+! CHECK: fir.store %{{.*}} to %[[P_ADDR]]
 
-! -> Check 'arr' (allocatable)
+! -> Check internal allocatable array 'arr'
 ! CHECK: %[[ARR_ADDR:.*]] = fir.coordinate_of %[[NESTED_ADDR]], arr
-! CHECK: %[[ARR_INIT_ADDR:.*]] = fir.address_of(@_QQ_QMmy_typesTinnertype.arr.null_box)
-! CHECK: %[[ARR_INIT_VAL:.*]] = fir.load %[[ARR_INIT_ADDR]]
-! CHECK: fir.store %[[ARR_INIT_VAL]] to %[[ARR_ADDR]]
+! CHECK: fir.store %{{.*}} to %[[ARR_ADDR]]
 
-! ------------------------------------------------------------------------------
-! 4. Check derived type array 'nested_arr' initialization (Runtime call)
-! ------------------------------------------------------------------------------
-! CHECK: %[[NESTED_ARR_ADDR:.*]] = fir.coordinate_of %{{.*}}, nested_arr
-! CHECK: %[[NESTED_ARR_BOX:.*]] = fir.embox %[[NESTED_ARR_ADDR]]
-! CHECK: %[[NESTED_ARR_PTR:.*]] = fir.convert %[[NESTED_ARR_BOX]]
-! CHECK: fir.call @_FortranAInitialize(%[[NESTED_ARR_PTR]], {{.*}})
+! CRITICAL 1: Ensure NO expensive runtime calls are generated.
+! CHECK-NOT: fir.call @_FortranAInitialize
+
+! CRITICAL 2: Ensure NO large global initialization templates are generated for TargetType.
+! CHECK-NOT: fir.global internal @_QQ_QMmy_typesTtargettype.DerivedInit
 
 
 ! ------------------------------------------------------------------------------
-! Global Variables Check
+! 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
 
-! CRITICAL: Ensure NO full derived type initialization templates are generated!
-! We should NOT see fir.global for the entire DerivedInit.
-! CHECK-NOT: fir.global internal @_QQ_QMmy_typesToutertype.DerivedInit
-! CHECK-NOT: fir.global internal @_QQ_QMmy_typesTinnertype.DerivedInit
+! CHECK-LABEL: func.func @_QPtest_fallback_array()
+! CHECK: %[[ALLOCA_ARR:.*]] = fir.alloca !fir.type<_QMmy_typesTfallbackarraytype{{.*}}>
+! CHECK: %[[VAR_ARRAY:.*]] = fir.declare %[[ALLOCA_ARR]]
+! 
+! Ensure FallbackArrayType falls back to the highly optimized memcpy from a global template,
+! entirely avoiding the runtime loop initialization.
+! CHECK: %[[GLOBAL_INIT_ARR:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackarraytype.DerivedInit)
+! CHECK: fir.copy %[[GLOBAL_INIT_ARR]] to %[[VAR_ARRAY]]
 
-! Verify the fine-grained component global constants exist
-! CHECK-DAG: fir.global internal @_QQ_QMmy_typesToutertype.explicit_arr.arr_init(dense<[10, 20, 30]> : tensor<3xi32>)
-! CHECK-DAG: fir.global internal @_QQ_QMmy_typesToutertype.q.{{(null_box|init)}}
-! CHECK-DAG: fir.global internal @_QQ_QMmy_typesTinnertype.p.{{(null_box|init)}}
-! CHECK-DAG: fir.global internal @_QQ_QMmy_typesTinnertype.arr.null_box
\ No newline at end of file
+
+! ------------------------------------------------------------------------------
+! Test 3: Fallback mechanism for explicit initialization
+! ------------------------------------------------------------------------------
+subroutine test_fallback_explicit()
+  use my_types
+  type(FallbackExplicitType) :: var_explicit
+  call do_something_explicit(var_explicit)
+end subroutine test_fallback_explicit
+
+! CHECK-LABEL: func.func @_QPtest_fallback_explicit()
+! CHECK: %[[ALLOCA_EXP:.*]] = fir.alloca !fir.type<_QMmy_typesTfallbackexplicittype{{.*}}>
+! CHECK: %[[VAR_EXPLICIT:.*]] = fir.declare %[[ALLOCA_EXP]]
+! 
+! Ensure types with explicit initialization trigger the gatekeeper and fall back to the old logic.
+! CHECK: %[[GLOBAL_INIT_EXP:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackexplicittype.DerivedInit)
+! CHECK: fir.copy %[[GLOBAL_INIT_EXP]] to %[[VAR_EXPLICIT]]
\ No newline at end of file

>From 364e5dc2722af774d8011b6dec6c6fc2842c184e Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Wed, 8 Apr 2026 19:11:22 +0800
Subject: [PATCH 5/7] Refactor derived type initialization and update tests.

---
 flang/lib/Lower/ConvertVariable.cpp           | 257 ++++++++----------
 .../Lower/HLFIR/structure-constructor.f90     | 215 +++++++++------
 .../Lower/OpenMP/private-derived-type.f90     |  12 +-
 flang/test/Lower/call-copy-in-out.f90         | 257 ++++++++++++++----
 flang/test/Lower/component-wise-init.f90      |   2 +-
 flang/test/Lower/default-initialization.f90   |  64 +++--
 .../test/Lower/derived-type-finalization.f90  | 111 +++++---
 flang/test/Lower/derived-type-temp.f90        |   8 +-
 .../Lower/forall/forall-allocatable-2.f90     |  75 ++---
 flang/test/Lower/pointer-default-init.f90     |   8 +-
 10 files changed, 606 insertions(+), 403 deletions(-)

diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 91b21e80621f3..767173f654e53 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -45,6 +45,8 @@
 #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 "llvm/ADT/SmallVector.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include <optional>
@@ -813,38 +815,6 @@ mustBeDefaultInitializedAtRuntime(const Fortran::lower::pft::Variable &var) {
   return Fortran::lower::hasDefaultInitialization(sym);
 }
 
-/// Determines whether a derived type component requires non-trivial
-/// initialization. A component requires non-trivial initialization if it is an
-/// allocatable or pointer data component, or if it is a nested derived type
-/// that contains such components.
-static bool RequiresNonTrivialComponentInitialization(
-    const Fortran::semantics::Symbol &sym) {
-  const Fortran::semantics::DeclTypeSpec *declTy = sym.GetType();
-  if (!declTy || !declTy->AsDerived())
-    return false;
-  const Fortran::semantics::DerivedTypeSpec &derivedSpec = *declTy->AsDerived();
-  const Fortran::semantics::Scope *scope = derivedSpec.GetScope();
-  assert(scope && "derived type has no scope");
-  const auto &typeDetails =
-      derivedSpec.typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
-
-  for (const auto &compName : typeDetails.componentNames()) {
-    auto iter = scope->find(compName);
-    assert(iter != scope->cend() && "component symbol not found in scope");
-    const Fortran::semantics::Symbol &compSym = iter->second.get();
-    const auto *objDetails =
-        compSym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
-    // If data component is an allocatable/pointer,
-    // or a nested derived type that requires initialization,
-    // return true.
-    if (objDetails && (Fortran::semantics::IsAllocatableOrPointer(compSym) ||
-                       RequiresNonTrivialComponentInitialization(compSym))) {
-      return true;
-    }
-  }
-  return false;
-}
-
 /// Performs component-wise initialization for \p derivedSpec,
 /// selectively generating IR only for components that require it.
 static void genDerivedTypeComponentInit(
@@ -852,81 +822,123 @@ static void genDerivedTypeComponentInit(
     const Fortran::semantics::DerivedTypeSpec &derivedSpec,
     mlir::Value baseAddr, fir::RecordType recTy) {
   fir::FirOpBuilder &builder = converter.getFirOpBuilder();
-  const Fortran::semantics::Scope *scope = derivedSpec.GetScope();
-  assert(scope && "derived type has no scope");
-  const auto &typeDetails =
-      derivedSpec.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 &compSym = scopeIter->second.get();
-    // Only process data components; procedure pointers are ignored.
-    const auto *objDetails =
-        compSym.detailsIf<Fortran::semantics::ObjectEntityDetails>();
-    if (!objDetails)
-      continue;
-
-    bool isPtrOrAlloc = Fortran::semantics::IsAllocatableOrPointer(compSym);
-    const Fortran::semantics::DeclTypeSpec *declTy = compSym.GetType();
-    bool isNestedDerived = declTy && declTy->AsDerived();
-    // Targets are pointer or allocatable components, or nested derived types
-    // containing them.
-    bool isTargetComponent =
-        isPtrOrAlloc ||
-        (isNestedDerived && RequiresNonTrivialComponentInitialization(compSym));
-    if (!isTargetComponent)
+  // 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;
+    if (!comp.has<Fortran::semantics::ObjectEntityDetails>() ||
+        !Fortran::semantics::IsAllocatableOrPointer(comp))
       continue;
-    std::string name = converter.getRecordTypeFieldName(compSym);
-    mlir::Type compFirTy = recTy.getType(name);
-    assert(compFirTy && "Component field type not found in RecordType");
-    // Compute the memory coordinate of the current component.
-    auto fieldIdx = fir::FieldIndexOp::create(
-        builder, loc, fir::FieldType::get(recTy.getContext()), name, recTy,
-        mlir::ValueRange{});
-    auto compAddr =
-        fir::CoordinateOp::create(builder, loc, builder.getRefType(compFirTy),
-                                  baseAddr, mlir::ValueRange{fieldIdx});
-    if (isPtrOrAlloc) {
-      // Target 1: pointer or allocatable component.
-      mlir::Value nullBox = fir::factory::createUnallocatedBox(
-          builder, loc, compFirTy, mlir::ValueRange{});
-      fir::StoreOp::create(builder, loc, nullBox, compAddr);
-    } else if (isNestedDerived) {
-      // Target 2: Nested derived type containing pointer/allocatable
-      // components.
-      auto nestedRecTy = mlir::cast<fir::RecordType>(compFirTy);
-      genDerivedTypeComponentInit(converter, loc, *declTy->AsDerived(),
-                                  compAddr, nestedRecTy);
+    // 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 nullBox = fir::factory::createUnallocatedBox(
+        builder, loc, finalCompFirTy, mlir::ValueRange{});
+    fir::StoreOp::create(builder, loc, nullBox, currentAddr);
   }
 }
 
-/// Checks if a derived type meets the criteria for component-wise
-/// initialization. The type must contain at least one pointer/allocatable
-/// component, and strictly NO explicit initialization anywhere in its
-/// hierarchy.
+/// 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 explicit
+/// default initializers.
 static bool isEligibleForComponentWiseInit(
     const Fortran::semantics::DerivedTypeSpec &derivedSpec) {
   bool hasPtrOrAlloc = false;
-  auto checkImpl = [&](const Fortran::semantics::DerivedTypeSpec &spec,
-                       auto &self) -> bool {
-    const Fortran::semantics::Scope *scope = spec.scope();
+  // 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 =
-        spec.typeSymbol().get<Fortran::semantics::DerivedTypeDetails>();
+        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 an explicit default initializer.
       const auto *objDetails =
           comp.detailsIf<Fortran::semantics::ObjectEntityDetails>();
       const auto *procDetails =
           comp.detailsIf<Fortran::semantics::ProcEntityDetails>();
-      // If any data component or procedure pointer has explicit
-      // initialization, abort and fall back to the global memcpy approach.
       if ((objDetails && objDetails->init()) ||
           (procDetails && procDetails->init())) {
         return false;
@@ -935,25 +947,23 @@ static bool isEligibleForComponentWiseInit(
         hasPtrOrAlloc = true;
         continue;
       }
-      // Recursively traverse nested derived types.
+      // Traverse nested derived types.
       if (const Fortran::semantics::DeclTypeSpec *declTy = comp.GetType()) {
         if (const Fortran::semantics::DerivedTypeSpec *nestedSpec =
                 declTy->AsDerived()) {
-          // If it is an array of derived types that requires initialization,
-          // fall back to memcpy to avoid generating expensive runtime loops.
-          if (comp.Rank() > 0 &&
-              RequiresNonTrivialComponentInitialization(comp)) {
-            return false;
-          }
-          if (!self(*nestedSpec, self)) {
-            return false;
+          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 true;
-  };
-  return checkImpl(derivedSpec, checkImpl) && hasPtrOrAlloc;
+  }
+  return hasPtrOrAlloc;
 }
 
 /// Call default initialization runtime routine to initialize \p var.
@@ -994,56 +1004,15 @@ void Fortran::lower::defaultInitializeAtRuntime(
     if (isDerivedTypeScalar) {
       const auto &derivedSpec = *declTy->AsDerived();
       if (isEligibleForComponentWiseInit(derivedSpec)) {
-        // Component-wise initialization
+        // 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 {
-        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);
-              });
-        }
-        auto addrOf = fir::AddrOfOp::create(builder, loc, global.resultType(),
-                                            global.getSymbol());
-        fir::CopyOp::create(builder, loc, addrOf, fir::getBase(exv),
-                            /*noOverlap=*/true);
+        // Initialize via bulk memory copy from a global constant.
+        genInlinedInitWithMemcpy(converter, sym, symTy, exv, details, declTy);
       }
     } else {
       mlir::Value box = builder.createBox(loc, exv);
diff --git a/flang/test/Lower/HLFIR/structure-constructor.f90 b/flang/test/Lower/HLFIR/structure-constructor.f90
index 094aeaa14f682..871bd645b41c3 100644
--- a/flang/test/Lower/HLFIR/structure-constructor.f90
+++ b/flang/test/Lower/HLFIR/structure-constructor.f90
@@ -38,12 +38,13 @@ end subroutine test1
 ! CHECK-LABEL:   func.func @_QPtest1(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.boxchar<1> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}> {bindc_name = "res", uniq_name = "_QFtest1Eres"}
 ! CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest1Eres"} : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>)
 ! CHECK:           %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,4>>
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_6]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest1Ex"} : (!fir.ref<!fir.char<1,4>>, index, !fir.dscope) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
+! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_6]] dummy_scope %[[SCOPE]] arg 1 {uniq_name = "_QFtest1Ex"} : (!fir.ref<!fir.char<1,4>>, index, !fir.dscope) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
 ! CHECK:           %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>)
 ! CHECK:           %[[VAL_9:.*]] = fir.embox %[[VAL_8]]#0 : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> !fir.box<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
 ! CHECK:           %[[VAL_10:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -51,9 +52,9 @@ end subroutine test1
 ! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> !fir.box<none>
 ! CHECK:           %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
 ! CHECK:           fir.call @_FortranAInitialize(%[[VAL_12]], %[[VAL_13]], %[[VAL_11]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_15:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_8]]#0{"c"}   typeparams %[[VAL_15]] : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, index) -> !fir.ref<!fir.char<1,4>>
-! CHECK:           hlfir.assign %[[VAL_7]]#0 to %[[VAL_16]] temporary_lhs : !fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
+! CHECK:           %[[VAL_14:.*]] = arith.constant 4 : index
+! CHECK:           %[[VAL_15:.*]] = hlfir.designate %[[VAL_8]]#0{"c"}   typeparams %[[VAL_14]] : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, index) -> !fir.ref<!fir.char<1,4>>
+! CHECK:           hlfir.assign %[[VAL_7]]#0 to %[[VAL_15]] temporary_lhs : !fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
 ! CHECK:           hlfir.assign %[[VAL_8]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
 ! CHECK:           return
 ! CHECK:         }
@@ -67,11 +68,12 @@ end subroutine test2
 ! CHECK-LABEL:   func.func @_QPtest2(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt2{i:!fir.array<10xi32>}> {bindc_name = "res", uniq_name = "_QFtest2Eres"}
 ! CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest2Eres"} : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>)
 ! CHECK:           %[[VAL_4:.*]] = arith.constant 10 : index
 ! CHECK:           %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
-! CHECK:           %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_5]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK:           %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_5]]) dummy_scope %[[SCOPE]] arg 1 {uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>)
 ! CHECK:           %[[VAL_8:.*]] = fir.embox %[[VAL_7]]#0 : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> !fir.box<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>
 ! CHECK:           %[[VAL_9:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -79,10 +81,10 @@ end subroutine test2
 ! CHECK:           %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> !fir.box<none>
 ! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
 ! CHECK:           fir.call @_FortranAInitialize(%[[VAL_11]], %[[VAL_12]], %[[VAL_10]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_14:.*]] = arith.constant 10 : index
-! CHECK:           %[[VAL_15:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1>
-! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0{"i"} <%[[VAL_15]]>   shape %[[VAL_15]] : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.shape<1>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
-! CHECK:           hlfir.assign %[[VAL_6]]#0 to %[[VAL_16]] temporary_lhs : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>
+! CHECK:           %[[VAL_13:.*]] = arith.constant 10 : index
+! CHECK:           %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
+! CHECK:           %[[VAL_15:.*]] = hlfir.designate %[[VAL_7]]#0{"i"} <%[[VAL_14]]>   shape %[[VAL_14]] : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.shape<1>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK:           hlfir.assign %[[VAL_6]]#0 to %[[VAL_15]] temporary_lhs : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>
 ! CHECK:           hlfir.assign %[[VAL_7]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>
 ! CHECK:           return
 ! CHECK:         }
@@ -96,26 +98,31 @@ end subroutine test3
 ! CHECK-LABEL:   func.func @_QPtest3(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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_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>>>}>>
-! CHECK:           %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
-! CHECK:           %[[VAL_14:.*]] = arith.constant {{[0-9]*}} : i32
-! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<none>
-! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
-! CHECK:           fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"r"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           %[[VAL_19:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           %[[VAL_20:.*]] = arith.constant 0 : index
-! CHECK:           %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_19]], %[[VAL_20]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
-! CHECK:           %[[VAL_22:.*]] = fir.shift %[[VAL_21]]#0 : (index) -> !fir.shift<1>
-! CHECK:           %[[VAL_23:.*]] = fir.rebox %[[VAL_19]](%[[VAL_22]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
-! CHECK:           fir.store %[[VAL_23]] to %[[VAL_18]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#0 : !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_9:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] arg 1 {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_10:.*]]: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_11:.*]] = fir.embox %[[VAL_10]]#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>>>}>>
+! CHECK:           %[[VAL_12:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
+! CHECK:           %[[VAL_13:.*]] = arith.constant {{[0-9]*}} : i32
+! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<none>
+! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+! CHECK:           fir.call @_FortranAInitialize(%[[VAL_14]], %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_10]]#0{"r"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           %[[VAL_17:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           %[[VAL_18:.*]] = arith.constant 0 : index
+! CHECK:           %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_17]], %[[VAL_18]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK:           %[[VAL_20:.*]] = fir.shift %[[VAL_19]]#0 : (index) -> !fir.shift<1>
+! CHECK:           %[[VAL_21:.*]] = fir.rebox %[[VAL_17]](%[[VAL_20]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK:           fir.store %[[VAL_21]] to %[[VAL_16]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           hlfir.assign %[[VAL_10]]#0 to %[[VAL_3]]#0 : !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:           return
 ! CHECK:         }
 
@@ -128,37 +135,41 @@ end subroutine test4
 ! CHECK-LABEL:   func.func @_QPtest4(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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_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>>>>}>>)
-! CHECK:           %[[VAL_13:.*]] = fir.embox %[[VAL_12]]#0 : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
-! CHECK:           %[[VAL_14:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
-! CHECK:           %[[VAL_15:.*]] = arith.constant {{[0-9]*}} : i32
-! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
-! CHECK:           %[[VAL_17:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
-! CHECK:           fir.call @_FortranAInitialize(%[[VAL_16]], %[[VAL_17]], %[[VAL_15]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_19:.*]] = arith.constant 2 : index
-! CHECK:           %[[VAL_20:.*]] = hlfir.designate %[[VAL_12]]#0{"c"}   typeparams %[[VAL_19]] {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
-! CHECK:           %[[VAL_21:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
-! CHECK:           %[[VAL_22:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,2>>>
-! CHECK:           %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.heap<!fir.array<?x!fir.char<1,2>>>) -> i64
-! CHECK:           %[[VAL_24:.*]] = arith.constant 0 : i64
-! CHECK:           %[[VAL_25:.*]] = arith.cmpi ne, %[[VAL_23]], %[[VAL_24]] : i64
-! CHECK:           fir.if %[[VAL_25]] {
-! CHECK:             %[[VAL_26:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
-! CHECK:             hlfir.assign %[[VAL_26]] to %[[VAL_20]] realloc keep_lhs_len temporary_lhs : !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_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_9:.*]] = arith.constant 2 : index
+! CHECK:           %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_9]] dummy_scope %[[SCOPE]] arg 1 {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_11:.*]]: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>>>>}>>)
+! CHECK:           %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
+! CHECK:           %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
+! CHECK:           %[[VAL_14:.*]] = arith.constant {{[0-9]*}} : i32
+! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
+! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+! CHECK:           fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:           %[[VAL_17:.*]] = arith.constant 2 : index
+! CHECK:           %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"c"}   typeparams %[[VAL_17]] {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK:           %[[VAL_19:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK:           %[[VAL_20:.*]] = fir.box_addr %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,2>>>
+! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.char<1,2>>>) -> i64
+! CHECK:           %[[VAL_22:.*]] = arith.constant 0 : i64
+! CHECK:           %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
+! CHECK:           fir.if %[[VAL_23]] {
+! CHECK:             %[[VAL_24:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK:             hlfir.assign %[[VAL_24]] to %[[VAL_18]] realloc keep_lhs_len temporary_lhs : !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:           }
-! CHECK:           hlfir.assign %[[VAL_12]]#0 to %[[VAL_3]]#0 : !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_27:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_27]]
+! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#0 : !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_25:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_25]])
 ! CHECK:           return
 ! CHECK:         }
 
-
 subroutine test5(x)
   use types
   type(t4), allocatable :: x(:)
@@ -168,31 +179,36 @@ end subroutine test5
 ! CHECK-LABEL:   func.func @_QPtest5(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !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.bindc_name = "x"}) {
 ! 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:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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_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>>>>}>>>>}>>
-! CHECK:           %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
-! CHECK:           %[[VAL_14:.*]] = arith.constant {{[0-9]*}} : i32
-! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
-! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
-! CHECK:           fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"t5m"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_19:.*]] = fir.load %[[VAL_10]]#0 : !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:.*]] = fir.box_addr %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>) -> !fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>
-! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>) -> i64
-! CHECK:           %[[VAL_22:.*]] = arith.constant 0 : i64
-! CHECK:           %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
-! CHECK:           fir.if %[[VAL_23]] {
-! CHECK:             %[[VAL_24:.*]] = fir.load %[[VAL_10]]#0 : !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:             hlfir.assign %[[VAL_24]] to %[[VAL_18]] realloc temporary_lhs : !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_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_9:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] arg 1 {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_10:.*]]: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_11:.*]] = fir.embox %[[VAL_10]]#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>>>>}>>>>}>>
+! CHECK:           %[[VAL_12:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
+! CHECK:           %[[VAL_13:.*]] = arith.constant {{[0-9]*}} : i32
+! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_11]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
+! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+! CHECK:           fir.call @_FortranAInitialize(%[[VAL_14]], %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_10]]#0{"t5m"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_17:.*]] = fir.load %[[VAL_9]]#0 : !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_18:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>) -> !fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>
+! CHECK:           %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>) -> i64
+! CHECK:           %[[VAL_20:.*]] = arith.constant 0 : i64
+! CHECK:           %[[VAL_21:.*]] = arith.cmpi ne, %[[VAL_19]], %[[VAL_20]] : i64
+! CHECK:           fir.if %[[VAL_21]] {
+! CHECK:             %[[VAL_22:.*]] = fir.load %[[VAL_9]]#0 : !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:             hlfir.assign %[[VAL_22]] to %[[VAL_16]] realloc temporary_lhs : !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:           }
-! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#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.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_24:.*]] = fir.convert %[[VAL_12]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_24]]
+! CHECK:           hlfir.assign %[[VAL_10]]#0 to %[[VAL_3]]#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.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_23:.*]] = fir.convert %[[VAL_11]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_23]])
 ! CHECK:           return
 ! CHECK:         }
 
@@ -211,15 +227,21 @@ end subroutine test6
 ! CHECK:           %[[VAL_4:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>> {bindc_name = ".tmp.arrayctor"}
 ! CHECK:           %[[VAL_5:.*]] = 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_6:.*]] = 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>}>>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_7:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK:           %[[VAL_8:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,4>>
 ! CHECK:           %[[VAL_9:.*]] = arith.constant 4 : index
-! 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_10:.*]]:2 = hlfir.declare %[[VAL_8]] typeparams %[[VAL_9]] dummy_scope %[[SCOPE]] arg 2 {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_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_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 %[[SCOPE]] arg 1 {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>}>>}>>
 ! CHECK:           %[[VAL_22:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -279,9 +301,9 @@ end subroutine test6
 ! CHECK:           hlfir.assign %[[VAL_70]] to %[[VAL_44]] temporary_lhs : !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>
 ! CHECK:           hlfir.assign %[[VAL_20]]#0 to %[[VAL_12]]#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.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_71:.*]] = fir.convert %[[VAL_21]] : (!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>}>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_71]]
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_71]])
 ! CHECK:           %[[VAL_72:.*]] = fir.convert %[[VAL_29]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_72]]
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_72]])
 ! CHECK:           return
 ! CHECK:         }
 
@@ -299,11 +321,16 @@ end subroutine test7
 ! CHECK-LABEL:   func.func @_QPtest7(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
-! 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:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] arg 1 {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 +342,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:         }
 
@@ -328,10 +357,13 @@ subroutine test8
 end subroutine test8
 ! CHECK-LABEL:   func.func @_QPtest8() {
 ! CHECK:           %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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>>
@@ -359,7 +391,7 @@ end subroutine test8
 ! CHECK:           }
 ! CHECK:           hlfir.assign %[[VAL_14]]#0 to %[[VAL_2]]#0 : !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_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_30]]
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_30]])
 ! CHECK:           return
 ! CHECK:         }
 
@@ -373,10 +405,13 @@ subroutine test9
 end subroutine test9
 ! CHECK-LABEL:   func.func @_QPtest9() {
 ! CHECK:           %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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>>)
@@ -392,11 +427,10 @@ end subroutine test9
 ! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_20]] realloc keep_lhs_len temporary_lhs : !fir.ref<!fir.char<1,12>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
 ! CHECK:           hlfir.assign %[[VAL_12]]#0 to %[[VAL_2]]#0 : !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_21:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_21]]
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_21]])
 ! CHECK:           return
 ! CHECK:         }
 
-
 ! Test character non-allocatable component initialization
 ! from character allocatable of different size.
 subroutine test10
@@ -407,6 +441,7 @@ subroutine test10
 end subroutine test10
 ! CHECK-LABEL:   func.func @_QPtest10() {
 ! CHECK:           %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}>
+! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}> {bindc_name = "res", uniq_name = "_QFtest10Eres"}
 ! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest10Eres"} : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>)
 ! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,12>>> {bindc_name = "x", uniq_name = "_QFtest10Ex"}
diff --git a/flang/test/Lower/OpenMP/private-derived-type.f90 b/flang/test/Lower/OpenMP/private-derived-type.f90
index 3947a0d68b58c..fef0867045703 100644
--- a/flang/test/Lower/OpenMP/private-derived-type.f90
+++ b/flang/test/Lower/OpenMP/private-derived-type.f90
@@ -16,12 +16,12 @@ subroutine s4
 end subroutine s4
 
 ! CHECK:  omp.private {type = private} @[[DERIVED_PRIV:.*]] : !fir.type<{{.*}}y3{x:!fir.box<!fir.heap<i32>>}> init {
-! CHECK:             %[[VAL_25:.*]] = fir.embox %[[VAL_23:.*]] : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
+! CHECK:             %[[VAL_25:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
 ! CHECK:             %[[VAL_26:.*]] = fir.address_of
 ! CHECK:             %[[VAL_27:.*]] = arith.constant 8 : i32
 ! CHECK:             %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<none>
 ! CHECK:             %[[VAL_29:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-!                    Check we do call FortranAInitialize on the derived type
+! Check we do call FortranAInitialize on the derived type
 ! CHECK:             fir.call @_FortranAInitialize(%[[VAL_28]], %[[VAL_29]], %[[VAL_27]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
 ! CHECK:  }
 
@@ -29,14 +29,16 @@ 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:           }
 ! CHECK:           %[[VAL_39:.*]] = fir.embox %[[VAL_DERIVED_DECLARE]]#0 : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
 ! CHECK:           %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (!fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<none>
-!                  Check the derived type is destroyed
+! Check the derived type is destroyed
 ! CHECK:           fir.call @_FortranADestroy(%[[VAL_40]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:           return
 ! CHECK:         }
diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90
index fa2182ac11bac..c35a998b738a4 100644
--- a/flang/test/Lower/call-copy-in-out.f90
+++ b/flang/test/Lower/call-copy-in-out.f90
@@ -1,60 +1,107 @@
 ! Test copy-in / copy-out of non-contiguous variable passed as F77 array arguments.
-! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
+! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
 
 ! Nominal test
 ! CHECK-LABEL: func @_QPtest_assumed_shape_to_array(
 ! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_assumed_shape_to_array(x)
   real :: x(:)
-! CHECK: %[[x_decl:.*]]:2 = hlfir.declare %[[x]]
-! CHECK: %[[copy_in:.*]]:2 = hlfir.copy_in %[[x_decl]]#0 {{.*}}
-! CHECK: %[[addr:.*]] = fir.box_addr %[[copy_in]]#0
-! CHECK: fir.call @_QPbar(%[[addr]])
-! CHECK: hlfir.copy_out %{{.*}}, %[[copy_in]]#1 to %[[x_decl]]#0
+
+! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
+! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]] -> (!fir.heap<!fir.array<?xf32>>) {
+! CHECK:   %[[box_addr:.*]] = fir.box_addr %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.heap<!fir.array<?xf32>>
+! CHECK:   fir.result %[[box_addr]] : !fir.heap<!fir.array<?xf32>>
+! CHECK: } else {
+! Creating temp
+! CHECK:  %[[dim:.*]]:3 = fir.box_dims %[[x:.*]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK:  %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1 {uniq_name = ".copyinout"}
+
+! Copy-in
+! CHECK-DAG:  %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
+! CHECK-DAG:  %[[temp_box:.*]] = fir.embox %[[temp]](%[[shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK-DAG:  fir.store %[[temp_box]] to %[[temp_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
+! CHECK-DAG: %[[temp_box_addr:.*]] = fir.convert %[[temp_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
+! CHECK-DAG: %[[arg_box:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+! CHECK-DAG: fir.call @_FortranAAssignTemporary(%[[temp_box_addr]], %[[arg_box]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:  fir.result %[[temp]] : !fir.heap<!fir.array<?xf32>>
+
+! CHECK:  %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+! CHECK:  fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
+
+! Copy-out
+! CHECK-DAG:  %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
+! CHECK-DAG:  %[[temp_box:.*]] = fir.embox %[[addr]](%[[shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:  %[[rebox:.*]] = fir.rebox %[[temp_box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK:  fir.store %[[rebox]] to %[[temp_box_ref:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK-DAG:  fir.store %[[x]] to %[[arg_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
+! CHECK-DAG: %[[arg_box_addr:.*]] = fir.convert %[[arg_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
+! CHECK-DAG: %[[temp_box_cast:.*]] = fir.convert %[[temp_box_ref]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK-DAG: fir.call @_FortranACopyOutAssign(%[[arg_box_addr]], %[[temp_box_cast]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<i8>, i32) -> ()
+
   call bar(x)
 end subroutine
 
 ! Test that copy-in/copy-out does not trigger the re-evaluation of
 ! the designator expression.
 ! CHECK-LABEL: func @_QPeval_expr_only_once(
+! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.array<200xf32>>{{.*}}) {
 subroutine eval_expr_only_once(x)
   integer :: only_once
   real :: x(200)
 ! CHECK: fir.call @_QPonly_once()
-! CHECK: hlfir.designate
-! CHECK: hlfir.copy_in
-! CHECK-NOT: fir.call @_QPonly_once()
-! CHECK: fir.call @_QPbar
+! CHECK: %[[x_section:.*]] = fir.embox %[[x]](%{{.*}}) [%{{.*}}] : (!fir.ref<!fir.array<200xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: %[[box_none:.*]] = fir.convert %[[x_section]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
+! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]] -> (!fir.heap<!fir.array<?xf32>>) {
+
+! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>
 ! CHECK-NOT: fir.call @_QPonly_once()
-! CHECK: hlfir.copy_out
+! CHECK:  fir.call @_FortranAAssignTemporary
 ! CHECK-NOT: fir.call @_QPonly_once()
+
+! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+! CHECK:  fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
   call bar(x(1:200:only_once()))
+
+! CHECK-NOT: fir.call @_QPonly_once()
+! CHECK:  fir.call @_FortranACopyOutAssign
+! CHECK-NOT: fir.call @_QPonly_once()
+
 end subroutine
 
 ! Test no copy-in/copy-out is generated for contiguous assumed shapes.
 ! CHECK-LABEL: func @_QPtest_contiguous(
+! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.array<?xf32>>
 subroutine test_contiguous(x)
   real, contiguous :: x(:)
-! CHECK-NOT: hlfir.copy_in
-! CHECK: fir.call @_QPbar
-! CHECK-NOT: hlfir.copy_out
+! CHECK: %[[addr:.*]] = fir.box_addr %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+! CHECK-NOT:  fir.call @_FortranAAssignTemporary
+! CHECK: fir.call @_QPbar(%[[addr]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
   call bar(x)
+! CHECK-NOT:  fir.call @_FortranACopyOutAssign
+! CHECK: return
 end subroutine
 
 ! Test the parenthesis are preventing copy-out.
-! CHECK-LABEL: func @_QPtest_parenthesis(
+! CHECK: func @_QPtest_parenthesis(
+! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_parenthesis(x)
   real :: x(:)
-! CHECK: hlfir.elemental
-! CHECK: hlfir.associate
-! CHECK: fir.call @_QPbar
-! CHECK: hlfir.end_associate
-! CHECK-NOT: hlfir.copy_out
+! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1 {uniq_name = ".array.expr"}
+! CHECK:  fir.array_merge_store %{{.*}}, %{{.*}} to %[[temp]]
+! CHECK:  %[[cast:.*]] = fir.convert %[[temp]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
+! CHECK:  fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
   call bar((x))
+! CHECK-NOT:  fir.call @_FortranACopyOutAssign
+! CHECK: return
 end subroutine
 
 ! Test copy-in in is skipped for intent(out) arguments.
-! CHECK-LABEL: func @_QPtest_intent_out(
+! CHECK: func @_QPtest_intent_out(
+! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_intent_out(x)
   real :: x(:)
   interface
@@ -62,14 +109,26 @@ subroutine bar_intent_out(x)
     real, intent(out) :: x(100)
   end subroutine
   end interface
-! CHECK: hlfir.copy_in
-! CHECK: fir.call @_QPbar_intent_out
-! CHECK: hlfir.copy_out
+! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
+! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]]
+! CHECK: } else {
+! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1
+! CHECK-NOT:  fir.call @_FortranAAssignTemporary
+! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
+! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK:  fir.call @_QPbar_intent_out(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
   call bar_intent_out(x)
+
+! CHECK: fir.if %[[not_contiguous]]
+! CHECK: fir.call @_FortranACopyOutAssign
+! CHECK: return
 end subroutine
 
 ! Test copy-out is skipped for intent(out) arguments.
 ! CHECK-LABEL: func.func @_QPtest_intent_in(
+! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_intent_in(x)
   real :: x(:)
   interface
@@ -77,15 +136,30 @@ subroutine bar_intent_in(x)
     real, intent(in) :: x(100)
   end subroutine
   end interface
-! CHECK: hlfir.copy_in
-! CHECK: fir.call @_QPbar_intent_in
-! CHECK: hlfir.copy_out
-! CHECK-SAME: ) -> ()
+! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
+! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]]
+! CHECK: } else {
+! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1
+! CHECK: %[[temp_shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[temp_box:.*]] = fir.embox %[[temp]](%[[temp_shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK: fir.store %[[temp_box]] to %[[temp_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
+! CHECK: %[[temp_box_addr:.*]] = fir.convert %[[temp_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: fir.call @_FortranAAssignTemporary(%[[temp_box_addr]],
+! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
+! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK:  fir.call @_QPbar_intent_in(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
   call bar_intent_in(x)
+! CHECK: fir.if %[[not_contiguous]]
+! CHECK: fir.zero
+! CHECK:  fir.call @_FortranACopyOutAssign
+! CHECK: return
 end subroutine
 
 ! Test copy-in/copy-out is done for intent(inout)
-! CHECK-LABEL: func @_QPtest_intent_inout(
+! CHECK: func @_QPtest_intent_inout(
+! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_intent_inout(x)
   real :: x(:)
   interface
@@ -93,55 +167,111 @@ subroutine bar_intent_inout(x)
     real, intent(inout) :: x(100)
   end subroutine
   end interface
-! CHECK: hlfir.copy_in
-! CHECK: fir.call @_QPbar_intent_inout
-! CHECK: hlfir.copy_out
-! CHECK-SAME: to
+! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
+! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
+! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]]
+! CHECK: } else {
+! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1
+! CHECK:  fir.call @_FortranAAssign
+! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
+! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
+! CHECK:  fir.call @_QPbar_intent_inout(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
   call bar_intent_inout(x)
+! CHECK: fir.if %[[not_contiguous]]
+! CHECK:  fir.call @_FortranACopyOutAssign
+! CHECK: return
 end subroutine
 
 ! Test characters are handled correctly
 ! CHECK-LABEL: func @_QPtest_char(
+! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,10>>>{{.*}}) {
 subroutine test_char(x)
+! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.array<?x!fir.char<1,10>>>
+! CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.array<?x!fir.char<1,10>>>
+! CHECK:           %[[VAL_3:.*]] = arith.constant 10 : index
+! CHECK:           %[[VAL_4:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<none>
+! CHECK:           %[[VAL_5:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_4]]) fastmath<contract> : (!fir.box<none>) -> i1
+! CHECK:           %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.heap<!fir.array<?x!fir.char<1,10>>>) {
+! CHECK:             %[[VAL_7:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x!fir.char<1,10>>>
+! CHECK:             fir.result %[[VAL_7]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>
+! CHECK:           } else {
+! CHECK:             %[[VAL_8:.*]] = arith.constant 0 : index
+! CHECK:             %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>, index) -> (index, index, index)
+! CHECK:             %[[VAL_10:.*]] = fir.allocmem !fir.array<?x!fir.char<1,10>>, %[[VAL_9]]#1 {uniq_name = ".copyinout"}
+! CHECK:             %[[VAL_11:.*]] = fir.shape %[[VAL_9]]#1 : (index) -> !fir.shape<1>
+! CHECK:             %[[VAL_12:.*]] = fir.embox %[[VAL_10]](%[[VAL_11]]) : (!fir.heap<!fir.array<?x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,10>>>
+! CHECK:             fir.store %[[VAL_12]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>
+! CHECK:             %[[VAL_15:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK:             %[[VAL_16:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<none>
+! CHECK:             fir.call @_FortranAAssignTemporary(%[[VAL_15]], %[[VAL_16]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:             fir.result %[[VAL_10]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>
+! CHECK:           }
+! CHECK:           %[[VAL_19:.*]] = arith.constant 0 : index
+! CHECK:           %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>, index) -> (index, index, index)
+! CHECK:           %[[VAL_21:.*]] = arith.constant false
+! CHECK:           %[[VAL_22:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_21]] : i1
+! CHECK:           %[[VAL_23:.*]] = fir.convert %[[VAL_24:.*]] : (!fir.heap<!fir.array<?x!fir.char<1,10>>>) -> !fir.ref<!fir.char<1,?>>
+! CHECK:           %[[VAL_25:.*]] = fir.emboxchar %[[VAL_23]], %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+! CHECK:           fir.call @_QPbar_char(%[[VAL_25]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
+! CHECK:           fir.if %[[VAL_22]] {
+! CHECK:             %[[VAL_26:.*]] = fir.shape %[[VAL_20]]#1 : (index) -> !fir.shape<1>
+! CHECK:             %[[VAL_27:.*]] = fir.embox %[[VAL_24]](%[[VAL_26]]) : (!fir.heap<!fir.array<?x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,10>>>
+! CHECK:             %[[REBOX:.*]] = fir.rebox %[[VAL_27]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>
+! CHECK:             fir.store %[[REBOX]] to %[[TMP_BOX_REF:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
+! CHECK:             fir.store %[[VAL_0]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>
+! CHECK:             %[[VAL_31:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK:             %[[VAL_32:.*]] = fir.convert %[[TMP_BOX_REF]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK:             fir.call @_FortranACopyOutAssign(%[[VAL_31]], %[[VAL_32]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<i8>, i32) -> ()
+! CHECK:           }
+
   character(10) :: x(:)
-! CHECK: hlfir.copy_in
-! CHECK: fir.call @_QPbar_char
-! CHECK: hlfir.copy_out
   call bar_char(x)
+  ! CHECK:         return
+  ! CHECK:       }
 end subroutine test_char
 
 ! CHECK-LABEL: func @_QPtest_scalar_substring_does_no_trigger_copy_inout
+! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>
 subroutine test_scalar_substring_does_no_trigger_copy_inout(c, i, j)
   character(*) :: c
   integer :: i, j
-  ! CHECK: hlfir.designate
-  ! CHECK-NOT: hlfir.copy_in
-  ! CHECK: fir.call @_QPbar_char_2
-  ! CHECK-NOT: hlfir.copy_out
+  ! CHECK: %[[unbox:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
+  ! CHECK: %[[c:.*]] = fir.convert %[[unbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
+  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[c]], %{{.*}} : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
+  ! CHECK: %[[substr:.*]] = fir.convert %[[coor]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
+  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[substr]], %{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+  ! CHECK: fir.call @_QPbar_char_2(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
   call bar_char_2(c(i:j))
 end subroutine
 
 ! CHECK-LABEL: func @_QPissue871(
+! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.type<_QFissue871Tt{i:i32}>>>>{{.*}})
 subroutine issue871(p)
   ! Test passing implicit derived from scalar pointer (no copy-in/out).
   type t
     integer :: i
   end type t
   type(t), pointer :: p
-  ! CHECK-NOT: hlfir.copy_in
-  ! CHECK: fir.call @_QPbar_derived
+  ! CHECK: %[[box_load:.*]] = fir.load %[[p]]
+  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]]
+  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
+  ! CHECK: fir.call @_QPbar_derived(%[[cast]])
   call bar_derived(p)
 end subroutine
 
 ! CHECK-LABEL: func @_QPissue871_array(
+! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue871_arrayTt{i:i32}>>>>>
 subroutine issue871_array(p)
   ! Test passing implicit derived from contiguous pointer (no copy-in/out).
   type t
     integer :: i
   end type t
   type(t), pointer, contiguous :: p(:)
-  ! CHECK-NOT: hlfir.copy_in
-  ! CHECK: fir.call @_QPbar_derived_array
+  ! CHECK: %[[box_load:.*]] = fir.load %[[p]]
+  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]]
+  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
+  ! CHECK: fir.call @_QPbar_derived_array(%[[cast]])
   call bar_derived_array(p)
 end subroutine
 
@@ -151,10 +281,10 @@ subroutine whole_components()
   type t
     integer :: i(100)
   end type
+  ! CHECK: %[[a:.*]] = fir.alloca !fir.type<_QFwhole_componentsTt{i:!fir.array<100xi32>}>
   type(t) :: a
-  ! CHECK: hlfir.designate
-  ! CHECK-NOT: hlfir.copy_in
-  ! CHECK: fir.call @_QPbar_integer
+  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_componentsTt{i:!fir.array<100xi32>}>>) -> !fir.ref<!fir.array<100xi32>>
+  ! CHECK: fir.call @_QPbar_integer(%[[addr]]) {{.*}}: (!fir.ref<!fir.array<100xi32>>) -> ()
   call bar_integer(a%i)
 end subroutine
 
@@ -164,10 +294,19 @@ subroutine whole_component_contiguous_pointer()
   type t
     integer, pointer, contiguous :: i(:)
   end type
+  ! CHECK: %[[a:.*]] = fir.alloca !fir.type<_QFwhole_component_contiguous_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>
   type(t) :: a
-  ! CHECK: hlfir.designate
-  ! CHECK-NOT: hlfir.copy_in
-  ! CHECK: fir.call @_QPbar_integer
+  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+  ! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
+  ! 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<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
+  ! CHECK: fir.store %[[embox]] to %[[coor]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+  ! CHECK: %[[coor2:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+  ! CHECK: %[[box_load:.*]] = fir.load %[[coor2]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
+  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
+  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.ref<!fir.array<100xi32>>
+  ! CHECK: fir.call @_QPbar_integer(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xi32>>) -> ()
   call bar_integer(a%i)
 end subroutine
 
@@ -177,9 +316,21 @@ subroutine whole_component_contiguous_char_pointer()
   type t
     character(:), pointer, contiguous :: i(:)
   end type
+  ! CHECK: %[[a:.*]] = fir.alloca !fir.type<_QFwhole_component_contiguous_char_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>
   type(t) :: a
-  ! CHECK: hlfir.designate
-  ! CHECK-NOT: hlfir.copy_in
-  ! CHECK: fir.call @_QPbar_char_3
+  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_char_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
+  ! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.array<?x!fir.char<1,?>>>
+  ! CHECK: %[[c0_1:.*]] = arith.constant 0 : index
+  ! CHECK: %[[shape:.*]] = fir.shape %[[c0_1]] : (index) -> !fir.shape<1>
+  ! CHECK: %[[c0_2:.*]] = arith.constant 0 : index
+  ! CHECK: %[[embox:.*]] = fir.embox %[[zero]](%[[shape]]) typeparams %[[c0_2]] : (!fir.ptr<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
+  ! CHECK: fir.store %[[embox]] to %[[coor]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
+  ! CHECK: %[[coor2:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_char_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
+  ! CHECK: %[[box_load:.*]] = fir.load %[[coor2]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
+  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>) -> !fir.ptr<!fir.array<?x!fir.char<1,?>>>
+  ! CHECK: %[[len:.*]] = fir.box_elesize %[[box_load]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>) -> index
+  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>>
+  ! CHECK: %[[emboxchar:.*]] = fir.emboxchar %[[cast]], %[[len]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
+  ! CHECK: fir.call @_QPbar_char_3(%[[emboxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
   call bar_char_3(a%i)
 end subroutine
diff --git a/flang/test/Lower/component-wise-init.f90 b/flang/test/Lower/component-wise-init.f90
index 99633062c7619..6145d049ba21e 100644
--- a/flang/test/Lower/component-wise-init.f90
+++ b/flang/test/Lower/component-wise-init.f90
@@ -108,4 +108,4 @@ end subroutine test_fallback_explicit
 ! 
 ! Ensure types with explicit initialization trigger the gatekeeper and fall back to the old logic.
 ! CHECK: %[[GLOBAL_INIT_EXP:.*]] = fir.address_of(@_QQ_QMmy_typesTfallbackexplicittype.DerivedInit)
-! CHECK: fir.copy %[[GLOBAL_INIT_EXP]] to %[[VAR_EXPLICIT]]
\ No newline at end of file
+! CHECK: fir.copy %[[GLOBAL_INIT_EXP]] to %[[VAR_EXPLICIT]]
diff --git a/flang/test/Lower/default-initialization.f90 b/flang/test/Lower/default-initialization.f90
index f64d7185015f7..c2a4673c537af 100644
--- a/flang/test/Lower/default-initialization.f90
+++ b/flang/test/Lower/default-initialization.f90
@@ -21,9 +21,9 @@ module test_dinit
   ! Test local scalar is default initialized
   ! CHECK-LABEL: func @_QMtest_dinitPlocal()
   subroutine local
-    !CHECK: %[[x:.*]]  = fir.alloca !fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocalEx"}
-    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
-    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    !CHECK: %[[x:.*]]  = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocalEx"}
+    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
     type(t) :: x
     print *, x%i
   end subroutine
@@ -31,9 +31,9 @@ subroutine local
   ! Test local array is default initialized
   ! CHECK-LABEL: func @_QMtest_dinitPlocal_array()
   subroutine local_array()
-    ! CHECK: %[[x:.*]] = fir.alloca !fir.array<4x!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[x:.*]] = fir.alloca !fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>
     ! CHECK: %[[xshape:.*]] = fir.shape %c4{{.*}} : (index) -> !fir.shape<1>
-    ! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshape]]) : (!fir.ref<!fir.array<4x!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<4x!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>>
+    ! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshape]]) : (!fir.ref<!fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>>
     ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
     ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> ()
     type(t) :: x(4)
@@ -44,38 +44,41 @@ subroutine local_array()
   ! scalars.
   ! CHECK-LABEL: func @_QMtest_dinitPlocal_alloc_comp()
   subroutine local_alloc_comp
-    !CHECK: %[[x:.*]] = 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: %[[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]] 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: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocal_alloc_compEx"}
+    !CHECK: %[[COORD:.*]] = fir.coordinate_of %[[x]], 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
 
   ! Test function results are default initialized.
-  ! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>
+  ! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{i:i32}>
   function result()
-    !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}> {bindc_name = "result", uniq_name = "_QMtest_dinitFresultEresult"}
-    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
-    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> {bindc_name = "result", uniq_name = "_QMtest_dinitFresultEresult"}
+    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
     type(t) :: result
   end function
 
   ! Test intent(out) dummies are default initialized
   ! CHECK-LABEL: func @_QMtest_dinitPintent_out(
-  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
   subroutine intent_out(x)
-    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
-    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
     type(t), intent(out) :: x
   end subroutine
 
   ! Test that optional intent(out) are default initialized only when
   ! present.
   ! CHECK-LABEL: func @_QMtest_dinitPintent_out_optional(
-  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>> {fir.bindc_name = "x", fir.optional})
+  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>> {fir.bindc_name = "x", fir.optional})
   subroutine intent_out_optional(x)
-    ! CHECK: %[[isPresent:.*]] = fir.is_present %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>) -> i1
+    ! CHECK: %[[isPresent:.*]] = fir.is_present %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> i1
     ! CHECK: fir.if %[[isPresent]] {
-      ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+      ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
       ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
       ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> ()
     ! CHECK: }
@@ -89,32 +92,33 @@ subroutine local_eq()
     integer :: zi
     ! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8>
     ! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
-    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
-    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
-    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
     equivalence (x, zi)
     print *, i
   end subroutine
 
   ! Test local equivalences with both equivalenced entities being
-  ! default initialized. Note that the standard allow default initialization
-  ! to be performed several times as long as the values are the same. So
-  ! far that is what lowering is doing to stay simple.
+  ! default initialized.
+  ! Note that the standard allow default initialization
+  ! to be performed several times as long as the values are the same.
+  ! So far that is what lowering is doing to stay simple.
   ! CHECK-LABEL: func @_QMtest_dinitPlocal_eq2()
   subroutine local_eq2()
     type(tseq) :: x
     type(tseq) :: y
     ! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8>
     ! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
-    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
-    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
-    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
 
 
     ! CHECK: %[[ycoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
-    ! CHECK: %[[y:.*]] = fir.convert %[[ycoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
-    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
-    ! CHECK: fir.copy %[[ADDR]] to %[[y]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[y:.*]] = fir.convert %[[ycoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: fir.copy %[[ADDR]] to %[[y]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
     equivalence (x, y)
     print *, y%i
   end subroutine
diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90
index 352bc64c72945..4a0decef86d09 100644
--- a/flang/test/Lower/derived-type-finalization.f90
+++ b/flang/test/Lower/derived-type-finalization.f90
@@ -1,5 +1,5 @@
 ! Test derived type finalization
-! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s
 
 ! Missing tests:
 ! - finalization within BLOCK construct
@@ -55,21 +55,25 @@ subroutine test_lhs_allocatable()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_lhs() {
+! CHECK: %[[BOXREF:.*]] = fir.alloca !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
 ! CHECK: %[[LHS:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "lhs", uniq_name = "_QMderived_type_finalizationFtest_lhsElhs"}
-! CHECK: %[[LHS_DECL:.*]]:2 = hlfir.declare %[[LHS]]
-! CHECK: %[[RHS:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "rhs", uniq_name = "_QMderived_type_finalizationFtest_lhsErhs"}
-! CHECK: %[[RHS_DECL:.*]]:2 = hlfir.declare %[[RHS]]
-! CHECK: hlfir.assign %[[RHS_DECL]]#0 to %[[LHS_DECL]]#0
-! CHECK: fir.call @_FortranADestroy
-! CHECK: fir.call @_FortranADestroy
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[LHS]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: fir.store %[[EMBOX]] to %[[BOXREF]] : !fir.ref<!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOXREF]] : (!fir.ref<!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: fir.call @_FortranAAssign(%[[BOX_NONE]], {{.*}}
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_lhs_allocatable() {
 ! CHECK: %[[LHS:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = "lhs", uniq_name = "_QMderived_type_finalizationFtest_lhs_allocatableElhs"}
-! CHECK: %[[LHS_DECL:.*]]:2 = hlfir.declare %[[LHS]]
+! CHECK: %[[LHS_ADDR:.*]] = fir.alloca !fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>> {uniq_name = "_QMderived_type_finalizationFtest_lhs_allocatableElhs.addr"}
 ! CHECK: %[[RHS:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "rhs", uniq_name = "_QMderived_type_finalizationFtest_lhs_allocatableErhs"}
-! CHECK: %[[RHS_DECL:.*]]:2 = hlfir.declare %[[RHS]]
-! CHECK: hlfir.assign %[[RHS_DECL]]#0 to %[[LHS_DECL]]#0 realloc
-! CHECK: fir.call @_FortranADestroy
+! CHECK: %[[LHS_ADDR_LOAD:.*]] = fir.load %[[LHS_ADDR]] : !fir.ref<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[ADDR_I64:.*]] = fir.convert %[[LHS_ADDR_LOAD]] : (!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> i64
+! CHECK: %[[C0:.*]] = arith.constant 0 : i64
+! CHECK: %[[IS_NULL:.*]] = arith.cmpi ne, %[[ADDR_I64]], %[[C0]] : i64
+! CHECK: fir.if %[[IS_NULL]] {
+! CHECK:   %[[BOX_NONE:.*]] = fir.convert %[[LHS]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>) -> !fir.box<none>
+! CHECK:   fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
+! CHECK: }
 
   ! 7.5.6.3 point 2. Finalization on explicit deallocation.
   subroutine test_deallocate()
@@ -79,10 +83,10 @@ subroutine test_deallocate()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_deallocate() {
-! CHECK: %[[T:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
-! CHECK: %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
-! CHECK: fir.call @_FortranAAllocatableAllocate
-! CHECK: fir.call @_FortranAAllocatableDeallocate
+! CHECK: %[[LOCAL_T:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = "t", uniq_name = "_QMderived_type_finalizationFtest_deallocateEt"}
+! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[LOCAL_T]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 
   ! 7.5.6.3 point 2. Finalization of disassociated target.
   subroutine test_target_finalization()
@@ -92,10 +96,13 @@ subroutine test_target_finalization()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_target_finalization() {
-! CHECK: %[[P:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
-! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]]
+! CHECK: %[[P:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = "p", uniq_name = "_QMderived_type_finalizationFtest_target_finalizationEp"}
+! CHECK: %[[ADDR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>> {uniq_name = "_QMderived_type_finalizationFtest_target_finalizationEp.addr"}
+! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: fir.store %[[zero]] to %[[ADDR]] : !fir.ref<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
 ! CHECK: fir.call @_FortranAPointerAllocateSource
-! CHECK: fir.call @_FortranAPointerDeallocate
+! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
+! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocate(%[[P_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
 
   ! 7.5.6.3 point 3. Finalize on END.
   subroutine test_end_finalization()
@@ -103,9 +110,11 @@ subroutine test_end_finalization()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_end_finalization() {
-! CHECK: %[[T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}>
-! CHECK: %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
-! CHECK: fir.call @_FortranADestroy
+! CHECK: %[[LOCAL_T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "t", uniq_name = "_QMderived_type_finalizationFtest_end_finalizationEt"}
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[LOCAL_T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
+! CHECK: return
 
   ! test with multiple return.
   subroutine test_end_finalization2(a)
@@ -117,12 +126,21 @@ subroutine test_end_finalization2(a)
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_end_finalization2(
 ! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "a"}) {
-! CHECK:   %[[A_DECL:.*]]:2 = hlfir.declare %[[A]]
 ! CHECK:   %[[T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "t", uniq_name = "_QMderived_type_finalizationFtest_end_finalization2Et"}
-! CHECK:   %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
-! CHECK:   cf.cond_br
-! CHECK:   hlfir.assign
-! CHECK:   fir.call @_FortranADestroy
+! CHECK:   %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.logical<4>>
+! CHECK:   %[[CONV_A:.*]] = fir.convert %[[LOAD_A]] : (!fir.logical<4>) -> i1
+! CHECK:   cf.cond_br %[[CONV_A]], ^bb1, ^bb2
+! CHECK: ^bb1:
+! CHECK:   cf.br ^bb3
+! CHECK: ^bb2:
+! CHECK:   %[[C10:.*]] = arith.constant 10 : i32
+! CHECK:   %[[COORD_A:.*]] = fir.coordinate_of %[[T]], a : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.ref<i32>
+! CHECK:   fir.store %[[C10]] to %[[COORD_A]] : !fir.ref<i32>
+! CHECK:   cf.br ^bb3
+! CHECK: ^bb3:
+! CHECK:   %[[EMBOX:.*]] = fir.embox %[[T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK:   %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
+! CHECK:   fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
 ! CHECK:   return
 ! CHECK: }
 
@@ -137,14 +155,12 @@ subroutine test_fct_ref()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_fct_ref() {
-! CHECK: %[[RES:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = ".result"}
-! CHECK: %[[TY:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
-! CHECK: %[[TY_DECL:.*]]:2 = hlfir.declare %[[TY]]
-! CHECK: %[[RES_DECL:.*]]:2 = hlfir.declare %[[RES]]
+! CHECK: %[[RESULT:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = ".result"}
 ! CHECK: %[[CALL_RES:.*]] = fir.call @_QMderived_type_finalizationPret_type()
-! CHECK: fir.save_result %[[CALL_RES]] to %[[RES_DECL]]#0
-! CHECK: hlfir.assign %[[RES_DECL]]#0 to %[[TY_DECL]]#0 realloc
-! CHECK: fir.call @_FortranADestroy(%{{.*}})
+! CHECK: fir.save_result %[[CALL_RES]] to %[[RESULT]] : !fir.type<_QMderived_type_finalizationTt1{a:i32}>, !fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[RESULT]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
 ! CHECK: return
 
   subroutine test_finalize_intent_out(t)
@@ -153,8 +169,9 @@ subroutine test_finalize_intent_out(t)
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_finalize_intent_out(
 ! CHECK-SAME: %[[T:.*]]: !fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>> {fir.bindc_name = "t"}) {
-! CHECK: %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
-! CHECK: fir.call @_FortranADestroy(%{{.*}})
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
+! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}}: (!fir.box<none>) -> ()
 ! CHECK: return
 
   function get_t1(i)
@@ -170,7 +187,7 @@ subroutine test_nonpointer_function()
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_nonpointer_function() {
 ! CHECK: %[[TMP:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = ".result"}
 ! CHECK: %{{.*}} = fir.call @_FortranAioBeginExternalListOutput
-! CHECK: %[[RES:.*]] = fir.call @_QMderived_type_finalizationPget_t1(%{{.*}})
+! CHECK: %[[RES:.*]] = fir.call @_QMderived_type_finalizationPget_t1(%{{.*}}) {{.*}} : (!fir.ref<i32>) -> !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
 ! CHECK: fir.save_result %[[RES]] to %[[TMP]] : !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>, !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>
 ! CHECK: %{{.*}} = fir.call @_FortranAioOutputDerivedType
 ! CHECK-NOT: fir.call @_FortranADestroy
@@ -185,11 +202,15 @@ 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: %[[COORD_T:.*]] = fir.coordinate_of %[[b]], t : (!fir.ref<!fir.type<_QMderived_type_finalizationTt3{t:!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>}>>) -> !fir.ref<!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+! CHECK: %[[COORD_A:.*]] = fir.coordinate_of %[[COORD_T]], a : (!fir.ref<!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
+! CHECK: %[[SHAPE:.*]] = fir.shape %c0{{.*}} : (index) -> !fir.shape<1>
+! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK: fir.store %[[EMBOX]] to %[[COORD_A]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
 ! CHECK-NOT: fir.call @_FortranADestroy
-! CHECK: hlfir.assign
-! CHECK: fir.call @_FortranADestroy
+! CHECK: fir.call @_FortranAAssign(
+! CHECK: fir.call @_FortranADestroy(
 
   function no_func_ret_finalize() result(ty)
     type(t1) :: ty
@@ -197,7 +218,7 @@ function no_func_ret_finalize() result(ty)
   end function
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPno_func_ret_finalize() -> !fir.type<_QMderived_type_finalizationTt1{a:i32}> {
-! CHECK: hlfir.assign
+! CHECK: fir.call @_FortranAAssign
 ! CHECK-NOT: fir.call @_FortranADestroy
 ! CHECK: return %{{.*}} : !fir.type<_QMderived_type_finalizationTt1{a:i32}>
 
@@ -214,9 +235,11 @@ subroutine test_avoid_double_free()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_avoid_double_free() {
+! CHECK: %[[RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>> {bindc_name = ".result"}
 ! CHECK: fir.call @_FortranAAllocatableAllocateSource(
-! CHECK: fir.call @_FortranADestroy
-! CHECK: fir.call @_FortranAAllocatableDeallocatePolymorphic
+! CHECK-NOT: fir.freemem %{{.*}} : !fir.heap<!fir.array<?x!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[RES_CONV:.*]] = fir.convert %[[RES]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>>) -> !fir.box<none>
+! CHECK: fir.call @_FortranADestroy(%[[RES_CONV]]) {{.*}} : (!fir.box<none>) -> ()
 
   subroutine t4_final(this)
     type(t4) :: this
@@ -227,7 +250,7 @@ subroutine local_t4()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPlocal_t4()
-! CHECK: fir.call @_FortranADestroy(%{{.*}}) fastmath<contract> : (!fir.box<none>) -> ()
+! CHECK: fir.call @_FortranADestroy(%2) fastmath<contract> : (!fir.box<none>) -> ()
 
 end module
 
diff --git a/flang/test/Lower/derived-type-temp.f90 b/flang/test/Lower/derived-type-temp.f90
index b6363c2b8636f..3e5e3b8e0a9e1 100644
--- a/flang/test/Lower/derived-type-temp.f90
+++ b/flang/test/Lower/derived-type-temp.f90
@@ -13,7 +13,9 @@ program derived_temp_init
   y = t2(x)
 end
 
-! CHECK: %[[ALLOC:.*]] =  fir.alloca !fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}> {bindc_name = "x", uniq_name = "_QFEx"}
+! 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..c6b8232fa4ede 100644
--- a/flang/test/Lower/forall/forall-allocatable-2.f90
+++ b/flang/test/Lower/forall/forall-allocatable-2.f90
@@ -1,6 +1,6 @@
 ! Test forall lowering
 
-! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
 
 subroutine forall_with_allocatable2(a1)
   real :: a1(:)
@@ -14,36 +14,49 @@ subroutine forall_with_allocatable2(a1)
   end forall
 end subroutine forall_with_allocatable2
 
-! CHECK-LABEL: func.func @_QPforall_with_allocatable2(
-! CHECK-SAME:                                         %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a1"}) {
-! CHECK:         %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
-! 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_11:.*]] = arith.constant 5 : i32
-! CHECK:         %[[VAL_12:.*]] = arith.constant 15 : i32
-! CHECK:         hlfir.forall lb {
-! CHECK:           hlfir.yield %[[VAL_11]] : i32
-! CHECK:         } ub {
-! CHECK:           hlfir.yield %[[VAL_12]] : i32
-! CHECK:         }  (%[[VAL_13:.*]]: i32) {
-! CHECK:           %[[VAL_14:.*]] = hlfir.forall_index "i" %[[VAL_13]] : (i32) -> !fir.ref<i32>
-! CHECK:           hlfir.region_assign {
-! CHECK:             %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
-! CHECK:             %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64
-! CHECK:             %[[VAL_17:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_16]])  : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
-! CHECK:             %[[VAL_18:.*]] = fir.load %[[VAL_17]] : !fir.ref<f32>
-! CHECK:             hlfir.yield %[[VAL_18]] : f32
-! CHECK:           } to {
-! CHECK:             %[[VAL_19:.*]] = hlfir.designate %[[VAL_9]]#0{"arr"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:             %[[VAL_21:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
-! CHECK:             %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i32) -> i64
-! CHECK:             %[[VAL_23:.*]] = hlfir.designate %[[VAL_20]] (%[[VAL_22]])  : (!fir.box<!fir.heap<!fir.array<?xf32>>>, i64) -> !fir.ref<f32>
-! CHECK:             hlfir.yield %[[VAL_23]] : !fir.ref<f32>
-! CHECK:           }
+! CHECK-LABEL: func @_QPforall_with_allocatable2(
+! CHECK-SAME:                                    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
+! CHECK:         %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
+! CHECK:         %[[VAL_2:.*]] = 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_3:.*]] = fir.coordinate_of %[[VAL_2]], 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_4:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+! CHECK:         %[[VAL_5:.*]] = arith.constant 0 : index
+! CHECK:         %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
+! CHECK:         %[[VAL_7:.*]] = fir.embox %[[VAL_4]](%[[VAL_6]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK:         fir.store %[[VAL_7]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:         %[[VAL_9:.*]] = arith.constant 5 : i32
+! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
+! CHECK:         %[[VAL_11:.*]] = arith.constant 15 : i32
+! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i32) -> index
+! CHECK:         %[[VAL_13:.*]] = arith.constant 1 : index
+! CHECK:         %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_2]], 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_16:.*]] = fir.load %[[VAL_15]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:         %[[VAL_17:.*]] = arith.constant 0 : index
+! CHECK:         %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_16]], %[[VAL_17]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK:         %[[VAL_19:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+! CHECK:         %[[VAL_20:.*]] = fir.shape_shift %[[VAL_18]]#0, %[[VAL_18]]#1 : (index, index) -> !fir.shapeshift<1>
+! CHECK:         %[[VAL_21:.*]] = fir.array_load %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_22:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
+! CHECK:         %[[VAL_23:.*]] = fir.do_loop %[[VAL_24:.*]] = %[[VAL_10]] to %[[VAL_12]] step %[[VAL_13]] unordered iter_args(%[[VAL_25:.*]] = %[[VAL_21]]) -> (!fir.array<?xf32>) {
+! CHECK:           %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32
+! CHECK:           fir.store %[[VAL_26]] to %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_27:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_28:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64
+! CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
+! CHECK:           %[[VAL_31:.*]] = arith.subi %[[VAL_30]], %[[VAL_27]] : index
+! CHECK:           %[[VAL_32:.*]] = fir.array_fetch %[[VAL_22]], %[[VAL_31]] : (!fir.array<?xf32>, index) -> f32
+! CHECK:           %[[VAL_33:.*]] = arith.constant 1 : index
+! CHECK:           %[[VAL_34:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
+! CHECK:           %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i32) -> i64
+! CHECK:           %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i64) -> index
+! CHECK:           %[[VAL_37:.*]] = arith.subi %[[VAL_36]], %[[VAL_33]] : index
+! CHECK:           %[[VAL_38:.*]] = fir.array_update %[[VAL_25]], %[[VAL_32]], %[[VAL_37]] : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>
+! CHECK:           fir.result %[[VAL_38]] : !fir.array<?xf32>
 ! CHECK:         }
+! CHECK:         fir.array_merge_store %[[VAL_21]], %[[VAL_39:.*]] to %[[VAL_19]] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.heap<!fir.array<?xf32>>
+! CHECK:         %[[VAL_40:.*]] = fir.embox %[[VAL_2]] : (!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_41:.*]] = fir.convert %[[VAL_40]] : (!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_41]])
 ! CHECK:         return
 ! CHECK:       }
diff --git a/flang/test/Lower/pointer-default-init.f90 b/flang/test/Lower/pointer-default-init.f90
index dd9c7539b4f05..047485b23c877 100644
--- a/flang/test/Lower/pointer-default-init.f90
+++ b/flang/test/Lower/pointer-default-init.f90
@@ -39,8 +39,12 @@ subroutine test_local()
 end subroutine
 ! CHECK-LABEL:   func.func @_QPtest_local() {
 ! CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtestTt{i:i32,x:!fir.box<!fir.ptr<!fir.array<?xf32>>>}> {bindc_name = "x", uniq_name = "_QFtest_localEx"}
-! 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]] 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]], 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

>From 7e51c1398cacd4e1ad9fee0503c7d6d8cbf28606 Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Thu, 9 Apr 2026 12:31:39 +0800
Subject: [PATCH 6/7] Update test files

---
 flang/test/Lower/call-copy-in-out.f90         | 258 ++++--------------
 .../test/Lower/derived-type-finalization.f90  | 112 +++-----
 .../Lower/forall/forall-allocatable-2.f90     |  80 +++---
 3 files changed, 134 insertions(+), 316 deletions(-)

diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90
index c35a998b738a4..2fc78fcf1e65c 100644
--- a/flang/test/Lower/call-copy-in-out.f90
+++ b/flang/test/Lower/call-copy-in-out.f90
@@ -1,107 +1,60 @@
 ! Test copy-in / copy-out of non-contiguous variable passed as F77 array arguments.
-! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
+! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
 
 ! Nominal test
 ! CHECK-LABEL: func @_QPtest_assumed_shape_to_array(
 ! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_assumed_shape_to_array(x)
   real :: x(:)
-
-! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
-! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]] -> (!fir.heap<!fir.array<?xf32>>) {
-! CHECK:   %[[box_addr:.*]] = fir.box_addr %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.heap<!fir.array<?xf32>>
-! CHECK:   fir.result %[[box_addr]] : !fir.heap<!fir.array<?xf32>>
-! CHECK: } else {
-! Creating temp
-! CHECK:  %[[dim:.*]]:3 = fir.box_dims %[[x:.*]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK:  %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1 {uniq_name = ".copyinout"}
-
-! Copy-in
-! CHECK-DAG:  %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
-! CHECK-DAG:  %[[temp_box:.*]] = fir.embox %[[temp]](%[[shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK-DAG:  fir.store %[[temp_box]] to %[[temp_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK-DAG: %[[temp_box_addr:.*]] = fir.convert %[[temp_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
-! CHECK-DAG: %[[arg_box:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK-DAG: fir.call @_FortranAAssignTemporary(%[[temp_box_addr]], %[[arg_box]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:  fir.result %[[temp]] : !fir.heap<!fir.array<?xf32>>
-
-! CHECK:  %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-! CHECK:  fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
-
-! Copy-out
-! CHECK-DAG:  %[[shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
-! CHECK-DAG:  %[[temp_box:.*]] = fir.embox %[[addr]](%[[shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK:  %[[rebox:.*]] = fir.rebox %[[temp_box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
-! CHECK:  fir.store %[[rebox]] to %[[temp_box_ref:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK-DAG:  fir.store %[[x]] to %[[arg_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK-DAG: %[[arg_box_addr:.*]] = fir.convert %[[arg_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
-! CHECK-DAG: %[[temp_box_cast:.*]] = fir.convert %[[temp_box_ref]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK-DAG: fir.call @_FortranACopyOutAssign(%[[arg_box_addr]], %[[temp_box_cast]], %{{.*}}, %{{.*}}){{.*}}: (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<i8>, i32) -> ()
-
+! CHECK: %[[x_decl:.*]]:2 = hlfir.declare %[[x]]
+! CHECK: %[[copy_in:.*]]:2 = hlfir.copy_in %[[x_decl]]#0 {{.*}}
+! CHECK: %[[addr:.*]] = fir.box_addr %[[copy_in]]#0
+! CHECK: fir.call @_QPbar(%[[addr]])
+! CHECK: hlfir.copy_out %{{.*}}, %[[copy_in]]#1 to %[[x_decl]]#0
   call bar(x)
 end subroutine
 
 ! Test that copy-in/copy-out does not trigger the re-evaluation of
 ! the designator expression.
 ! CHECK-LABEL: func @_QPeval_expr_only_once(
-! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.array<200xf32>>{{.*}}) {
 subroutine eval_expr_only_once(x)
   integer :: only_once
   real :: x(200)
 ! CHECK: fir.call @_QPonly_once()
-! CHECK: %[[x_section:.*]] = fir.embox %[[x]](%{{.*}}) [%{{.*}}] : (!fir.ref<!fir.array<200xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK: %[[box_none:.*]] = fir.convert %[[x_section]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
-! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]] -> (!fir.heap<!fir.array<?xf32>>) {
-
-! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>
-! CHECK-NOT: fir.call @_QPonly_once()
-! CHECK:  fir.call @_FortranAAssignTemporary
+! CHECK: hlfir.designate
+! CHECK: hlfir.copy_in
 ! CHECK-NOT: fir.call @_QPonly_once()
-
-! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-! CHECK:  fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
-  call bar(x(1:200:only_once()))
-
+! CHECK: fir.call @_QPbar
 ! CHECK-NOT: fir.call @_QPonly_once()
-! CHECK:  fir.call @_FortranACopyOutAssign
+! CHECK: hlfir.copy_out
 ! CHECK-NOT: fir.call @_QPonly_once()
-
+  call bar(x(1:200:only_once()))
 end subroutine
 
 ! Test no copy-in/copy-out is generated for contiguous assumed shapes.
 ! CHECK-LABEL: func @_QPtest_contiguous(
-! CHECK-SAME: %[[x:.*]]: !fir.box<!fir.array<?xf32>>
 subroutine test_contiguous(x)
   real, contiguous :: x(:)
-! CHECK: %[[addr:.*]] = fir.box_addr %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-! CHECK-NOT:  fir.call @_FortranAAssignTemporary
-! CHECK: fir.call @_QPbar(%[[addr]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
+! CHECK-NOT: hlfir.copy_in
+! CHECK: fir.call @_QPbar
+! CHECK-NOT: hlfir.copy_out
   call bar(x)
-! CHECK-NOT:  fir.call @_FortranACopyOutAssign
-! CHECK: return
 end subroutine
 
 ! Test the parenthesis are preventing copy-out.
-! CHECK: func @_QPtest_parenthesis(
-! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
+! CHECK-LABEL: func @_QPtest_parenthesis(
 subroutine test_parenthesis(x)
   real :: x(:)
-! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1 {uniq_name = ".array.expr"}
-! CHECK:  fir.array_merge_store %{{.*}}, %{{.*}} to %[[temp]]
-! CHECK:  %[[cast:.*]] = fir.convert %[[temp]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>
-! CHECK:  fir.call @_QPbar(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<?xf32>>) -> ()
+! CHECK: hlfir.elemental
+! CHECK: hlfir.associate
+! CHECK: fir.call @_QPbar
+! CHECK: hlfir.end_associate
+! CHECK-NOT: hlfir.copy_out
   call bar((x))
-! CHECK-NOT:  fir.call @_FortranACopyOutAssign
-! CHECK: return
 end subroutine
 
 ! Test copy-in in is skipped for intent(out) arguments.
-! CHECK: func @_QPtest_intent_out(
-! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
+! CHECK-LABEL: func @_QPtest_intent_out(
 subroutine test_intent_out(x)
   real :: x(:)
   interface
@@ -109,26 +62,14 @@ subroutine bar_intent_out(x)
     real, intent(out) :: x(100)
   end subroutine
   end interface
-! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
-! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]]
-! CHECK: } else {
-! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1
-! CHECK-NOT:  fir.call @_FortranAAssignTemporary
-! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
-! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
-! CHECK:  fir.call @_QPbar_intent_out(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
+! CHECK: hlfir.copy_in
+! CHECK: fir.call @_QPbar_intent_out
+! CHECK: hlfir.copy_out
   call bar_intent_out(x)
-
-! CHECK: fir.if %[[not_contiguous]]
-! CHECK: fir.call @_FortranACopyOutAssign
-! CHECK: return
 end subroutine
 
-! Test copy-out is skipped for intent(out) arguments.
+! Test copy-out is skipped for intent(in) arguments.
 ! CHECK-LABEL: func.func @_QPtest_intent_in(
-! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
 subroutine test_intent_in(x)
   real :: x(:)
   interface
@@ -136,30 +77,14 @@ subroutine bar_intent_in(x)
     real, intent(in) :: x(100)
   end subroutine
   end interface
-! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
-! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]]
-! CHECK: } else {
-! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1
-! CHECK: %[[temp_shape:.*]] = fir.shape %[[dim]]#1 : (index) -> !fir.shape<1>
-! CHECK: %[[temp_box:.*]] = fir.embox %[[temp]](%[[temp_shape]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK: fir.store %[[temp_box]] to %[[temp_box_loc:.*]] : !fir.ref<!fir.box<!fir.array<?xf32>>>
-! CHECK: %[[temp_box_addr:.*]] = fir.convert %[[temp_box_loc]] : (!fir.ref<!fir.box<!fir.array<?xf32>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: fir.call @_FortranAAssignTemporary(%[[temp_box_addr]],
-! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
-! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
-! CHECK:  fir.call @_QPbar_intent_in(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
+! CHECK: hlfir.copy_in
+! CHECK: fir.call @_QPbar_intent_in
+! CHECK: hlfir.copy_out %{{.*}}, %{{.*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1) -> ()
   call bar_intent_in(x)
-! CHECK: fir.if %[[not_contiguous]]
-! CHECK: fir.zero
-! CHECK:  fir.call @_FortranACopyOutAssign
-! CHECK: return
 end subroutine
 
 ! Test copy-in/copy-out is done for intent(inout)
-! CHECK: func @_QPtest_intent_inout(
-! CHECK: %[[x:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
+! CHECK-LABEL: func @_QPtest_intent_inout(
 subroutine test_intent_inout(x)
   real :: x(:)
   interface
@@ -167,111 +92,55 @@ subroutine bar_intent_inout(x)
     real, intent(inout) :: x(100)
   end subroutine
   end interface
-! CHECK: %[[box_none:.*]] = fir.convert %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<none>
-! CHECK: %[[is_contiguous:.*]] = fir.call @_FortranAIsContiguous(%[[box_none]]) {{.*}}: (!fir.box<none>) -> i1
-! CHECK: %[[addr:.*]] = fir.if %[[is_contiguous]]
-! CHECK: } else {
-! CHECK: %[[dim:.*]]:3 = fir.box_dims %[[x]], %c0{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK: %[[temp:.*]] = fir.allocmem !fir.array<?xf32>, %[[dim]]#1
-! CHECK:  fir.call @_FortranAAssign
-! CHECK: %[[not_contiguous:.*]] = arith.cmpi eq, %[[is_contiguous]], %false{{.*}} : i1
-! CHECK:  %[[cast:.*]] = fir.convert %[[addr]] : (!fir.heap<!fir.array<?xf32>>) -> !fir.ref<!fir.array<100xf32>>
-! CHECK:  fir.call @_QPbar_intent_inout(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xf32>>) -> ()
+! CHECK: hlfir.copy_in
+! CHECK: fir.call @_QPbar_intent_inout
+! CHECK: hlfir.copy_out
+! CHECK-SAME: to
   call bar_intent_inout(x)
-! CHECK: fir.if %[[not_contiguous]]
-! CHECK:  fir.call @_FortranACopyOutAssign
-! CHECK: return
 end subroutine
 
 ! Test characters are handled correctly
 ! CHECK-LABEL: func @_QPtest_char(
-! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.char<1,10>>>{{.*}}) {
 subroutine test_char(x)
-! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.box<!fir.array<?x!fir.char<1,10>>>
-! CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.array<?x!fir.char<1,10>>>
-! CHECK:           %[[VAL_3:.*]] = arith.constant 10 : index
-! CHECK:           %[[VAL_4:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<none>
-! CHECK:           %[[VAL_5:.*]] = fir.call @_FortranAIsContiguous(%[[VAL_4]]) fastmath<contract> : (!fir.box<none>) -> i1
-! CHECK:           %[[VAL_6:.*]] = fir.if %[[VAL_5]] -> (!fir.heap<!fir.array<?x!fir.char<1,10>>>) {
-! CHECK:             %[[VAL_7:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.heap<!fir.array<?x!fir.char<1,10>>>
-! CHECK:             fir.result %[[VAL_7]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>
-! CHECK:           } else {
-! CHECK:             %[[VAL_8:.*]] = arith.constant 0 : index
-! CHECK:             %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>, index) -> (index, index, index)
-! CHECK:             %[[VAL_10:.*]] = fir.allocmem !fir.array<?x!fir.char<1,10>>, %[[VAL_9]]#1 {uniq_name = ".copyinout"}
-! CHECK:             %[[VAL_11:.*]] = fir.shape %[[VAL_9]]#1 : (index) -> !fir.shape<1>
-! CHECK:             %[[VAL_12:.*]] = fir.embox %[[VAL_10]](%[[VAL_11]]) : (!fir.heap<!fir.array<?x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,10>>>
-! CHECK:             fir.store %[[VAL_12]] to %[[VAL_2]] : !fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>
-! CHECK:             %[[VAL_15:.*]] = fir.convert %[[VAL_2]] : (!fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK:             %[[VAL_16:.*]] = fir.convert %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<none>
-! CHECK:             fir.call @_FortranAAssignTemporary(%[[VAL_15]], %[[VAL_16]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:             fir.result %[[VAL_10]] : !fir.heap<!fir.array<?x!fir.char<1,10>>>
-! CHECK:           }
-! CHECK:           %[[VAL_19:.*]] = arith.constant 0 : index
-! CHECK:           %[[VAL_20:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_19]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>, index) -> (index, index, index)
-! CHECK:           %[[VAL_21:.*]] = arith.constant false
-! CHECK:           %[[VAL_22:.*]] = arith.cmpi eq, %[[VAL_5]], %[[VAL_21]] : i1
-! CHECK:           %[[VAL_23:.*]] = fir.convert %[[VAL_24:.*]] : (!fir.heap<!fir.array<?x!fir.char<1,10>>>) -> !fir.ref<!fir.char<1,?>>
-! CHECK:           %[[VAL_25:.*]] = fir.emboxchar %[[VAL_23]], %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
-! CHECK:           fir.call @_QPbar_char(%[[VAL_25]]) fastmath<contract> : (!fir.boxchar<1>) -> ()
-! CHECK:           fir.if %[[VAL_22]] {
-! CHECK:             %[[VAL_26:.*]] = fir.shape %[[VAL_20]]#1 : (index) -> !fir.shape<1>
-! CHECK:             %[[VAL_27:.*]] = fir.embox %[[VAL_24]](%[[VAL_26]]) : (!fir.heap<!fir.array<?x!fir.char<1,10>>>, !fir.shape<1>) -> !fir.box<!fir.array<?x!fir.char<1,10>>>
-! CHECK:             %[[REBOX:.*]] = fir.rebox %[[VAL_27]] : (!fir.box<!fir.array<?x!fir.char<1,10>>>) -> !fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>
-! CHECK:             fir.store %[[REBOX]] to %[[TMP_BOX_REF:.*]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>
-! CHECK:             fir.store %[[VAL_0]] to %[[VAL_1]] : !fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>
-! CHECK:             %[[VAL_31:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.box<!fir.array<?x!fir.char<1,10>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK:             %[[VAL_32:.*]] = fir.convert %[[TMP_BOX_REF]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,10>>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK:             fir.call @_FortranACopyOutAssign(%[[VAL_31]], %[[VAL_32]], %{{.*}}, %{{.*}}) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.ref<!fir.box<none>>, !fir.ref<i8>, i32) -> ()
-! CHECK:           }
-
   character(10) :: x(:)
+! CHECK: hlfir.copy_in
+! CHECK: fir.call @_QPbar_char
+! CHECK: hlfir.copy_out
   call bar_char(x)
-  ! CHECK:         return
-  ! CHECK:       }
 end subroutine test_char
 
 ! CHECK-LABEL: func @_QPtest_scalar_substring_does_no_trigger_copy_inout
-! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>
 subroutine test_scalar_substring_does_no_trigger_copy_inout(c, i, j)
   character(*) :: c
   integer :: i, j
-  ! CHECK: %[[unbox:.*]]:2 = fir.unboxchar %[[arg0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
-  ! CHECK: %[[c:.*]] = fir.convert %[[unbox]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[c]], %{{.*}} : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
-  ! CHECK: %[[substr:.*]] = fir.convert %[[coor]] : (!fir.ref<!fir.char<1>>) -> !fir.ref<!fir.char<1,?>>
-  ! CHECK: %[[boxchar:.*]] = fir.emboxchar %[[substr]], %{{.*}} : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
-  ! CHECK: fir.call @_QPbar_char_2(%[[boxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
+  ! CHECK: hlfir.designate
+  ! CHECK-NOT: hlfir.copy_in
+  ! CHECK: fir.call @_QPbar_char_2
+  ! CHECK-NOT: hlfir.copy_out
   call bar_char_2(c(i:j))
 end subroutine
 
 ! CHECK-LABEL: func @_QPissue871(
-! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.type<_QFissue871Tt{i:i32}>>>>{{.*}})
 subroutine issue871(p)
   ! Test passing implicit derived from scalar pointer (no copy-in/out).
   type t
     integer :: i
   end type t
   type(t), pointer :: p
-  ! CHECK: %[[box_load:.*]] = fir.load %[[p]]
-  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]]
-  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
-  ! CHECK: fir.call @_QPbar_derived(%[[cast]])
+  ! CHECK-NOT: hlfir.copy_in
+  ! CHECK: fir.call @_QPbar_derived
   call bar_derived(p)
 end subroutine
 
 ! CHECK-LABEL: func @_QPissue871_array(
-! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue871_arrayTt{i:i32}>>>>>
 subroutine issue871_array(p)
   ! Test passing implicit derived from contiguous pointer (no copy-in/out).
   type t
     integer :: i
   end type t
   type(t), pointer, contiguous :: p(:)
-  ! CHECK: %[[box_load:.*]] = fir.load %[[p]]
-  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]]
-  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]]
-  ! CHECK: fir.call @_QPbar_derived_array(%[[cast]])
+  ! CHECK-NOT: hlfir.copy_in
+  ! CHECK: fir.call @_QPbar_derived_array
   call bar_derived_array(p)
 end subroutine
 
@@ -281,10 +150,10 @@ subroutine whole_components()
   type t
     integer :: i(100)
   end type
-  ! CHECK: %[[a:.*]] = fir.alloca !fir.type<_QFwhole_componentsTt{i:!fir.array<100xi32>}>
   type(t) :: a
-  ! CHECK: %[[addr:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_componentsTt{i:!fir.array<100xi32>}>>) -> !fir.ref<!fir.array<100xi32>>
-  ! CHECK: fir.call @_QPbar_integer(%[[addr]]) {{.*}}: (!fir.ref<!fir.array<100xi32>>) -> ()
+  ! CHECK: hlfir.designate
+  ! CHECK-NOT: hlfir.copy_in
+  ! CHECK: fir.call @_QPbar_integer
   call bar_integer(a%i)
 end subroutine
 
@@ -294,19 +163,10 @@ subroutine whole_component_contiguous_pointer()
   type t
     integer, pointer, contiguous :: i(:)
   end type
-  ! CHECK: %[[a:.*]] = fir.alloca !fir.type<_QFwhole_component_contiguous_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>
   type(t) :: a
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  ! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xi32>>
-  ! 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<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>>
-  ! CHECK: fir.store %[[embox]] to %[[coor]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  ! CHECK: %[[coor2:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  ! CHECK: %[[box_load:.*]] = fir.load %[[coor2]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
-  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.ptr<!fir.array<?xi32>>
-  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr<!fir.array<?xi32>>) -> !fir.ref<!fir.array<100xi32>>
-  ! CHECK: fir.call @_QPbar_integer(%[[cast]]) {{.*}}: (!fir.ref<!fir.array<100xi32>>) -> ()
+  ! CHECK: hlfir.designate
+  ! CHECK-NOT: hlfir.copy_in
+  ! CHECK: fir.call @_QPbar_integer
   call bar_integer(a%i)
 end subroutine
 
@@ -316,21 +176,9 @@ subroutine whole_component_contiguous_char_pointer()
   type t
     character(:), pointer, contiguous :: i(:)
   end type
-  ! CHECK: %[[a:.*]] = fir.alloca !fir.type<_QFwhole_component_contiguous_char_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>
   type(t) :: a
-  ! CHECK: %[[coor:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_char_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
-  ! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.array<?x!fir.char<1,?>>>
-  ! CHECK: %[[c0_1:.*]] = arith.constant 0 : index
-  ! CHECK: %[[shape:.*]] = fir.shape %[[c0_1]] : (index) -> !fir.shape<1>
-  ! CHECK: %[[c0_2:.*]] = arith.constant 0 : index
-  ! CHECK: %[[embox:.*]] = fir.embox %[[zero]](%[[shape]]) typeparams %[[c0_2]] : (!fir.ptr<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>
-  ! CHECK: fir.store %[[embox]] to %[[coor]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
-  ! CHECK: %[[coor2:.*]] = fir.coordinate_of %[[a]], i : (!fir.ref<!fir.type<_QFwhole_component_contiguous_char_pointerTt{i:!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
-  ! CHECK: %[[box_load:.*]] = fir.load %[[coor2]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
-  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>) -> !fir.ptr<!fir.array<?x!fir.char<1,?>>>
-  ! CHECK: %[[len:.*]] = fir.box_elesize %[[box_load]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>) -> index
-  ! CHECK: %[[cast:.*]] = fir.convert %[[addr]] : (!fir.ptr<!fir.array<?x!fir.char<1,?>>>) -> !fir.ref<!fir.char<1,?>>
-  ! CHECK: %[[emboxchar:.*]] = fir.emboxchar %[[cast]], %[[len]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1>
-  ! CHECK: fir.call @_QPbar_char_3(%[[emboxchar]]) {{.*}}: (!fir.boxchar<1>) -> ()
+  ! CHECK: hlfir.designate
+  ! CHECK-NOT: hlfir.copy_in
+  ! CHECK: fir.call @_QPbar_char_3
   call bar_char_3(a%i)
 end subroutine
diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90
index 4a0decef86d09..032c82b9de04e 100644
--- a/flang/test/Lower/derived-type-finalization.f90
+++ b/flang/test/Lower/derived-type-finalization.f90
@@ -1,5 +1,5 @@
 ! Test derived type finalization
-! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
 
 ! Missing tests:
 ! - finalization within BLOCK construct
@@ -55,25 +55,21 @@ subroutine test_lhs_allocatable()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_lhs() {
-! CHECK: %[[BOXREF:.*]] = fir.alloca !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
 ! CHECK: %[[LHS:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "lhs", uniq_name = "_QMderived_type_finalizationFtest_lhsElhs"}
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[LHS]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK: fir.store %[[EMBOX]] to %[[BOXREF]] : !fir.ref<!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[BOXREF]] : (!fir.ref<!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: fir.call @_FortranAAssign(%[[BOX_NONE]], {{.*}}
+! CHECK: %[[LHS_DECL:.*]]:2 = hlfir.declare %[[LHS]]
+! CHECK: %[[RHS:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "rhs", uniq_name = "_QMderived_type_finalizationFtest_lhsErhs"}
+! CHECK: %[[RHS_DECL:.*]]:2 = hlfir.declare %[[RHS]]
+! CHECK: hlfir.assign %[[RHS_DECL]]#0 to %[[LHS_DECL]]#0
+! CHECK: fir.call @_FortranADestroy
+! CHECK: fir.call @_FortranADestroy
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_lhs_allocatable() {
 ! CHECK: %[[LHS:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = "lhs", uniq_name = "_QMderived_type_finalizationFtest_lhs_allocatableElhs"}
-! CHECK: %[[LHS_ADDR:.*]] = fir.alloca !fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>> {uniq_name = "_QMderived_type_finalizationFtest_lhs_allocatableElhs.addr"}
+! CHECK: %[[LHS_DECL:.*]]:2 = hlfir.declare %[[LHS]]
 ! CHECK: %[[RHS:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "rhs", uniq_name = "_QMderived_type_finalizationFtest_lhs_allocatableErhs"}
-! CHECK: %[[LHS_ADDR_LOAD:.*]] = fir.load %[[LHS_ADDR]] : !fir.ref<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
-! CHECK: %[[ADDR_I64:.*]] = fir.convert %[[LHS_ADDR_LOAD]] : (!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> i64
-! CHECK: %[[C0:.*]] = arith.constant 0 : i64
-! CHECK: %[[IS_NULL:.*]] = arith.cmpi ne, %[[ADDR_I64]], %[[C0]] : i64
-! CHECK: fir.if %[[IS_NULL]] {
-! CHECK:   %[[BOX_NONE:.*]] = fir.convert %[[LHS]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>) -> !fir.box<none>
-! CHECK:   fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
-! CHECK: }
+! CHECK: %[[RHS_DECL:.*]]:2 = hlfir.declare %[[RHS]]
+! CHECK: hlfir.assign %[[RHS_DECL]]#0 to %[[LHS_DECL]]#0 realloc
+! CHECK: fir.call @_FortranADestroy
 
   ! 7.5.6.3 point 2. Finalization on explicit deallocation.
   subroutine test_deallocate()
@@ -83,10 +79,10 @@ subroutine test_deallocate()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_deallocate() {
-! CHECK: %[[LOCAL_T:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = "t", uniq_name = "_QMderived_type_finalizationFtest_deallocateEt"}
-! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[LOCAL_T]] : (!fir.ref<!fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %{{.*}} = fir.call @_FortranAAllocatableDeallocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK: %[[T:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
+! CHECK: fir.call @_FortranAAllocatableAllocate
+! CHECK: fir.call @_FortranAAllocatableDeallocate
 
   ! 7.5.6.3 point 2. Finalization of disassociated target.
   subroutine test_target_finalization()
@@ -96,13 +92,10 @@ subroutine test_target_finalization()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_target_finalization() {
-! CHECK: %[[P:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = "p", uniq_name = "_QMderived_type_finalizationFtest_target_finalizationEp"}
-! CHECK: %[[ADDR:.*]] = fir.alloca !fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>> {uniq_name = "_QMderived_type_finalizationFtest_target_finalizationEp.addr"}
-! CHECK: %[[zero:.*]] = fir.zero_bits !fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK: fir.store %[[zero]] to %[[ADDR]] : !fir.ref<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[P:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[P_DECL:.*]]:2 = hlfir.declare %[[P]]
 ! CHECK: fir.call @_FortranAPointerAllocateSource
-! CHECK: %[[P_BOX_NONE:.*]] = fir.convert %[[P]] : (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>) -> !fir.ref<!fir.box<none>>
-! CHECK: %{{.*}} = fir.call @_FortranAPointerDeallocate(%[[P_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref<!fir.box<none>>, i1, !fir.box<none>, !fir.ref<i8>, i32) -> i32
+! CHECK: fir.call @_FortranAPointerDeallocate
 
   ! 7.5.6.3 point 3. Finalize on END.
   subroutine test_end_finalization()
@@ -110,11 +103,9 @@ subroutine test_end_finalization()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_end_finalization() {
-! CHECK: %[[LOCAL_T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "t", uniq_name = "_QMderived_type_finalizationFtest_end_finalizationEt"}
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[LOCAL_T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
-! CHECK: return
+! CHECK: %[[T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}>
+! CHECK: %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
+! CHECK: fir.call @_FortranADestroy
 
   ! test with multiple return.
   subroutine test_end_finalization2(a)
@@ -126,21 +117,12 @@ subroutine test_end_finalization2(a)
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_end_finalization2(
 ! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "a"}) {
+! CHECK:   %[[A_DECL:.*]]:2 = hlfir.declare %[[A]]
 ! CHECK:   %[[T:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = "t", uniq_name = "_QMderived_type_finalizationFtest_end_finalization2Et"}
-! CHECK:   %[[LOAD_A:.*]] = fir.load %[[A]] : !fir.ref<!fir.logical<4>>
-! CHECK:   %[[CONV_A:.*]] = fir.convert %[[LOAD_A]] : (!fir.logical<4>) -> i1
-! CHECK:   cf.cond_br %[[CONV_A]], ^bb1, ^bb2
-! CHECK: ^bb1:
-! CHECK:   cf.br ^bb3
-! CHECK: ^bb2:
-! CHECK:   %[[C10:.*]] = arith.constant 10 : i32
-! CHECK:   %[[COORD_A:.*]] = fir.coordinate_of %[[T]], a : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.ref<i32>
-! CHECK:   fir.store %[[C10]] to %[[COORD_A]] : !fir.ref<i32>
-! CHECK:   cf.br ^bb3
-! CHECK: ^bb3:
-! CHECK:   %[[EMBOX:.*]] = fir.embox %[[T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK:   %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
-! CHECK:   fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
+! CHECK:   %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
+! CHECK:   cf.cond_br
+! CHECK:   hlfir.assign
+! CHECK:   fir.call @_FortranADestroy
 ! CHECK:   return
 ! CHECK: }
 
@@ -155,12 +137,14 @@ subroutine test_fct_ref()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_fct_ref() {
-! CHECK: %[[RESULT:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = ".result"}
-! CHECK: %[[CALL_RES:.*]] = fir.call @_QMderived_type_finalizationPret_type()
-! CHECK: fir.save_result %[[CALL_RES]] to %[[RESULT]] : !fir.type<_QMderived_type_finalizationTt1{a:i32}>, !fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[RESULT]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}} : (!fir.box<none>) -> ()
+! CHECK: %[[RES:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = ".result"}
+! CHECK: %[[TY:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[TY_DECL:.*]]:2 = hlfir.declare %[[TY]]
+! CHECK: %[[CALL_RES:.*]] = fir.call @_QMderived_type_finalizationPret_type() fastmath<contract> : () -> !fir.type<_QMderived_type_finalizationTt1{a:i32}>
+! CHECK: fir.save_result %[[CALL_RES]] to %[[RES]]
+! CHECK: %[[RES_DECL:.*]]:2 = hlfir.declare %[[RES]]
+! CHECK: hlfir.assign %[[RES_DECL]]#0 to %[[TY_DECL]]#0 realloc
+! CHECK: fir.call @_FortranADestroy(%{{.*}})
 ! CHECK: return
 
   subroutine test_finalize_intent_out(t)
@@ -169,9 +153,8 @@ subroutine test_finalize_intent_out(t)
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_finalize_intent_out(
 ! CHECK-SAME: %[[T:.*]]: !fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>> {fir.bindc_name = "t"}) {
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[T]] : (!fir.ref<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>
-! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[EMBOX]] : (!fir.box<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranADestroy(%[[BOX_NONE]]) {{.*}}: (!fir.box<none>) -> ()
+! CHECK: %[[T_DECL:.*]]:2 = hlfir.declare %[[T]]
+! CHECK: fir.call @_FortranADestroy(%{{.*}})
 ! CHECK: return
 
   function get_t1(i)
@@ -187,7 +170,7 @@ subroutine test_nonpointer_function()
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_nonpointer_function() {
 ! CHECK: %[[TMP:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>> {bindc_name = ".result"}
 ! CHECK: %{{.*}} = fir.call @_FortranAioBeginExternalListOutput
-! CHECK: %[[RES:.*]] = fir.call @_QMderived_type_finalizationPget_t1(%{{.*}}) {{.*}} : (!fir.ref<i32>) -> !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
+! CHECK: %[[RES:.*]] = fir.call @_QMderived_type_finalizationPget_t1(%{{.*}})
 ! CHECK: fir.save_result %[[RES]] to %[[TMP]] : !fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>, !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>
 ! CHECK: %{{.*}} = fir.call @_FortranAioOutputDerivedType
 ! CHECK-NOT: fir.call @_FortranADestroy
@@ -202,15 +185,10 @@ 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: %[[COORD_T:.*]] = fir.coordinate_of %[[b]], t : (!fir.ref<!fir.type<_QMderived_type_finalizationTt3{t:!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>}>>) -> !fir.ref<!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
-! CHECK: %[[COORD_A:.*]] = fir.coordinate_of %[[COORD_T]], a : (!fir.ref<!fir.type<_QMderived_type_finalizationTt2{a:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK: %[[ZERO:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
-! CHECK: %[[SHAPE:.*]] = fir.shape %c0{{.*}} : (index) -> !fir.shape<1>
-! CHECK: %[[EMBOX:.*]] = fir.embox %[[ZERO]](%[[SHAPE]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
-! CHECK: fir.store %[[EMBOX]] to %[[COORD_A]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[b_DECL:.*]]:2 = hlfir.declare %[[b]]
+! CHECK: hlfir.assign %{{.*}} to %[[b_DECL]]#0
 ! CHECK-NOT: fir.call @_FortranADestroy
-! CHECK: fir.call @_FortranAAssign(
-! CHECK: fir.call @_FortranADestroy(
+! CHECK: fir.call @_FortranADestroy
 
   function no_func_ret_finalize() result(ty)
     type(t1) :: ty
@@ -218,7 +196,7 @@ function no_func_ret_finalize() result(ty)
   end function
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPno_func_ret_finalize() -> !fir.type<_QMderived_type_finalizationTt1{a:i32}> {
-! CHECK: fir.call @_FortranAAssign
+! CHECK: hlfir.assign
 ! CHECK-NOT: fir.call @_FortranADestroy
 ! CHECK: return %{{.*}} : !fir.type<_QMderived_type_finalizationTt1{a:i32}>
 
@@ -235,11 +213,9 @@ subroutine test_avoid_double_free()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPtest_avoid_double_free() {
-! CHECK: %[[RES:.*]] = fir.alloca !fir.class<!fir.heap<!fir.array<?x!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>> {bindc_name = ".result"}
 ! CHECK: fir.call @_FortranAAllocatableAllocateSource(
-! CHECK-NOT: fir.freemem %{{.*}} : !fir.heap<!fir.array<?x!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
-! CHECK: %[[RES_CONV:.*]] = fir.convert %[[RES]] : (!fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>>>) -> !fir.box<none>
-! CHECK: fir.call @_FortranADestroy(%[[RES_CONV]]) {{.*}} : (!fir.box<none>) -> ()
+! CHECK: fir.call @_FortranADestroy
+! CHECK: fir.call @_FortranAAllocatableDeallocatePolymorphic
 
   subroutine t4_final(this)
     type(t4) :: this
@@ -250,7 +226,7 @@ subroutine local_t4()
   end subroutine
 
 ! CHECK-LABEL: func.func @_QMderived_type_finalizationPlocal_t4()
-! CHECK: fir.call @_FortranADestroy(%2) fastmath<contract> : (!fir.box<none>) -> ()
+! CHECK: fir.call @_FortranADestroy(%{{.*}}) fastmath<contract> : (!fir.box<none>) -> ()
 
 end module
 
diff --git a/flang/test/Lower/forall/forall-allocatable-2.f90 b/flang/test/Lower/forall/forall-allocatable-2.f90
index c6b8232fa4ede..730ae1ab4e6c6 100644
--- a/flang/test/Lower/forall/forall-allocatable-2.f90
+++ b/flang/test/Lower/forall/forall-allocatable-2.f90
@@ -1,6 +1,6 @@
 ! Test forall lowering
 
-! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s
 
 subroutine forall_with_allocatable2(a1)
   real :: a1(:)
@@ -14,49 +14,43 @@ subroutine forall_with_allocatable2(a1)
   end forall
 end subroutine forall_with_allocatable2
 
-! CHECK-LABEL: func @_QPforall_with_allocatable2(
-! CHECK-SAME:                                    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>>{{.*}}) {
-! CHECK:         %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"}
-! CHECK:         %[[VAL_2:.*]] = 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_3:.*]] = fir.coordinate_of %[[VAL_2]], 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_4:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
-! CHECK:         %[[VAL_5:.*]] = arith.constant 0 : index
-! CHECK:         %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
-! CHECK:         %[[VAL_7:.*]] = fir.embox %[[VAL_4]](%[[VAL_6]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
-! CHECK:         fir.store %[[VAL_7]] to %[[VAL_3]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:         %[[VAL_9:.*]] = arith.constant 5 : i32
-! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index
+! CHECK-LABEL: func.func @_QPforall_with_allocatable2(
+! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a1"}) {
+! CHECK:         %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
+! CHECK:         %[[VAL_2:.*]]: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_3:.*]] = 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_4:.*]]:2 = hlfir.declare %[[VAL_3]] {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_5:.*]] = fir.coordinate_of %[[VAL_4]]#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_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_10:.*]] = arith.constant 5 : i32
 ! CHECK:         %[[VAL_11:.*]] = arith.constant 15 : i32
-! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i32) -> index
-! CHECK:         %[[VAL_13:.*]] = arith.constant 1 : index
-! CHECK:         %[[VAL_15:.*]] = fir.coordinate_of %[[VAL_2]], 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_16:.*]] = fir.load %[[VAL_15]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:         %[[VAL_17:.*]] = arith.constant 0 : index
-! CHECK:         %[[VAL_18:.*]]:3 = fir.box_dims %[[VAL_16]], %[[VAL_17]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
-! CHECK:         %[[VAL_19:.*]] = fir.box_addr %[[VAL_16]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-! CHECK:         %[[VAL_20:.*]] = fir.shape_shift %[[VAL_18]]#0, %[[VAL_18]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:         %[[VAL_21:.*]] = fir.array_load %[[VAL_19]](%[[VAL_20]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.array<?xf32>
-! CHECK:         %[[VAL_22:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?xf32>>) -> !fir.array<?xf32>
-! CHECK:         %[[VAL_23:.*]] = fir.do_loop %[[VAL_24:.*]] = %[[VAL_10]] to %[[VAL_12]] step %[[VAL_13]] unordered iter_args(%[[VAL_25:.*]] = %[[VAL_21]]) -> (!fir.array<?xf32>) {
-! CHECK:           %[[VAL_26:.*]] = fir.convert %[[VAL_24]] : (index) -> i32
-! CHECK:           fir.store %[[VAL_26]] to %[[VAL_1]] : !fir.ref<i32>
-! CHECK:           %[[VAL_27:.*]] = arith.constant 1 : index
-! CHECK:           %[[VAL_28:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
-! CHECK:           %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i32) -> i64
-! CHECK:           %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i64) -> index
-! CHECK:           %[[VAL_31:.*]] = arith.subi %[[VAL_30]], %[[VAL_27]] : index
-! CHECK:           %[[VAL_32:.*]] = fir.array_fetch %[[VAL_22]], %[[VAL_31]] : (!fir.array<?xf32>, index) -> f32
-! CHECK:           %[[VAL_33:.*]] = arith.constant 1 : index
-! CHECK:           %[[VAL_34:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32>
-! CHECK:           %[[VAL_35:.*]] = fir.convert %[[VAL_34]] : (i32) -> i64
-! CHECK:           %[[VAL_36:.*]] = fir.convert %[[VAL_35]] : (i64) -> index
-! CHECK:           %[[VAL_37:.*]] = arith.subi %[[VAL_36]], %[[VAL_33]] : index
-! CHECK:           %[[VAL_38:.*]] = fir.array_update %[[VAL_25]], %[[VAL_32]], %[[VAL_37]] : (!fir.array<?xf32>, f32, index) -> !fir.array<?xf32>
-! CHECK:           fir.result %[[VAL_38]] : !fir.array<?xf32>
+! CHECK:         hlfir.forall lb {
+! CHECK:           hlfir.yield %[[VAL_10]] : i32
+! CHECK:         } ub {
+! CHECK:           hlfir.yield %[[VAL_11]] : i32
+! CHECK:         }  (%[[VAL_12:.*]]: i32) {
+! CHECK:           %[[VAL_13:.*]] = hlfir.forall_index "i" %[[VAL_12]] : (i32) -> !fir.ref<i32>
+! CHECK:           hlfir.region_assign {
+! CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
+! CHECK:             %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> i64
+! CHECK:             %[[VAL_16:.*]] = hlfir.designate %[[VAL_2]]#0 (%[[VAL_15]])  : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
+! CHECK:             %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<f32>
+! CHECK:             hlfir.yield %[[VAL_17]] : f32
+! CHECK:           } to {
+! CHECK:             %[[VAL_18:.*]] = hlfir.designate %[[VAL_4]]#0{"arr"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_19:.*]] = fir.load %[[VAL_18]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:             %[[VAL_20:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
+! CHECK:             %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i32) -> i64
+! CHECK:             %[[VAL_22:.*]] = hlfir.designate %[[VAL_19]] (%[[VAL_21]])  : (!fir.box<!fir.heap<!fir.array<?xf32>>>, i64) -> !fir.ref<f32>
+! CHECK:             hlfir.yield %[[VAL_22]] : !fir.ref<f32>
+! CHECK:           }
 ! CHECK:         }
-! CHECK:         fir.array_merge_store %[[VAL_21]], %[[VAL_39:.*]] to %[[VAL_19]] : !fir.array<?xf32>, !fir.array<?xf32>, !fir.heap<!fir.array<?xf32>>
-! CHECK:         %[[VAL_40:.*]] = fir.embox %[[VAL_2]] : (!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_41:.*]] = fir.convert %[[VAL_40]] : (!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_41]])
+! CHECK:         %[[VAL_23:.*]] = fir.embox %[[VAL_4]]#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_24:.*]] = fir.convert %[[VAL_23]] : (!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_24]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:         return
 ! CHECK:       }

>From 050c5edc8ed16e5285285af979168f5e104b4aca Mon Sep 17 00:00:00 2001
From: hechenxi <hechenxi at bosc.ac.cn>
Date: Thu, 9 Apr 2026 13:55:23 +0800
Subject: [PATCH 7/7] Update test files

---
 .../Lower/HLFIR/structure-constructor.f90     | 160 +++++++++---------
 .../Lower/OpenMP/private-derived-type.f90     |   6 +-
 flang/test/Lower/call-copy-in-out.f90         |   5 +-
 flang/test/Lower/default-initialization.f90   |  57 +++----
 .../test/Lower/derived-type-finalization.f90  |   4 +-
 flang/test/Lower/derived-type-temp.f90        |   2 +-
 .../Lower/forall/forall-allocatable-2.f90     |  60 +++----
 7 files changed, 143 insertions(+), 151 deletions(-)

diff --git a/flang/test/Lower/HLFIR/structure-constructor.f90 b/flang/test/Lower/HLFIR/structure-constructor.f90
index 871bd645b41c3..f2d2c094198b3 100644
--- a/flang/test/Lower/HLFIR/structure-constructor.f90
+++ b/flang/test/Lower/HLFIR/structure-constructor.f90
@@ -38,13 +38,12 @@ end subroutine test1
 ! CHECK-LABEL:   func.func @_QPtest1(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.boxchar<1> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}> {bindc_name = "res", uniq_name = "_QFtest1Eres"}
 ! CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest1Eres"} : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>)
 ! CHECK:           %[[VAL_4:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK:           %[[VAL_5:.*]] = fir.convert %[[VAL_4]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,4>>
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_6]] dummy_scope %[[SCOPE]] arg 1 {uniq_name = "_QFtest1Ex"} : (!fir.ref<!fir.char<1,4>>, index, !fir.dscope) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
+! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_6]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest1Ex"} : (!fir.ref<!fir.char<1,4>>, index, !fir.dscope) -> (!fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>)
 ! CHECK:           %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>)
 ! CHECK:           %[[VAL_9:.*]] = fir.embox %[[VAL_8]]#0 : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> !fir.box<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
 ! CHECK:           %[[VAL_10:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -52,9 +51,9 @@ end subroutine test1
 ! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_9]] : (!fir.box<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> !fir.box<none>
 ! CHECK:           %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
 ! CHECK:           fir.call @_FortranAInitialize(%[[VAL_12]], %[[VAL_13]], %[[VAL_11]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_14:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_15:.*]] = hlfir.designate %[[VAL_8]]#0{"c"}   typeparams %[[VAL_14]] : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, index) -> !fir.ref<!fir.char<1,4>>
-! CHECK:           hlfir.assign %[[VAL_7]]#0 to %[[VAL_15]] temporary_lhs : !fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
+! CHECK:           %[[VAL_15:.*]] = arith.constant 4 : index
+! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_8]]#0{"c"}   typeparams %[[VAL_15]] : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, index) -> !fir.ref<!fir.char<1,4>>
+! CHECK:           hlfir.assign %[[VAL_7]]#0 to %[[VAL_16]] temporary_lhs : !fir.ref<!fir.char<1,4>>, !fir.ref<!fir.char<1,4>>
 ! CHECK:           hlfir.assign %[[VAL_8]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>
 ! CHECK:           return
 ! CHECK:         }
@@ -68,12 +67,11 @@ end subroutine test2
 ! CHECK-LABEL:   func.func @_QPtest2(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_2:.*]] = fir.alloca !fir.type<_QMtypesTt2{i:!fir.array<10xi32>}> {bindc_name = "res", uniq_name = "_QFtest2Eres"}
 ! CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest2Eres"} : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>)
 ! CHECK:           %[[VAL_4:.*]] = arith.constant 10 : index
 ! CHECK:           %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1>
-! CHECK:           %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_5]]) dummy_scope %[[SCOPE]] arg 1 {uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
+! CHECK:           %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_5]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest2Ex"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "ctor.temp"} : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>)
 ! CHECK:           %[[VAL_8:.*]] = fir.embox %[[VAL_7]]#0 : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> !fir.box<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>
 ! CHECK:           %[[VAL_9:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -81,10 +79,10 @@ end subroutine test2
 ! CHECK:           %[[VAL_11:.*]] = fir.convert %[[VAL_8]] : (!fir.box<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>) -> !fir.box<none>
 ! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_9]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
 ! CHECK:           fir.call @_FortranAInitialize(%[[VAL_11]], %[[VAL_12]], %[[VAL_10]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_13:.*]] = arith.constant 10 : index
-! CHECK:           %[[VAL_14:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1>
-! CHECK:           %[[VAL_15:.*]] = hlfir.designate %[[VAL_7]]#0{"i"} <%[[VAL_14]]>   shape %[[VAL_14]] : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.shape<1>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
-! CHECK:           hlfir.assign %[[VAL_6]]#0 to %[[VAL_15]] temporary_lhs : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>
+! CHECK:           %[[VAL_14:.*]] = arith.constant 10 : index
+! CHECK:           %[[VAL_15:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1>
+! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_7]]#0{"i"} <%[[VAL_15]]>   shape %[[VAL_15]] : (!fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.shape<1>, !fir.shape<1>) -> !fir.ref<!fir.array<10xi32>>
+! CHECK:           hlfir.assign %[[VAL_6]]#0 to %[[VAL_16]] temporary_lhs : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>
 ! CHECK:           hlfir.assign %[[VAL_7]]#0 to %[[VAL_3]]#0 : !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>, !fir.ref<!fir.type<_QMtypesTt2{i:!fir.array<10xi32>}>>
 ! CHECK:           return
 ! CHECK:         }
@@ -98,7 +96,6 @@ end subroutine test3
 ! CHECK-LABEL:   func.func @_QPtest3(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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:           %[[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>>>>
@@ -107,22 +104,22 @@ end subroutine test3
 ! 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_9:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] arg 1 {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_10:.*]]: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_11:.*]] = fir.embox %[[VAL_10]]#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>>>}>>
-! CHECK:           %[[VAL_12:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
-! CHECK:           %[[VAL_13:.*]] = arith.constant {{[0-9]*}} : i32
-! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_11]] : (!fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<none>
-! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
-! CHECK:           fir.call @_FortranAInitialize(%[[VAL_14]], %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_10]]#0{"r"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           %[[VAL_17:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           %[[VAL_18:.*]] = arith.constant 0 : index
-! CHECK:           %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_17]], %[[VAL_18]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
-! CHECK:           %[[VAL_20:.*]] = fir.shift %[[VAL_19]]#0 : (index) -> !fir.shift<1>
-! CHECK:           %[[VAL_21:.*]] = fir.rebox %[[VAL_17]](%[[VAL_20]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
-! CHECK:           fir.store %[[VAL_21]] to %[[VAL_16]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           hlfir.assign %[[VAL_10]]#0 to %[[VAL_3]]#0 : !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_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>>>}>>
+! CHECK:           %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
+! CHECK:           %[[VAL_14:.*]] = arith.constant {{[0-9]*}} : i32
+! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.box<none>
+! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+! CHECK:           fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:           %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"r"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMtypesTt3{r:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           %[[VAL_19:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           %[[VAL_20:.*]] = arith.constant 0 : index
+! CHECK:           %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_19]], %[[VAL_20]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
+! CHECK:           %[[VAL_22:.*]] = fir.shift %[[VAL_21]]#0 : (index) -> !fir.shift<1>
+! CHECK:           %[[VAL_23:.*]] = fir.rebox %[[VAL_19]](%[[VAL_22]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
+! CHECK:           fir.store %[[VAL_23]] to %[[VAL_18]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#0 : !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:           return
 ! CHECK:         }
 
@@ -135,7 +132,6 @@ end subroutine test4
 ! CHECK-LABEL:   func.func @_QPtest4(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>> {fir.bindc_name = "x"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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:           %[[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>>>>>
@@ -144,32 +140,33 @@ end subroutine test4
 ! 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_9:.*]] = arith.constant 2 : index
-! CHECK:           %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_0]] typeparams %[[VAL_9]] dummy_scope %[[SCOPE]] arg 1 {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_11:.*]]: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>>>>}>>)
-! CHECK:           %[[VAL_12:.*]] = fir.embox %[[VAL_11]]#0 : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
-! CHECK:           %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
-! CHECK:           %[[VAL_14:.*]] = arith.constant {{[0-9]*}} : i32
-! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
-! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
-! CHECK:           fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_17:.*]] = arith.constant 2 : index
-! CHECK:           %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"c"}   typeparams %[[VAL_17]] {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
-! CHECK:           %[[VAL_19:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
-! CHECK:           %[[VAL_20:.*]] = fir.box_addr %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,2>>>
-! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.char<1,2>>>) -> i64
-! CHECK:           %[[VAL_22:.*]] = arith.constant 0 : i64
-! CHECK:           %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
-! CHECK:           fir.if %[[VAL_23]] {
-! CHECK:             %[[VAL_24:.*]] = fir.load %[[VAL_10]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
-! CHECK:             hlfir.assign %[[VAL_24]] to %[[VAL_18]] realloc keep_lhs_len temporary_lhs : !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_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>>>>}>>)
+! CHECK:           %[[VAL_13:.*]] = fir.embox %[[VAL_12]]#0 : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>
+! CHECK:           %[[VAL_14:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
+! CHECK:           %[[VAL_15:.*]] = arith.constant {{[0-9]*}} : i32
+! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
+! CHECK:           %[[VAL_17:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+! CHECK:           fir.call @_FortranAInitialize(%[[VAL_16]], %[[VAL_17]], %[[VAL_15]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:           %[[VAL_19:.*]] = arith.constant 2 : index
+! CHECK:           %[[VAL_20:.*]] = hlfir.designate %[[VAL_12]]#0{"c"}   typeparams %[[VAL_19]] {fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>, index) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK:           %[[VAL_21:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK:           %[[VAL_22:.*]] = fir.box_addr %[[VAL_21]] : (!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>) -> !fir.heap<!fir.array<?x!fir.char<1,2>>>
+! CHECK:           %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.heap<!fir.array<?x!fir.char<1,2>>>) -> i64
+! CHECK:           %[[VAL_24:.*]] = arith.constant 0 : i64
+! CHECK:           %[[VAL_25:.*]] = arith.cmpi ne, %[[VAL_23]], %[[VAL_24]] : i64
+! CHECK:           fir.if %[[VAL_25]] {
+! CHECK:             %[[VAL_26:.*]] = fir.load %[[VAL_11]]#0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>>
+! CHECK:             hlfir.assign %[[VAL_26]] to %[[VAL_20]] realloc keep_lhs_len temporary_lhs : !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:           }
-! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#0 : !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_25:.*]] = fir.convert %[[VAL_12]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_25]])
+! CHECK:           hlfir.assign %[[VAL_12]]#0 to %[[VAL_3]]#0 : !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_27:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>) -> !fir.box<none>
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_27]]
 ! CHECK:           return
 ! CHECK:         }
 
+
 subroutine test5(x)
   use types
   type(t4), allocatable :: x(:)
@@ -179,7 +176,6 @@ end subroutine test5
 ! CHECK-LABEL:   func.func @_QPtest5(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !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.bindc_name = "x"}) {
 ! 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:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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:           %[[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>>>>}>>>>>
@@ -188,27 +184,27 @@ end subroutine test5
 ! 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_9:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] arg 1 {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_10:.*]]: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_11:.*]] = fir.embox %[[VAL_10]]#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>>>>}>>>>}>>
-! CHECK:           %[[VAL_12:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
-! CHECK:           %[[VAL_13:.*]] = arith.constant {{[0-9]*}} : i32
-! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_11]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
-! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
-! CHECK:           fir.call @_FortranAInitialize(%[[VAL_14]], %[[VAL_15]], %[[VAL_13]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
-! CHECK:           %[[VAL_16:.*]] = hlfir.designate %[[VAL_10]]#0{"t5m"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_17:.*]] = fir.load %[[VAL_9]]#0 : !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_18:.*]] = fir.box_addr %[[VAL_17]] : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>) -> !fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>
-! CHECK:           %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>) -> i64
-! CHECK:           %[[VAL_20:.*]] = arith.constant 0 : i64
-! CHECK:           %[[VAL_21:.*]] = arith.cmpi ne, %[[VAL_19]], %[[VAL_20]] : i64
-! CHECK:           fir.if %[[VAL_21]] {
-! CHECK:             %[[VAL_22:.*]] = fir.load %[[VAL_9]]#0 : !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:             hlfir.assign %[[VAL_22]] to %[[VAL_16]] realloc temporary_lhs : !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_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>>>>}>>>>}>>
+! CHECK:           %[[VAL_13:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
+! CHECK:           %[[VAL_14:.*]] = arith.constant {{[0-9]*}} : i32
+! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_12]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
+! CHECK:           %[[VAL_16:.*]] = fir.convert %[[VAL_13]] : (!fir.ref<!fir.char<1,{{[0-9]*}}>>) -> !fir.ref<i8>
+! CHECK:           fir.call @_FortranAInitialize(%[[VAL_15]], %[[VAL_16]], %[[VAL_14]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
+! CHECK:           %[[VAL_18:.*]] = hlfir.designate %[[VAL_11]]#0{"t5m"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_19:.*]] = fir.load %[[VAL_10]]#0 : !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:.*]] = fir.box_addr %[[VAL_19]] : (!fir.box<!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>>) -> !fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>
+! CHECK:           %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (!fir.heap<!fir.array<?x!fir.type<_QMtypesTt4{c:!fir.box<!fir.heap<!fir.array<?x!fir.char<1,2>>>>}>>>) -> i64
+! CHECK:           %[[VAL_22:.*]] = arith.constant 0 : i64
+! CHECK:           %[[VAL_23:.*]] = arith.cmpi ne, %[[VAL_21]], %[[VAL_22]] : i64
+! CHECK:           fir.if %[[VAL_23]] {
+! CHECK:             %[[VAL_24:.*]] = fir.load %[[VAL_10]]#0 : !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:             hlfir.assign %[[VAL_24]] to %[[VAL_18]] realloc temporary_lhs : !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:           }
-! CHECK:           hlfir.assign %[[VAL_10]]#0 to %[[VAL_3]]#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.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_23:.*]] = fir.convert %[[VAL_11]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_23]])
+! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_3]]#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.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_24:.*]] = fir.convert %[[VAL_12]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_24]]
 ! CHECK:           return
 ! CHECK:         }
 
@@ -227,11 +223,10 @@ end subroutine test6
 ! CHECK:           %[[VAL_4:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>> {bindc_name = ".tmp.arrayctor"}
 ! CHECK:           %[[VAL_5:.*]] = 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_6:.*]] = 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>}>>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_7:.*]]:2 = fir.unboxchar %[[VAL_1]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
 ! CHECK:           %[[VAL_8:.*]] = fir.convert %[[VAL_7]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.char<1,4>>
 ! CHECK:           %[[VAL_9:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_8]] typeparams %[[VAL_9]] dummy_scope %[[SCOPE]] arg 2 {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_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:           %[[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>>>>}>>>>}>>
@@ -241,7 +236,7 @@ end subroutine test6
 ! 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 %[[SCOPE]] arg 1 {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_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>}>>}>>
 ! CHECK:           %[[VAL_22:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref<!fir.char<1,{{[0-9]*}}>>
@@ -301,9 +296,9 @@ end subroutine test6
 ! CHECK:           hlfir.assign %[[VAL_70]] to %[[VAL_44]] temporary_lhs : !hlfir.expr<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.array<1x!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>>
 ! CHECK:           hlfir.assign %[[VAL_20]]#0 to %[[VAL_12]]#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.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_71:.*]] = fir.convert %[[VAL_21]] : (!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>}>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_71]])
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_71]]
 ! CHECK:           %[[VAL_72:.*]] = fir.convert %[[VAL_29]] : (!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>>>>}>>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_72]])
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_72]]
 ! CHECK:           return
 ! CHECK:         }
 
@@ -321,8 +316,7 @@ end subroutine test7
 ! CHECK-LABEL:   func.func @_QPtest7(
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) {
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt7{c1:i32,c2:!fir.box<!fir.heap<!fir.array<?xf32>>>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[SCOPE]] arg 1 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest7En"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
+! 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:           %[[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>>>>
@@ -357,7 +351,6 @@ subroutine test8
 end subroutine test8
 ! CHECK-LABEL:   func.func @_QPtest8() {
 ! CHECK:           %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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:           %[[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>>>>
@@ -391,7 +384,7 @@ end subroutine test8
 ! CHECK:           }
 ! CHECK:           hlfir.assign %[[VAL_14]]#0 to %[[VAL_2]]#0 : !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_30:.*]] = fir.convert %[[VAL_15]] : (!fir.box<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_30]])
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_30]]
 ! CHECK:           return
 ! CHECK:         }
 
@@ -405,7 +398,6 @@ subroutine test9
 end subroutine test9
 ! CHECK-LABEL:   func.func @_QPtest9() {
 ! CHECK:           %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! 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:           %[[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>>>>
@@ -427,10 +419,11 @@ end subroutine test9
 ! CHECK:           hlfir.assign %[[VAL_11]]#0 to %[[VAL_20]] realloc keep_lhs_len temporary_lhs : !fir.ref<!fir.char<1,12>>, !fir.ref<!fir.box<!fir.heap<!fir.char<1,11>>>>
 ! CHECK:           hlfir.assign %[[VAL_12]]#0 to %[[VAL_2]]#0 : !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_21:.*]] = fir.convert %[[VAL_13]] : (!fir.box<!fir.type<_QMtypesTt8{c:!fir.box<!fir.heap<!fir.char<1,11>>>}>>) -> !fir.box<none>
-! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_21]])
+! CHECK:           fir.call @_FortranADestroyWithoutFinalization(%[[VAL_21]]
 ! CHECK:           return
 ! CHECK:         }
 
+
 ! Test character non-allocatable component initialization
 ! from character allocatable of different size.
 subroutine test10
@@ -441,7 +434,6 @@ subroutine test10
 end subroutine test10
 ! CHECK-LABEL:   func.func @_QPtest10() {
 ! CHECK:           %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}>
-! CHECK:           %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK:           %[[VAL_1:.*]] = fir.alloca !fir.type<_QMtypesTt1{c:!fir.char<1,4>}> {bindc_name = "res", uniq_name = "_QFtest10Eres"}
 ! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtest10Eres"} : (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>) -> (!fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>, !fir.ref<!fir.type<_QMtypesTt1{c:!fir.char<1,4>}>>)
 ! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,12>>> {bindc_name = "x", uniq_name = "_QFtest10Ex"}
diff --git a/flang/test/Lower/OpenMP/private-derived-type.f90 b/flang/test/Lower/OpenMP/private-derived-type.f90
index fef0867045703..c286ea29c62aa 100644
--- a/flang/test/Lower/OpenMP/private-derived-type.f90
+++ b/flang/test/Lower/OpenMP/private-derived-type.f90
@@ -16,12 +16,12 @@ subroutine s4
 end subroutine s4
 
 ! CHECK:  omp.private {type = private} @[[DERIVED_PRIV:.*]] : !fir.type<{{.*}}y3{x:!fir.box<!fir.heap<i32>>}> init {
-! CHECK:             %[[VAL_25:.*]] = fir.embox %{{.*}} : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
+! CHECK:             %[[VAL_25:.*]] = fir.embox %[[VAL_23:.*]] : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
 ! CHECK:             %[[VAL_26:.*]] = fir.address_of
 ! CHECK:             %[[VAL_27:.*]] = arith.constant 8 : i32
 ! CHECK:             %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<none>
 ! CHECK:             %[[VAL_29:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,{{.*}}>>) -> !fir.ref<i8>
-! Check we do call FortranAInitialize on the derived type
+!                    Check we do call FortranAInitialize on the derived type
 ! CHECK:             fir.call @_FortranAInitialize(%[[VAL_28]], %[[VAL_29]], %[[VAL_27]]) fastmath<contract> : (!fir.box<none>, !fir.ref<i8>, i32) -> ()
 ! CHECK:  }
 
@@ -38,7 +38,7 @@ end subroutine s4
 ! CHECK:           }
 ! CHECK:           %[[VAL_39:.*]] = fir.embox %[[VAL_DERIVED_DECLARE]]#0 : (!fir.ref<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>
 ! CHECK:           %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (!fir.box<!fir.type<_QFs4Ty3{x:!fir.box<!fir.heap<i32>>}>>) -> !fir.box<none>
-! Check the derived type is destroyed
+!                  Check the derived type is destroyed
 ! CHECK:           fir.call @_FortranADestroy(%[[VAL_40]]) fastmath<contract> : (!fir.box<none>) -> ()
 ! CHECK:           return
 ! CHECK:         }
diff --git a/flang/test/Lower/call-copy-in-out.f90 b/flang/test/Lower/call-copy-in-out.f90
index 2fc78fcf1e65c..e29c106d67c40 100644
--- a/flang/test/Lower/call-copy-in-out.f90
+++ b/flang/test/Lower/call-copy-in-out.f90
@@ -68,7 +68,7 @@ subroutine bar_intent_out(x)
   call bar_intent_out(x)
 end subroutine
 
-! Test copy-out is skipped for intent(in) arguments.
+! Test copy-out is skipped for intent(out) arguments.
 ! CHECK-LABEL: func.func @_QPtest_intent_in(
 subroutine test_intent_in(x)
   real :: x(:)
@@ -79,7 +79,8 @@ subroutine bar_intent_in(x)
   end interface
 ! CHECK: hlfir.copy_in
 ! CHECK: fir.call @_QPbar_intent_in
-! CHECK: hlfir.copy_out %{{.*}}, %{{.*}} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, i1) -> ()
+! CHECK: hlfir.copy_out
+! 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/default-initialization.f90 b/flang/test/Lower/default-initialization.f90
index c2a4673c537af..76e29587dffb9 100644
--- a/flang/test/Lower/default-initialization.f90
+++ b/flang/test/Lower/default-initialization.f90
@@ -21,9 +21,9 @@ module test_dinit
   ! Test local scalar is default initialized
   ! CHECK-LABEL: func @_QMtest_dinitPlocal()
   subroutine local
-    !CHECK: %[[x:.*]]  = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocalEx"}
-    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
-    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+    !CHECK: %[[x:.*]]  = fir.alloca !fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocalEx"}
+    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
     type(t) :: x
     print *, x%i
   end subroutine
@@ -31,9 +31,9 @@ subroutine local
   ! Test local array is default initialized
   ! CHECK-LABEL: func @_QMtest_dinitPlocal_array()
   subroutine local_array()
-    ! CHECK: %[[x:.*]] = fir.alloca !fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>
+    ! CHECK: %[[x:.*]] = fir.alloca !fir.array<4x!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
     ! CHECK: %[[xshape:.*]] = fir.shape %c4{{.*}} : (index) -> !fir.shape<1>
-    ! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshape]]) : (!fir.ref<!fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<4x!fir.type<_QMtest_dinitTt{i:i32}>>>
+    ! CHECK: %[[xbox:.*]] = fir.embox %[[x]](%[[xshape]]) : (!fir.ref<!fir.array<4x!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>>, !fir.shape<1>) -> !fir.box<!fir.array<4x!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>>
     ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
     ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> ()
     type(t) :: x(4)
@@ -44,7 +44,7 @@ subroutine local_array()
   ! scalars.
   ! CHECK-LABEL: func @_QMtest_dinitPlocal_alloc_comp()
   subroutine local_alloc_comp
-    !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt_alloc_comp{i:!fir.box<!fir.heap<!fir.array<?xf32>>>}> {bindc_name = "x", uniq_name = "_QMtest_dinitFlocal_alloc_compEx"}
+    !CHECK: %[[x:.*]] = 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: %[[COORD:.*]] = fir.coordinate_of %[[x]], 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>
@@ -54,31 +54,31 @@ subroutine local_alloc_comp
   end subroutine
 
   ! Test function results are default initialized.
-  ! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{i:i32}>
+  ! CHECK-LABEL: func @_QMtest_dinitPresult() -> !fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>
   function result()
-    !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{i:i32}> {bindc_name = "result", uniq_name = "_QMtest_dinitFresultEresult"}
-    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
-    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+    !CHECK: %[[x:.*]] = fir.alloca !fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}> {bindc_name = "result", uniq_name = "_QMtest_dinitFresultEresult"}
+    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
     type(t) :: result
   end function
 
   ! Test intent(out) dummies are default initialized
   ! CHECK-LABEL: func @_QMtest_dinitPintent_out(
-  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
   subroutine intent_out(x)
-    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
-    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>
+    !CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTt.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
+    !CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>, !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
     type(t), intent(out) :: x
   end subroutine
 
   ! Test that optional intent(out) are default initialized only when
   ! present.
   ! CHECK-LABEL: func @_QMtest_dinitPintent_out_optional(
-  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>> {fir.bindc_name = "x", fir.optional})
+  ! CHECK-SAME: %[[x:.*]]: !fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>> {fir.bindc_name = "x", fir.optional})
   subroutine intent_out_optional(x)
-    ! CHECK: %[[isPresent:.*]] = fir.is_present %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> i1
+    ! CHECK: %[[isPresent:.*]] = fir.is_present %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>) -> i1
     ! CHECK: fir.if %[[isPresent]] {
-      ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{i:i32}>>
+      ! CHECK: %[[xbox:.*]] = fir.embox %[[x]] : (!fir.ref<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>) -> !fir.box<!fir.type<_QMtest_dinitTt{{(,sequence)?}}{i:i32}>>
       ! CHECK: %[[xboxNone:.*]] = fir.convert %[[xbox]]
       ! CHECK: fir.call @_FortranAInitialize(%[[xboxNone]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.box<none>, !fir.ref<i8>, i32) -> ()
     ! CHECK: }
@@ -92,33 +92,32 @@ subroutine local_eq()
     integer :: zi
     ! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8>
     ! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
-    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
-    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>
-    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
     equivalence (x, zi)
     print *, i
   end subroutine
 
   ! Test local equivalences with both equivalenced entities being
-  ! default initialized.
-  ! Note that the standard allow default initialization
-  ! to be performed several times as long as the values are the same.
-  ! So far that is what lowering is doing to stay simple.
+  ! default initialized. Note that the standard allow default initialization
+  ! to be performed several times as long as the values are the same. So
+  ! far that is what lowering is doing to stay simple.
   ! CHECK-LABEL: func @_QMtest_dinitPlocal_eq2()
   subroutine local_eq2()
     type(tseq) :: x
     type(tseq) :: y
     ! CHECK: %[[equiv:.*]] = fir.alloca !fir.array<4xi8>
     ! CHECK: %[[xcoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
-    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
-    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>
-    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: %[[x:.*]] = fir.convert %[[xcoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: fir.copy %[[ADDR]] to %[[x]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
 
 
     ! CHECK: %[[ycoor:.*]] = fir.coordinate_of %[[equiv]], %c0{{.*}} : (!fir.ref<!fir.array<4xi8>>, index) -> !fir.ref<i8>
-    ! CHECK: %[[y:.*]] = fir.convert %[[ycoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
-    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>
-    ! CHECK: fir.copy %[[ADDR]] to %[[y]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{i:i32}>>
+    ! CHECK: %[[y:.*]] = fir.convert %[[ycoor]] : (!fir.ref<i8>) -> !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: %[[ADDR:.*]] = fir.address_of(@_QQ_QMtest_dinitTtseq.DerivedInit) : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
+    ! CHECK: fir.copy %[[ADDR]] to %[[y]] no_overlap : !fir.ref<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>, !fir.ptr<!fir.type<_QMtest_dinitTtseq{{(,sequence)?}}{i:i32}>>
     equivalence (x, y)
     print *, y%i
   end subroutine
diff --git a/flang/test/Lower/derived-type-finalization.f90 b/flang/test/Lower/derived-type-finalization.f90
index 032c82b9de04e..6c4b5f6e2b02c 100644
--- a/flang/test/Lower/derived-type-finalization.f90
+++ b/flang/test/Lower/derived-type-finalization.f90
@@ -140,8 +140,8 @@ subroutine test_fct_ref()
 ! CHECK: %[[RES:.*]] = fir.alloca !fir.type<_QMderived_type_finalizationTt1{a:i32}> {bindc_name = ".result"}
 ! CHECK: %[[TY:.*]] = fir.alloca !fir.box<!fir.heap<!fir.type<_QMderived_type_finalizationTt1{a:i32}>>>
 ! CHECK: %[[TY_DECL:.*]]:2 = hlfir.declare %[[TY]]
-! CHECK: %[[CALL_RES:.*]] = fir.call @_QMderived_type_finalizationPret_type() fastmath<contract> : () -> !fir.type<_QMderived_type_finalizationTt1{a:i32}>
-! CHECK: fir.save_result %[[CALL_RES]] to %[[RES]]
+! CHECK: %[[CALL_RES:.*]] = fir.call @_QMderived_type_finalizationPret_type()
+! CHECK: fir.save_result %[[CALL_RES]] to %[[RES]] :
 ! CHECK: %[[RES_DECL:.*]]:2 = hlfir.declare %[[RES]]
 ! CHECK: hlfir.assign %[[RES_DECL]]#0 to %[[TY_DECL]]#0 realloc
 ! CHECK: fir.call @_FortranADestroy(%{{.*}})
diff --git a/flang/test/Lower/derived-type-temp.f90 b/flang/test/Lower/derived-type-temp.f90
index 3e5e3b8e0a9e1..c2ee34e53ba7f 100644
--- a/flang/test/Lower/derived-type-temp.f90
+++ b/flang/test/Lower/derived-type-temp.f90
@@ -13,7 +13,7 @@ program derived_temp_init
   y = t2(x)
 end
 
-! CHECK: %[[ALLOC:.*]] = fir.alloca !fir.type<_QFTt1{i:!fir.box<!fir.heap<i32>>}> {bindc_name = "x", uniq_name = "_QFEx"}
+! 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: %[[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>
diff --git a/flang/test/Lower/forall/forall-allocatable-2.f90 b/flang/test/Lower/forall/forall-allocatable-2.f90
index 730ae1ab4e6c6..513d2f6731f1d 100644
--- a/flang/test/Lower/forall/forall-allocatable-2.f90
+++ b/flang/test/Lower/forall/forall-allocatable-2.f90
@@ -15,42 +15,42 @@ subroutine forall_with_allocatable2(a1)
 end subroutine forall_with_allocatable2
 
 ! CHECK-LABEL: func.func @_QPforall_with_allocatable2(
-! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a1"}) {
+! CHECK-SAME:                                         %[[VAL_0:.*]]: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "a1"}) {
 ! CHECK:         %[[VAL_1:.*]] = fir.dummy_scope : !fir.dscope
-! CHECK:         %[[VAL_2:.*]]: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_3:.*]] = 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_4:.*]]:2 = hlfir.declare %[[VAL_3]] {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_5:.*]] = fir.coordinate_of %[[VAL_4]]#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_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_10:.*]] = arith.constant 5 : i32
-! CHECK:         %[[VAL_11:.*]] = arith.constant 15 : i32
+! 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_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 {
-! CHECK:           hlfir.yield %[[VAL_10]] : i32
-! CHECK:         } ub {
 ! CHECK:           hlfir.yield %[[VAL_11]] : i32
-! CHECK:         }  (%[[VAL_12:.*]]: i32) {
-! CHECK:           %[[VAL_13:.*]] = hlfir.forall_index "i" %[[VAL_12]] : (i32) -> !fir.ref<i32>
+! CHECK:         } ub {
+! CHECK:           hlfir.yield %[[VAL_12]] : i32
+! CHECK:         }  (%[[VAL_13:.*]]: i32) {
+! CHECK:           %[[VAL_14:.*]] = hlfir.forall_index "i" %[[VAL_13]] : (i32) -> !fir.ref<i32>
 ! CHECK:           hlfir.region_assign {
-! CHECK:             %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
-! CHECK:             %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (i32) -> i64
-! CHECK:             %[[VAL_16:.*]] = hlfir.designate %[[VAL_2]]#0 (%[[VAL_15]])  : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
-! CHECK:             %[[VAL_17:.*]] = fir.load %[[VAL_16]] : !fir.ref<f32>
-! CHECK:             hlfir.yield %[[VAL_17]] : f32
+! CHECK:             %[[VAL_15:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
+! CHECK:             %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64
+! CHECK:             %[[VAL_17:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_16]])  : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>
+! CHECK:             %[[VAL_18:.*]] = fir.load %[[VAL_17]] : !fir.ref<f32>
+! CHECK:             hlfir.yield %[[VAL_18]] : f32
 ! CHECK:           } to {
-! CHECK:             %[[VAL_18:.*]] = hlfir.designate %[[VAL_4]]#0{"arr"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_19:.*]] = fir.load %[[VAL_18]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-! CHECK:             %[[VAL_20:.*]] = fir.load %[[VAL_13]] : !fir.ref<i32>
-! CHECK:             %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i32) -> i64
-! CHECK:             %[[VAL_22:.*]] = hlfir.designate %[[VAL_19]] (%[[VAL_21]])  : (!fir.box<!fir.heap<!fir.array<?xf32>>>, i64) -> !fir.ref<f32>
-! CHECK:             hlfir.yield %[[VAL_22]] : !fir.ref<f32>
+! CHECK:             %[[VAL_19:.*]] = hlfir.designate %[[VAL_9]]#0{"arr"}   {fortran_attrs = #fir.var_attrs<allocatable>} : (!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_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:             %[[VAL_21:.*]] = fir.load %[[VAL_14]] : !fir.ref<i32>
+! CHECK:             %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i32) -> i64
+! CHECK:             %[[VAL_23:.*]] = hlfir.designate %[[VAL_20]] (%[[VAL_22]])  : (!fir.box<!fir.heap<!fir.array<?xf32>>>, i64) -> !fir.ref<f32>
+! CHECK:             hlfir.yield %[[VAL_23]] : !fir.ref<f32>
 ! CHECK:           }
 ! CHECK:         }
-! CHECK:         %[[VAL_23:.*]] = fir.embox %[[VAL_4]]#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_24:.*]] = fir.convert %[[VAL_23]] : (!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_24]]) fastmath<contract> : (!fir.box<none>) -> ()
+! 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:       }



More information about the flang-commits mailing list