[flang-commits] [flang] [flang][acc] Preserve association status of privatized pointers (PR #228581)

Razvan Lupusoru via flang-commits flang-commits at lists.llvm.org
Fri Oct 2 13:51:25 PDT 2026


https://github.com/razvanlupusoru created https://github.com/llvm/llvm-project/pull/228581

Privatization allocated a target and copied it even when a Fortran pointer or allocatable was unassociated or unallocated. That reads through a null address. The private allocation now follows the original association status. A reduction stores its initial value only when that storage exists. The target is copied only when one exists.

Before:
```
%private = fir.allocmem f32
// Box %private into the private descriptor.
hlfir.assign %src to %private temporary_lhs : f32, !fir.heap<f32>
```

After:
```
%private = fir.if %is_associated -> !fir.heap<f32> {
  %allocation = fir.allocmem f32
  fir.result %allocation : !fir.heap<f32>
} else {
  %null = fir.zero_bits !fir.heap<f32>
  fir.result %null : !fir.heap<f32>
}
// Box %private into the private descriptor.
fir.if %is_associated {
  hlfir.assign %src to %private temporary_lhs : f32, !fir.heap<f32>
}
```

>From e1cf8af6a05baf2e69b94ff4b81b59ecd9f694f6 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Fri, 2 Oct 2026 13:48:09 -0700
Subject: [PATCH] [flang][acc] Preserve association status of privatized
 pointers

Privatization allocated a target and copied it even when a Fortran
pointer or allocatable was unassociated or unallocated. That reads
through a null address. The private allocation now follows the
original association status. A reduction stores its initial value
only when that storage exists. The target is copied only when one
exists.

Before:
```
%private = fir.allocmem f32
// Box %private into the private descriptor.
hlfir.assign %src to %private temporary_lhs : f32, !fir.heap<f32>
```

After:
```
%private = fir.if %is_associated -> !fir.heap<f32> {
  %allocation = fir.allocmem f32
  fir.result %allocation : !fir.heap<f32>
} else {
  %null = fir.zero_bits !fir.heap<f32>
  fir.result %null : !fir.heap<f32>
}
// Box %private into the private descriptor.
fir.if %is_associated {
  hlfir.assign %src to %private temporary_lhs : f32, !fir.heap<f32>
}
```
---
 .../Support/FIROpenACCTypeInterfaces.cpp      | 102 +++++++++++---
 .../OpenACC/recipe-populate-firstprivate.mlir |  98 +++++++++++++
 .../Fir/OpenACC/recipe-populate-private.mlir  |  58 +++++---
 flang/test/Lower/OpenACC/acc-private.f90      |  66 +++++++--
 flang/test/Lower/OpenACC/acc-reduction.f90    | 132 ++++++++++++------
 5 files changed, 367 insertions(+), 89 deletions(-)

diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index 73be000f701b4..04352914be1ab 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -769,10 +769,17 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
   fir::FirOpBuilder builder(mlirBuilder, mod);
 
   hlfir::Entity inputVar = hlfir::Entity{var};
-  bool preservePointerAllocation =
-      fir::isPointerType(inputVar.getType()) && bounds.empty();
+  // Whole POINTER/ALLOCATABLE: allocate private storage only when the source
+  // is associated or allocated, so the private copy stays null otherwise.
+  // A reduction identity is stored only into that allocated storage.
+  // Reduction init yields only the private variable, so its destroy reloads
+  // that descriptor. Private and firstprivate also yield the allocation.
+  bool preserveNullAllocation =
+      bounds.empty() &&
+      (fir::isPointerType(inputVar.getType()) ||
+       fir::isAllocatableType(inputVar.getType()));
   mlir::Type pointerAllocationType;
-  if (preservePointerAllocation)
+  if (preserveNullAllocation)
     pointerAllocationType =
         fir::HeapType::get(inputVar.getElementOrSequenceType());
 
@@ -788,7 +795,8 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
       mlir::Value cond =
           fir::IsPresentOp::create(builder, loc, builder.getI1Type(), var);
       llvm::SmallVector<mlir::Type> resultTypes{type};
-      if (preservePointerAllocation)
+      // Reduction init cannot yield the allocation alongside the variable.
+      if (preserveNullAllocation && !initVal)
         resultTypes.push_back(pointerAllocationType);
       optIfOp = fir::IfOp::create(builder, loc, resultTypes, cond,
                                   /*withElseRegion=*/true);
@@ -873,16 +881,30 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
     // array POINTER and ALLOCATABLE always have dynamic size. Constant sections
     // of POINTER/ALLOCATABLE can use alloca since only part of the data is
     // privatized (it makes no sense to deallocate them).
-    if (preservePointerAllocation) {
+    if (preserveNullAllocation) {
       mlir::Value originalAddr =
           hlfir::genVariableRawAddress(loc, builder, inputVar);
       mlir::Value isAssociated = builder.genIsNotNullAddr(loc, originalAddr);
       auto ifOp = fir::IfOp::create(
           builder, loc, mlir::TypeRange{pointerAllocationType}, isAssociated,
           /*withElseRegion=*/true);
+      ifOp.setUnlikelyIfWeights(/*unlikelyElse=*/true);
       builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
       mlir::Value privateAllocation = builder.createHeapTemporary(
           loc, baseType, varName, tempExtents, typeParams, {placeholderAttr});
+      // The identity is stored only when storage was allocated. Storing it
+      // after the branch would write through the null result.
+      if (initVal) {
+        mlir::Value tempEntity = privateAllocation;
+        if (fir::hasDynamicSize(baseType))
+          tempEntity = fir::EmboxOp::create(
+              builder, loc, fir::BoxType::get(baseType), privateAllocation,
+              tempShape, /*slice=*/mlir::Value{}, typeParams);
+        hlfir::genNoAliasAssignment(loc, builder, hlfir::Entity{initVal},
+                                    hlfir::Entity{tempEntity},
+                                    /*emitWorkshareLoop=*/false,
+                                    /*temporaryLHS=*/true);
+      }
       fir::ResultOp::create(builder, loc, privateAllocation);
       builder.setInsertionPointToStart(&ifOp.getElseRegion().front());
       fir::ResultOp::create(
@@ -894,7 +916,7 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
                                           typeParams, {placeholderAttr});
     }
     needsDestroy = true;
-    if (preservePointerAllocation) {
+    if (preserveNullAllocation && !initVal) {
       assert(alloc.getType() == pointerAllocationType &&
              "unexpected private pointer allocation type");
       pointerAllocation = alloc;
@@ -904,7 +926,8 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
                                     typeParams, {placeholderAttr});
   }
   // Step3: Assign the initial value to the privatized part if any.
-  if (initVal) {
+  // Pointer and allocatable reductions assign inside the allocated branch.
+  if (initVal && !preserveNullAllocation) {
     mlir::Value tempEntity = alloc;
     if (fir::hasDynamicSize(baseType))
       tempEntity =
@@ -1004,22 +1027,25 @@ mlir::Value OpenACCMappableModel<Ty>::generatePrivateInit(
     retVal = builder.createConvert(loc, type, retVal);
   }
 
+  // Private and firstprivate destroy receives the allocation directly.
+  // A reduction yields only the private variable.
+  bool yieldAllocation = preserveNullAllocation && !initVal;
   if (mayBeOptional) {
     llvm::SmallVector<mlir::Value> thenResults{retVal};
-    if (preservePointerAllocation)
+    if (yieldAllocation)
       thenResults.push_back(pointerAllocation);
     fir::ResultOp::create(builder, loc, thenResults);
     builder.setInsertionPointToStart(&optIfOp->getElseRegion().front());
     mlir::Value absent = fir::AbsentOp::create(builder, loc, type);
     llvm::SmallVector<mlir::Value> elseResults{absent};
-    if (preservePointerAllocation)
+    if (yieldAllocation)
       elseResults.push_back(
           builder.createNullConstant(loc, pointerAllocationType));
     fir::ResultOp::create(builder, loc, elseResults);
     retVal = optIfOp->getResult(0);
-    if (preservePointerAllocation)
+    if (yieldAllocation)
       destroyValues.push_back(optIfOp->getResult(1));
-  } else if (preservePointerAllocation) {
+  } else if (yieldAllocation) {
     destroyValues.push_back(pointerAllocation);
   }
 
@@ -1070,27 +1096,41 @@ bool OpenACCMappableModel<Ty>::generateCopy(
   hlfir::Entity source{src};
   hlfir::Entity destination{dest};
 
-  source = hlfir::derefPointersAndAllocatables(loc, builder, source);
-  destination = hlfir::derefPointersAndAllocatables(loc, builder, destination);
-
   // When optional: only copy when source is present (fir.is_present). When
   // absent, destination is already null from init. When non-optional, copy
-  // directly without the conditional.
+  // directly without the conditional. Presence is separate from association.
+  std::optional<fir::IfOp> presentIf;
   if (auto fortranVarInfo =
           mlir::dyn_cast_if_present<fir::OpenACCFortranVariableInfoAttr>(
               varInfo)) {
     if (fortranVarInfo.getMayBeOptional()) {
       // When variable is optional: use fir.is_present to check. When
       // non-optional, skip the conditional to avoid unnecessary branches.
-      std::optional<fir::IfOp> optIfOp;
       mlir::Value cond =
           fir::IsPresentOp::create(builder, loc, builder.getI1Type(), src);
-      optIfOp = fir::IfOp::create(builder, loc, mlir::TypeRange{}, cond,
-                                  /*withElseRegion=*/false);
-      builder.setInsertionPointToStart(&optIfOp->getThenRegion().front());
+      presentIf = fir::IfOp::create(builder, loc, mlir::TypeRange{}, cond,
+                                    /*withElseRegion=*/false);
+      builder.setInsertionPointToStart(&presentIf->getThenRegion().front());
     }
   }
 
+  // A POINTER or ALLOCATABLE may have a null base address, including when
+  // the recipe covers only a section of it. Test the base address before
+  // dereferencing, and copy only when the variable is associated or allocated.
+  std::optional<fir::IfOp> allocatedIf;
+  if (fir::isPointerType(source.getType()) ||
+      fir::isAllocatableType(source.getType())) {
+    mlir::Value srcAddr = hlfir::genVariableRawAddress(loc, builder, source);
+    mlir::Value isAllocated = builder.genIsNotNullAddr(loc, srcAddr);
+    allocatedIf = fir::IfOp::create(builder, loc, mlir::TypeRange{},
+                                    isAllocated, /*withElseRegion=*/false);
+    allocatedIf->setUnlikelyIfWeights(/*unlikelyElse=*/true);
+    builder.setInsertionPointToStart(&allocatedIf->getThenRegion().front());
+  }
+
+  source = hlfir::derefPointersAndAllocatables(loc, builder, source);
+  destination = hlfir::derefPointersAndAllocatables(loc, builder, destination);
+
   if (!bounds.empty())
     std::tie(source, destination) =
         genArraySectionsInRecipe(builder, loc, bounds, source, destination);
@@ -1111,6 +1151,12 @@ bool OpenACCMappableModel<Ty>::generateCopy(
   hlfir::AssignOp::create(builder, loc, source, destination, /*realloc=*/false,
                           /*keep_lhs_length_if_realloc=*/false,
                           /*temporary_lhs=*/true);
+  // Callers that share this builder append the recipe terminator in the
+  // copy block, after these conditions.
+  if (allocatedIf)
+    builder.setInsertionPointAfter(*allocatedIf);
+  if (presentIf)
+    builder.setInsertionPointAfter(*presentIf);
   return true;
 }
 
@@ -1344,6 +1390,24 @@ bool OpenACCMappableModel<Ty>::generatePrivateDestroy(
     fir::FreeMemOp::create(builder, loc, addr);
   };
   if (bounds.empty()) {
+    // Reduction init yields only the private descriptor. When that descriptor
+    // is a POINTER or ALLOCATABLE, its base address is null if the original
+    // was unassociated or unallocated, so free only in that case.
+    if (fir::isPointerType(inputVar.getType()) ||
+        fir::isAllocatableType(inputVar.getType())) {
+      mlir::Value addr = hlfir::genVariableRawAddress(loc, builder, inputVar);
+      mlir::Value isAllocated = builder.genIsNotNullAddr(loc, addr);
+      auto ifOp = fir::IfOp::create(builder, loc, isAllocated,
+                                    /*withElseRegion=*/false);
+      builder.setInsertionPointToStart(&ifOp.getThenRegion().front());
+      mlir::Type heapType =
+          fir::HeapType::get(fir::unwrapRefType(addr.getType()));
+      if (heapType != addr.getType())
+        addr = fir::ConvertOp::create(builder, loc, heapType, addr);
+      fir::FreeMemOp::create(builder, loc, addr);
+      builder.setInsertionPointAfter(ifOp);
+      return true;
+    }
     genFreeRawAddress(inputVar);
     return true;
   }
diff --git a/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir b/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir
index ff582f93976f1..c3fd622409ea2 100644
--- a/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir
+++ b/flang/test/Fir/OpenACC/recipe-populate-firstprivate.mlir
@@ -203,3 +203,101 @@ func.func @test_optional_ptr_f64() {
   %1:2 = hlfir.declare %var uniq_name("load_hlfir") : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
   return
 }
+
+// -----
+
+// Whole scalar POINTER: copy the pointee only when base_addr is non-null.
+// CHECK: acc.firstprivate.recipe @firstprivate_box_ptr_scalar : !fir.ref<!fir.box<!fir.ptr<f64>>> init {
+// CHECK: } copy {
+// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.box<!fir.ptr<f64>>>, %[[DST:.*]]: !fir.ref<!fir.box<!fir.ptr<f64>>>):
+// CHECK:   %[[BOX:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.box<!fir.ptr<f64>>>
+// CHECK:   %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.ptr<f64>>) -> !fir.ptr<f64>
+// CHECK-NOT: fir.load %[[ADDR]]
+// CHECK:   %[[COND:.*]] = arith.cmpi ne
+// CHECK:   fir.if %[[COND]] weights([1, 0]) {
+// CHECK:     hlfir.assign {{.*}} temporary_lhs
+// CHECK:   }
+// CHECK-NOT: hlfir.assign
+// CHECK:   acc.terminator
+// CHECK: }
+
+func.func @test_box_ptr_scalar() {
+  %0 = fir.alloca !fir.box<!fir.ptr<f64>> {test.var = "box_ptr_scalar"}
+  %var = fir.alloca f32
+  %1:2 = hlfir.declare %var uniq_name("load_hlfir") : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+  return
+}
+
+// -----
+
+// Whole array POINTER: same association guard around the array assignment.
+// CHECK: acc.firstprivate.recipe @firstprivate_box_ptr_array : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> init {
+// CHECK: } copy {
+// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>):
+// CHECK:   %[[BOX:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+// CHECK:   %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.ptr<!fir.array<?xf32>>
+// CHECK-NOT: fir.load %[[ADDR]]
+// CHECK:   %[[COND:.*]] = arith.cmpi ne
+// CHECK:   fir.if %[[COND]] weights([1, 0]) {
+// CHECK:     hlfir.assign {{.*}} temporary_lhs
+// CHECK:   }
+// CHECK-NOT: hlfir.assign
+// CHECK:   acc.terminator
+// CHECK: }
+
+func.func @test_box_ptr_array() {
+  %0 = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>> {test.var = "box_ptr_array"}
+  %var = fir.alloca f32
+  %1:2 = hlfir.declare %var uniq_name("load_hlfir") : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+  return
+}
+
+// -----
+
+// Whole scalar ALLOCATABLE: copy only when allocated.
+// CHECK: acc.firstprivate.recipe @firstprivate_box_heap_scalar : !fir.ref<!fir.box<!fir.heap<f64>>> init {
+// CHECK:   fir.if {{.*}} -> (!fir.heap<f64>) {
+// CHECK: } copy {
+// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.box<!fir.heap<f64>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>):
+// CHECK:   %[[BOX:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.box<!fir.heap<f64>>>
+// CHECK:   %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<f64>>) -> !fir.heap<f64>
+// CHECK-NOT: fir.load %[[ADDR]]
+// CHECK:   %[[COND:.*]] = arith.cmpi ne
+// CHECK:   fir.if %[[COND]] weights([1, 0]) {
+// CHECK:     hlfir.assign {{.*}} temporary_lhs
+// CHECK:   }
+// CHECK-NOT: hlfir.assign
+// CHECK:   acc.terminator
+// CHECK: }
+
+func.func @test_box_heap_scalar() {
+  %0 = fir.alloca !fir.box<!fir.heap<f64>> {test.var = "box_heap_scalar"}
+  %var = fir.alloca f32
+  %1:2 = hlfir.declare %var uniq_name("load_hlfir") : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+  return
+}
+
+// -----
+
+// Whole array ALLOCATABLE: same allocation guard around the array assignment.
+// CHECK: acc.firstprivate.recipe @firstprivate_box_heap_array : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> init {
+// CHECK:   fir.if {{.*}} -> (!fir.heap<!fir.array<?xf32>>) {
+// CHECK: } copy {
+// CHECK: ^bb0(%[[SRC:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
+// CHECK:   %[[BOX:.*]] = fir.load %[[SRC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK:   %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+// CHECK-NOT: fir.load %[[ADDR]]
+// CHECK:   %[[COND:.*]] = arith.cmpi ne
+// CHECK:   fir.if %[[COND]] weights([1, 0]) {
+// CHECK:     hlfir.assign {{.*}} temporary_lhs
+// CHECK:   }
+// CHECK-NOT: hlfir.assign
+// CHECK:   acc.terminator
+// CHECK: }
+
+func.func @test_box_heap_array() {
+  %0 = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>> {test.var = "box_heap_array"}
+  %var = fir.alloca f32
+  %1:2 = hlfir.declare %var uniq_name("load_hlfir") : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+  return
+}
diff --git a/flang/test/Fir/OpenACC/recipe-populate-private.mlir b/flang/test/Fir/OpenACC/recipe-populate-private.mlir
index abd01fe526ff1..bf67e34089ef6 100644
--- a/flang/test/Fir/OpenACC/recipe-populate-private.mlir
+++ b/flang/test/Fir/OpenACC/recipe-populate-private.mlir
@@ -106,19 +106,27 @@ func.func @test_derived() {
 
 // -----
 
-// Test box type with heap scalar (needs destroy)
+// Test box type with heap scalar (needs destroy). Unallocated allocatables
+// keep a null private allocation.
 // CHECK: acc.private.recipe @private_box_heap_scalar : !fir.ref<!fir.box<!fir.heap<f64>>> init {
 // CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>):
-// CHECK:   %[[SCALAR:.*]] = fir.allocmem f64
-// CHECK:   %[[EMBOX:.*]] = fir.embox %[[SCALAR]] : (!fir.heap<f64>) -> !fir.box<!fir.heap<f64>>
+// CHECK:   %[[PRIVATE_ALLOC:.*]] = fir.if {{.*}} -> (!fir.heap<f64>) {
+// CHECK:     %[[SCALAR:.*]] = fir.allocmem f64
+// CHECK:     fir.result %[[SCALAR]] : !fir.heap<f64>
+// CHECK:   } else {
+// CHECK:     %[[NULL_ALLOC:.*]] = fir.zero_bits !fir.heap<f64>
+// CHECK:     fir.result %[[NULL_ALLOC]] : !fir.heap<f64>
+// CHECK:   }
+// CHECK:   %[[EMBOX:.*]] = fir.embox %[[PRIVATE_ALLOC]] : (!fir.heap<f64>) -> !fir.box<!fir.heap<f64>>
 // CHECK:   %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<f64>>
 // CHECK:   fir.store %[[EMBOX]] to %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<f64>>>
-// CHECK:   acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<f64>>>
+// CHECK:   acc.yield %[[BOXALLOC]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.heap<f64>>>, !fir.heap<f64>
 // CHECK: } destroy {
-// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>, %[[PRIVATE:.*]]: !fir.ref<!fir.box<!fir.heap<f64>>>):
-// CHECK:   %[[BOX:.*]] = fir.load %[[PRIVATE]] : !fir.ref<!fir.box<!fir.heap<f64>>>
-// CHECK:   %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<f64>>) -> !fir.heap<f64>
-// CHECK:   fir.freemem %[[ADDR]] : !fir.heap<f64>
+// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<f64>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<f64>):
+// CHECK-NOT: fir.box_addr
+// CHECK:   fir.if {{.*}} {
+// CHECK:     fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<f64>
+// CHECK:   }
 // CHECK:   acc.terminator
 // CHECK: }
 
@@ -163,16 +171,23 @@ func.func @test_box_ptr_scalar() {
 
 // -----
 
-// Test box type with 1D heap array (needs destroy)
+// Test box type with 1D heap array (needs destroy). Unallocated allocatables
+// keep a null private allocation.
 // CHECK: acc.private.recipe @private_box_heap_array_1d : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> init {
 // CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
+// CHECK:   %[[PRIVATE_ALLOC:.*]] = fir.if {{.*}} -> (!fir.heap<!fir.array<?xf32>>) {
+// CHECK:     fir.allocmem !fir.array<?xf32>
+// CHECK:   } else {
+// CHECK:     fir.zero_bits !fir.heap<!fir.array<?xf32>>
+// CHECK:   }
 // CHECK:   %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>>
-// CHECK:   acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK:   acc.yield %[[BOXALLOC]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.heap<!fir.array<?xf32>>
 // CHECK: } destroy {
-// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %[[PRIVATE:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
-// CHECK:   %[[BOX:.*]] = fir.load %[[PRIVATE]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
-// CHECK:   %[[ADDR:.*]] = fir.box_addr %[[BOX]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-// CHECK:   fir.freemem %[[ADDR]] : !fir.heap<!fir.array<?xf32>>
+// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<!fir.array<?xf32>>):
+// CHECK-NOT: fir.box_addr
+// CHECK:   fir.if {{.*}} {
+// CHECK:     fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<!fir.array<?xf32>>
+// CHECK:   }
 // CHECK:   acc.terminator
 // CHECK: }
 
@@ -185,13 +200,22 @@ func.func @test_box_heap_array_1d() {
 
 // -----
 
-// Test box type with 2D heap array (needs destroy)
+// Test box type with 2D heap array (needs destroy). Unallocated allocatables
+// keep a null private allocation.
 // CHECK: acc.private.recipe @private_box_heap_array_2d : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>> init {
 // CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>):
+// CHECK:   %[[PRIVATE_ALLOC:.*]] = fir.if {{.*}} -> (!fir.heap<!fir.array<?x?xi64>>) {
+// CHECK:     fir.allocmem !fir.array<?x?xi64>
+// CHECK:   } else {
+// CHECK:     fir.zero_bits !fir.heap<!fir.array<?x?xi64>>
+// CHECK:   }
 // CHECK:   %[[BOXALLOC:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?x?xi64>>>
-// CHECK:   acc.yield %[[BOXALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>
+// CHECK:   acc.yield %[[BOXALLOC]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>, !fir.heap<!fir.array<?x?xi64>>
 // CHECK: } destroy {
-// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>):
+// CHECK: ^bb0(%{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>, %{{.*}}: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xi64>>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<!fir.array<?x?xi64>>):
+// CHECK:   fir.if {{.*}} {
+// CHECK:     fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<!fir.array<?x?xi64>>
+// CHECK:   }
 // CHECK:   acc.terminator
 // CHECK: }
 
diff --git a/flang/test/Lower/OpenACC/acc-private.f90 b/flang/test/Lower/OpenACC/acc-private.f90
index 1e762288e94ee..6af5ef9fde44f 100644
--- a/flang/test/Lower/OpenACC/acc-private.f90
+++ b/flang/test/Lower/OpenACC/acc-private.f90
@@ -1,6 +1,7 @@
 ! This test checks lowering of OpenACC loop directive.
 
 ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s --check-prefix=SECTION
 
 
 ! CHECK-LABEL:   acc.private.recipe @privatization_ptr_10xf32 : !fir.ptr<!fir.array<10xf32>> init {
@@ -204,17 +205,24 @@
 ! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
 ! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
 ! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-! CHECK:           %[[ALLOCMEM_0:.*]] = fir.allocmem i32 <{bindc_name = "acc.private.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if {{.*}} -> (!fir.heap<i32>) {
+! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem i32 <{bindc_name = "acc.private.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<i32>
+! CHECK:           } else {
+! CHECK:             %[[NULL_ALLOC:.*]] = fir.zero_bits !fir.heap<i32>
+! CHECK:             fir.result %[[NULL_ALLOC]] : !fir.heap<i32>
+! CHECK:           }
+! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[PRIVATE_ALLOC]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
 ! CHECK:           fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK:           acc.yield %[[ALLOCA_0]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.heap<i32>>>, !fir.heap<i32>
 
 ! CHECK-LABEL:   } destroy {
-! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
-! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<i32>>>
-! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-! CHECK:           fir.freemem %[[BOX_ADDR_0]] : !fir.heap<i32>
+! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<i32>):
+! CHECK-NOT:       fir.box_addr
+! CHECK:           fir.if {{.*}} {
+! CHECK:             fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<i32>
+! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
 
@@ -225,22 +233,29 @@
 ! CHECK:           %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_0]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
 ! CHECK:           %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
 ! CHECK:           %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK:           %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 <{bindc_name = "acc.private.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if {{.*}} -> (!fir.heap<!fir.array<?xi32>>) {
+! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xi32>, %[[BOX_DIMS_0]]#1 <{bindc_name = "acc.private.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<!fir.array<?xi32>>
+! CHECK:           } else {
+! CHECK:             %[[NULL_ALLOC:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>>
+! CHECK:             fir.result %[[NULL_ALLOC]] : !fir.heap<!fir.array<?xi32>>
+! CHECK:           }
 ! CHECK:           %[[CONSTANT_1:.*]] = arith.constant 0 : index
 ! CHECK:           %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
 ! CHECK:           %[[CONSTANT_2:.*]] = arith.constant 0 : index
 ! CHECK:           %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_2]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
 ! CHECK:           %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_1]]#0, %[[BOX_DIMS_2]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
+! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[PRIVATE_ALLOC]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>>
 ! CHECK:           fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK:           acc.yield %[[ALLOCA_0]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.heap<!fir.array<?xi32>>
 
 ! CHECK-LABEL:   } destroy {
-! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>):
-! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
-! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
-! CHECK:           fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.array<?xi32>>
+! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<!fir.array<?xi32>>):
+! CHECK-NOT:       fir.box_addr
+! CHECK:           fir.if {{.*}} {
+! CHECK:             fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<!fir.array<?xi32>>
+! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
 
@@ -625,3 +640,26 @@ subroutine acc_private_use()
 ! CHECK:   %[[DECL_PRIV_I:.*]]:2 = hlfir.declare %[[PRIV_I]] uniq_name("_QFacc_private_useEi") : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
 ! CHECK:   fir.store %[[IV0]] to %[[DECL_PRIV_I]]#0 : !fir.ref<i32>
 ! CHECK:   %{{.*}} = fir.load %[[DECL_PRIV_I]]#0 : !fir.ref<i32>
+
+! A section of an allocatable still carries bounds when the allocatable is
+! unallocated. The copy must test the base address before designating it.
+! SECTION-LABEL: acc.firstprivate.recipe @"firstprivatization_section_?_ref_box_heap_Uxi32"
+! SECTION:       } copy {
+! SECTION:         fir.box_addr
+! SECTION:         arith.cmpi ne
+! SECTION:         fir.if {{.*}} weights([1, 0]) {
+! SECTION:           hlfir.designate
+! SECTION:           hlfir.assign {{.*}} temporary_lhs
+! SECTION:         }
+! SECTION-NOT:     hlfir.assign
+! SECTION:         acc.terminator
+! SECTION:       } destroy {
+
+subroutine acc_firstprivate_unalloc_allocatable_section(n)
+  integer :: n, i
+  integer, allocatable :: a(:)
+  !$acc parallel loop firstprivate(a(1:n))
+  do i = 1, n
+    a(i) = i
+  end do
+end subroutine
diff --git a/flang/test/Lower/OpenACC/acc-reduction.f90 b/flang/test/Lower/OpenACC/acc-reduction.f90
index bfbf70a75d944..8ed69804bb025 100644
--- a/flang/test/Lower/OpenACC/acc-reduction.f90
+++ b/flang/test/Lower/OpenACC/acc-reduction.f90
@@ -7,9 +7,20 @@
 ! CHECK:           %[[CONSTANT_0:.*]] = arith.constant false
 ! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
 ! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
-! CHECK:           %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.logical<4> <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
-! CHECK:           hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i1, !fir.heap<!fir.logical<4>>
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<!fir.logical<4>>) -> !fir.box<!fir.heap<!fir.logical<4>>>
+! CHECK:           %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
+! CHECK:           %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_1]] : (!fir.heap<!fir.logical<4>>) -> i64
+! CHECK:           %[[CONSTANT_I64:.*]] = arith.constant 0 : i64
+! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_I64]] : i64
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ALLOCATED]] weights([1, 0]) -> (!fir.heap<!fir.logical<4>>) {
+! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.logical<4> <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i1, !fir.heap<!fir.logical<4>>
+! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<!fir.logical<4>>
+! CHECK:           } else {
+! CHECK:             %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<!fir.logical<4>>
+! CHECK:             fir.result %[[ZERO_BITS]] : !fir.heap<!fir.logical<4>>
+! CHECK:           }
+! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[PRIVATE_ALLOC]] : (!fir.heap<!fir.logical<4>>) -> !fir.box<!fir.heap<!fir.logical<4>>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.logical<4>>>
 ! CHECK:           fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
 ! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
@@ -30,7 +41,12 @@
 ! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>):
 ! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.logical<4>>>>
 ! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.logical<4>>>) -> !fir.heap<!fir.logical<4>>
-! CHECK:           fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.logical<4>>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.heap<!fir.logical<4>>) -> i64
+! CHECK:           %[[CONSTANT_0:.*]] = arith.constant 0 : i64
+! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_0]] : i64
+! CHECK:           fir.if %[[IS_ALLOCATED]] {
+! CHECK:             fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.logical<4>>
+! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
 
@@ -134,22 +150,22 @@
 ! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr<!fir.array<?xf32>>) -> i64
 ! CHECK:           %[[CONSTANT_I64:.*]] = arith.constant 0 : i64
 ! CHECK:           %[[IS_ASSOCIATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_I64]] : i64
-! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ASSOCIATED]] -> (!fir.heap<!fir.array<?xf32>>) {
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ASSOCIATED]] weights([1, 0]) -> (!fir.heap<!fir.array<?xf32>>) {
 ! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:             %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK:             %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK:             %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
+! CHECK:             %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK:             fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
+! CHECK:               %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK:               hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK:             }
 ! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<!fir.array<?xf32>>
 ! CHECK:           } else {
 ! CHECK:             %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
 ! CHECK:             fir.result %[[ZERO_BITS]] : !fir.heap<!fir.array<?xf32>>
 ! CHECK:           }
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[PRIVATE_ALLOC]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK:           %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK:           %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK:           %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
-! CHECK:           %[[CONSTANT_3:.*]] = arith.constant 1 : index
-! CHECK:           fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
-! CHECK:             %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
-! CHECK:             hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
-! CHECK:           }
 ! CHECK:           %[[CONSTANT_4:.*]] = arith.constant 0 : index
 ! CHECK:           %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_4]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
 ! CHECK:           %[[CONSTANT_5:.*]] = arith.constant 0 : index
@@ -158,7 +174,7 @@
 ! CHECK:           %[[EMBOX_1:.*]] = fir.embox %[[PRIVATE_ALLOC]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.ptr<!fir.array<?xf32>>>
 ! CHECK:           fir.store %[[EMBOX_1]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
-! CHECK:           acc.yield %[[ALLOCA_0]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, !fir.heap<!fir.array<?xf32>>
+! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
 
 ! CHECK-LABEL:   } combiner {
 ! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>):
@@ -193,12 +209,15 @@
 ! CHECK:           acc.yield %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
 
 ! CHECK-LABEL:   } destroy {
-! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<!fir.array<?xf32>>):
-! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[PRIVATE_ALLOC]] : (!fir.heap<!fir.array<?xf32>>) -> i64
+! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>):
+! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
+! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>) -> !fir.ptr<!fir.array<?xf32>>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr<!fir.array<?xf32>>) -> i64
 ! CHECK:           %[[CONSTANT_0:.*]] = arith.constant 0 : i64
 ! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_0]] : i64
 ! CHECK:           fir.if %[[IS_ALLOCATED]] {
-! CHECK:             fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<!fir.array<?xf32>>
+! CHECK:             %[[CONVERT_1:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr<!fir.array<?xf32>>) -> !fir.heap<!fir.array<?xf32>>
+! CHECK:             fir.freemem %[[CONVERT_1]] : !fir.heap<!fir.array<?xf32>>
 ! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
@@ -211,22 +230,33 @@
 ! CHECK:           %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_1]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
 ! CHECK:           %[[SHAPE_0:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
 ! CHECK:           %[[SHAPE_1:.*]] = fir.shape %[[BOX_DIMS_0]]#1 : (index) -> !fir.shape<1>
-! CHECK:           %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
-! CHECK:           %[[CONSTANT_2:.*]] = arith.constant 0 : index
-! CHECK:           %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
-! CHECK:           %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
-! CHECK:           %[[CONSTANT_3:.*]] = arith.constant 1 : index
-! CHECK:           fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
-! CHECK:             %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
-! CHECK:             hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK:           %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.heap<!fir.array<?xf32>>) -> i64
+! CHECK:           %[[CONSTANT_I64:.*]] = arith.constant 0 : i64
+! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_I64]] : i64
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ALLOCATED]] weights([1, 0]) -> (!fir.heap<!fir.array<?xf32>>) {
+! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem !fir.array<?xf32>, %[[BOX_DIMS_0]]#1 <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_1]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+! CHECK:             %[[CONSTANT_2:.*]] = arith.constant 0 : index
+! CHECK:             %[[BOX_DIMS_1:.*]]:3 = fir.box_dims %[[EMBOX_0]], %[[CONSTANT_2]] : (!fir.box<!fir.array<?xf32>>, index) -> (index, index, index)
+! CHECK:             %[[SHAPE_2:.*]] = fir.shape %[[BOX_DIMS_1]]#1 : (index) -> !fir.shape<1>
+! CHECK:             %[[CONSTANT_3:.*]] = arith.constant 1 : index
+! CHECK:             fir.do_loop %[[VAL_1:.*]] = %[[CONSTANT_3]] to %[[BOX_DIMS_1]]#1 step %[[CONSTANT_3]] unordered {
+! CHECK:               %[[DESIGNATE_0:.*]] = hlfir.designate %[[EMBOX_0]] (%[[VAL_1]])  : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+! CHECK:               hlfir.assign %[[CONSTANT_0]] to %[[DESIGNATE_0]] temporary_lhs : f32, !fir.ref<f32>
+! CHECK:             }
+! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<!fir.array<?xf32>>
+! CHECK:           } else {
+! CHECK:             %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<!fir.array<?xf32>>
+! CHECK:             fir.result %[[ZERO_BITS]] : !fir.heap<!fir.array<?xf32>>
 ! CHECK:           }
 ! CHECK:           %[[CONSTANT_4:.*]] = arith.constant 0 : index
 ! CHECK:           %[[BOX_DIMS_2:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_4]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
 ! CHECK:           %[[CONSTANT_5:.*]] = arith.constant 0 : index
 ! CHECK:           %[[BOX_DIMS_3:.*]]:3 = fir.box_dims %[[LOAD_0]], %[[CONSTANT_5]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
 ! CHECK:           %[[SHAPE_SHIFT_0:.*]] = fir.shape_shift %[[BOX_DIMS_2]]#0, %[[BOX_DIMS_3]]#1 : (index, index) -> !fir.shapeshift<1>
-! CHECK:           %[[EMBOX_1:.*]] = fir.embox %[[ALLOCMEM_0]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
+! CHECK:           %[[EMBOX_1:.*]] = fir.embox %[[PRIVATE_ALLOC]](%[[SHAPE_SHIFT_0]]) : (!fir.heap<!fir.array<?xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.heap<!fir.array<?xf32>>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xf32>>>
 ! CHECK:           fir.store %[[EMBOX_1]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
 ! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
@@ -267,7 +297,12 @@
 ! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>):
 ! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
 ! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
-! CHECK:           fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.array<?xf32>>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.heap<!fir.array<?xf32>>) -> i64
+! CHECK:           %[[CONSTANT_0:.*]] = arith.constant 0 : i64
+! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_0]] : i64
+! CHECK:           fir.if %[[IS_ALLOCATED]] {
+! CHECK:             fir.freemem %[[BOX_ADDR_0]] : !fir.heap<!fir.array<?xf32>>
+! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
 
@@ -564,18 +599,18 @@
 ! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_1]] : (!fir.ptr<i32>) -> i64
 ! CHECK:           %[[CONSTANT_I64:.*]] = arith.constant 0 : i64
 ! CHECK:           %[[IS_ASSOCIATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_I64]] : i64
-! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ASSOCIATED]] -> (!fir.heap<i32>) {
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ASSOCIATED]] weights([1, 0]) -> (!fir.heap<i32>) {
 ! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem i32 <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i32, !fir.heap<i32>
 ! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<i32>
 ! CHECK:           } else {
 ! CHECK:             %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<i32>
 ! CHECK:             fir.result %[[ZERO_BITS]] : !fir.heap<i32>
 ! CHECK:           }
-! CHECK:           hlfir.assign %[[CONSTANT_0]] to %[[PRIVATE_ALLOC]] temporary_lhs : i32, !fir.heap<i32>
 ! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[PRIVATE_ALLOC]] : (!fir.heap<i32>) -> !fir.box<!fir.ptr<i32>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.ptr<i32>>
 ! CHECK:           fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
-! CHECK:           acc.yield %[[ALLOCA_0]], %[[PRIVATE_ALLOC]] : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.heap<i32>
+! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
 
 ! CHECK-LABEL:   } combiner {
 ! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
@@ -587,12 +622,15 @@
 ! CHECK:           acc.yield %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
 
 ! CHECK-LABEL:   } destroy {
-! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>, %[[PRIVATE_ALLOC:.*]]: !fir.heap<i32>):
-! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[PRIVATE_ALLOC]] : (!fir.heap<i32>) -> i64
+! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<i32>>>):
+! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
+! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr<i32>) -> i64
 ! CHECK:           %[[CONSTANT_0:.*]] = arith.constant 0 : i64
 ! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_0]] : i64
 ! CHECK:           fir.if %[[IS_ALLOCATED]] {
-! CHECK:             fir.freemem %[[PRIVATE_ALLOC]] : !fir.heap<i32>
+! CHECK:             %[[CONVERT_1:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.ptr<i32>) -> !fir.heap<i32>
+! CHECK:             fir.freemem %[[CONVERT_1]] : !fir.heap<i32>
 ! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
@@ -602,9 +640,20 @@
 ! CHECK:           %[[CONSTANT_0:.*]] = arith.constant 0 : i32
 ! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
 ! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-! CHECK:           %[[ALLOCMEM_0:.*]] = fir.allocmem i32 <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
-! CHECK:           hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i32, !fir.heap<i32>
-! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[ALLOCMEM_0]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
+! CHECK:           %[[LOAD_1:.*]] = fir.load %[[VAL_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
+! CHECK:           %[[BOX_ADDR_1:.*]] = fir.box_addr %[[LOAD_1]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_1]] : (!fir.heap<i32>) -> i64
+! CHECK:           %[[CONSTANT_I64:.*]] = arith.constant 0 : i64
+! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_I64]] : i64
+! CHECK:           %[[PRIVATE_ALLOC:.*]] = fir.if %[[IS_ALLOCATED]] weights([1, 0]) -> (!fir.heap<i32>) {
+! CHECK:             %[[ALLOCMEM_0:.*]] = fir.allocmem i32 <{bindc_name = "acc.reduction.init", uniq_name = ""}> {acc.var_name = #acc.var_name<"<acc.varname.placeholder>">}
+! CHECK:             hlfir.assign %[[CONSTANT_0]] to %[[ALLOCMEM_0]] temporary_lhs : i32, !fir.heap<i32>
+! CHECK:             fir.result %[[ALLOCMEM_0]] : !fir.heap<i32>
+! CHECK:           } else {
+! CHECK:             %[[ZERO_BITS:.*]] = fir.zero_bits !fir.heap<i32>
+! CHECK:             fir.result %[[ZERO_BITS]] : !fir.heap<i32>
+! CHECK:           }
+! CHECK:           %[[EMBOX_0:.*]] = fir.embox %[[PRIVATE_ALLOC]] : (!fir.heap<i32>) -> !fir.box<!fir.heap<i32>>
 ! CHECK:           %[[ALLOCA_0:.*]] = fir.alloca !fir.box<!fir.heap<i32>>
 ! CHECK:           fir.store %[[EMBOX_0]] to %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
 ! CHECK:           acc.yield %[[ALLOCA_0]] : !fir.ref<!fir.box<!fir.heap<i32>>>
@@ -622,7 +671,12 @@
 ! CHECK:         ^bb0(%[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>, %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<i32>>>):
 ! CHECK:           %[[LOAD_0:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<i32>>>
 ! CHECK:           %[[BOX_ADDR_0:.*]] = fir.box_addr %[[LOAD_0]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-! CHECK:           fir.freemem %[[BOX_ADDR_0]] : !fir.heap<i32>
+! CHECK:           %[[CONVERT_0:.*]] = fir.convert %[[BOX_ADDR_0]] : (!fir.heap<i32>) -> i64
+! CHECK:           %[[CONSTANT_0:.*]] = arith.constant 0 : i64
+! CHECK:           %[[IS_ALLOCATED:.*]] = arith.cmpi ne, %[[CONVERT_0]], %[[CONSTANT_0]] : i64
+! CHECK:           fir.if %[[IS_ALLOCATED]] {
+! CHECK:             fir.freemem %[[BOX_ADDR_0]] : !fir.heap<i32>
+! CHECK:           }
 ! CHECK:           acc.terminator
 ! CHECK:         }
 



More information about the flang-commits mailing list