[flang-commits] [flang] ab7bbbb - [flang][AllocationPlacement] prevent promotion of mock result to allocmem (#212825)

via flang-commits flang-commits at lists.llvm.org
Thu Jul 30 02:34:06 PDT 2026


Author: jeanPerier
Date: 2026-07-30T11:34:01+02:00
New Revision: ab7bbbbdc7bc0d7813d084898a8f913ca0b40fff

URL: https://github.com/llvm/llvm-project/commit/ab7bbbbdc7bc0d7813d084898a8f913ca0b40fff
DIFF: https://github.com/llvm/llvm-project/commit/ab7bbbbdc7bc0d7813d084898a8f913ca0b40fff.diff

LOG: [flang][AllocationPlacement] prevent promotion of mock result to allocmem (#212825)

Under the new experimental pass that can move automatic arrays to the
heap, "mock" result storage may be promoted to allocmem before
AbstractResult removes them and replace them by a hidden result.

Add a fir.must_be_stack attribute to these mock alloca so they are never
promoted. So that passes dealing with array function results ABI can
expect to find an fir.alloca and remove it.

Added: 
    flang/test/Integration/allocation-placement-array-result.f90

Modified: 
    flang/include/flang/Optimizer/Dialect/FIRAttr.h
    flang/lib/Lower/ConvertVariable.cpp
    flang/lib/Optimizer/Transforms/AllocationPlacement.cpp
    flang/test/Lower/HLFIR/array-ctor-index.f90
    flang/test/Lower/HLFIR/custom-intrinsic.f90
    flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
    flang/test/Lower/HLFIR/maxloc.f90
    flang/test/Lower/HLFIR/minloc.f90
    flang/test/Lower/submodule.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.h b/flang/include/flang/Optimizer/Dialect/FIRAttr.h
index ec6b7ff48329e..7c071e5d391e6 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRAttr.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.h
@@ -70,6 +70,16 @@ class MustBeHeapAttr : public mlir::BoolAttr {
   static constexpr llvm::StringRef getAttrName() { return "fir.must_be_heap"; }
 };
 
+/// Attribute which can be applied to a fir.alloca operation, specifying that
+/// the allocation may not be moved to the heap by passes.
+class MustBeStackAttr : public mlir::BoolAttr {
+public:
+  using BoolAttr::BoolAttr;
+
+  static constexpr llvm::StringLiteral name = "fir.must_be_stack";
+  static constexpr llvm::StringRef getAttrName() { return "fir.must_be_stack"; }
+};
+
 // Attributes for building SELECT CASE multiway branches
 
 /// A closed interval (including the bound values) is an interval with both an

diff  --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 007b536d97098..32b0863b4d57a 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -780,8 +780,21 @@ static mlir::Value createNewLocal(Fortran::lower::AbstractConverter &converter,
   }
 
   // Let the builder do all the heavy lifting.
-  if (!Fortran::semantics::IsProcedurePointer(ultimateSymbol))
-    return builder.allocateLocal(loc, ty, nm, symNm, shape, lenParams, isTarg);
+  if (!Fortran::semantics::IsProcedurePointer(ultimateSymbol)) {
+    mlir::Value local =
+        builder.allocateLocal(loc, ty, nm, symNm, shape, lenParams, isTarg);
+    // An array function result returned via the "result as argument" ABI has
+    // its local storage replaced by the caller-provided buffer by the
+    // abstract-result pass. Pin it to the stack so that allocation passes do
+    // not first promote it to the heap, which the abstract-result pass would
+    // then have to clean up.
+    if (mlir::isa<fir::SequenceType>(ty) &&
+        Fortran::semantics::IsFunctionResult(ultimateSymbol))
+      if (auto alloca = local.getDefiningOp<fir::AllocaOp>())
+        alloca->setAttr(fir::MustBeStackAttr::getAttrName(),
+                        fir::MustBeStackAttr::get(builder.getContext(), true));
+    return local;
+  }
 
   // Local procedure pointer.
   auto res{builder.allocateLocal(loc, ty, nm, symNm, shape, lenParams, isTarg)};

diff  --git a/flang/lib/Optimizer/Transforms/AllocationPlacement.cpp b/flang/lib/Optimizer/Transforms/AllocationPlacement.cpp
index d070376dd5637..c8ad34f7f60ad 100644
--- a/flang/lib/Optimizer/Transforms/AllocationPlacement.cpp
+++ b/flang/lib/Optimizer/Transforms/AllocationPlacement.cpp
@@ -17,6 +17,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "StackArrays.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
 #include "flang/Optimizer/Dialect/FIRDialect.h"
 #include "flang/Optimizer/Dialect/FIROps.h"
 #include "flang/Optimizer/Dialect/FIROpsSupport.h"
@@ -233,6 +234,16 @@ void AllocationPlacementPass::runOnOperation() {
     if (!alloca && !allocmem)
       return;
 
+    if (alloca) {
+      // Do not touch to fir.alloca that must stay fir.alloca (e.g.
+      // the temporary alloca for array function results that will
+      // later be promoted to hidden arguments).
+      auto attr = alloca->getAttrOfType<fir::MustBeStackAttr>(
+          fir::MustBeStackAttr::getAttrName());
+      if (attr && attr.getValue())
+        return;
+    }
+
     // Only array allocations are considered.
     mlir::Type inTy = alloca ? alloca.getInType() : allocmem.getAllocatedType();
     if (!mlir::isa<fir::SequenceType>(inTy))

diff  --git a/flang/test/Integration/allocation-placement-array-result.f90 b/flang/test/Integration/allocation-placement-array-result.f90
new file mode 100644
index 0000000000000..ea12675531ea7
--- /dev/null
+++ b/flang/test/Integration/allocation-placement-array-result.f90
@@ -0,0 +1,15 @@
+! Array function results are pinned to the stack in lowering (fir.must_be_stack),
+! so allocation placement must not move them to the heap. The abstract-result
+! pass turns the result into a caller-provided buffer, hence no malloc/free.
+
+! RUN: %flang_fc1 -emit-llvm -mllvm -enable-allocation-placement -o - %s 2>&1 | FileCheck %s
+
+function test(n)
+  real :: test(n)
+  call bar(n)
+end function
+
+! CHECK-LABEL: define void @test
+! CHECK-NOT: @malloc
+! CHECK-NOT: @free
+! CHECK: ret void

diff  --git a/flang/test/Lower/HLFIR/array-ctor-index.f90 b/flang/test/Lower/HLFIR/array-ctor-index.f90
index 98b3aeece8f1b..7d88bfc85a11b 100644
--- a/flang/test/Lower/HLFIR/array-ctor-index.f90
+++ b/flang/test/Lower/HLFIR/array-ctor-index.f90
@@ -10,7 +10,7 @@ end function test1
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<i8> {fir.bindc_name = "k"}) -> !fir.array<4xi8> {
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest1Ek"} : (!fir.ref<i8>, !fir.dscope) -> (!fir.ref<i8>, !fir.ref<i8>)
 ! CHECK:           %[[VAL_2:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi8> {bindc_name = "test1", uniq_name = "_QFtest1Etest1"}
+! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi8> {bindc_name = "test1", fir.must_be_stack = true, uniq_name = "_QFtest1Etest1"}
 ! CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_4]]) {uniq_name = "_QFtest1Etest1"} : (!fir.ref<!fir.array<4xi8>>, !fir.shape<1>) -> (!fir.ref<!fir.array<4xi8>>, !fir.ref<!fir.array<4xi8>>)
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 4 : index
@@ -60,7 +60,7 @@ end function test2
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<i16> {fir.bindc_name = "k"}) -> !fir.array<4xi16> {
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest2Ek"} : (!fir.ref<i16>, !fir.dscope) -> (!fir.ref<i16>, !fir.ref<i16>)
 ! CHECK:           %[[VAL_2:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi16> {bindc_name = "test2", uniq_name = "_QFtest2Etest2"}
+! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi16> {bindc_name = "test2", fir.must_be_stack = true, uniq_name = "_QFtest2Etest2"}
 ! CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_4]]) {uniq_name = "_QFtest2Etest2"} : (!fir.ref<!fir.array<4xi16>>, !fir.shape<1>) -> (!fir.ref<!fir.array<4xi16>>, !fir.ref<!fir.array<4xi16>>)
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 4 : index
@@ -110,7 +110,7 @@ end function test3
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<i32> {fir.bindc_name = "k"}) -> !fir.array<4xi32> {
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest3Ek"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
 ! CHECK:           %[[VAL_2:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi32> {bindc_name = "test3", uniq_name = "_QFtest3Etest3"}
+! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi32> {bindc_name = "test3", fir.must_be_stack = true, uniq_name = "_QFtest3Etest3"}
 ! CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_4]]) {uniq_name = "_QFtest3Etest3"} : (!fir.ref<!fir.array<4xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<4xi32>>, !fir.ref<!fir.array<4xi32>>)
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 4 : index
@@ -160,7 +160,7 @@ end function test4
 ! CHECK-SAME:                        %[[VAL_0:.*]]: !fir.ref<i64> {fir.bindc_name = "k"}) -> !fir.array<4xi64> {
 ! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest4Ek"} : (!fir.ref<i64>, !fir.dscope) -> (!fir.ref<i64>, !fir.ref<i64>)
 ! CHECK:           %[[VAL_2:.*]] = arith.constant 4 : index
-! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi64> {bindc_name = "test4", uniq_name = "_QFtest4Etest4"}
+! CHECK:           %[[VAL_3:.*]] = fir.alloca !fir.array<4xi64> {bindc_name = "test4", fir.must_be_stack = true, uniq_name = "_QFtest4Etest4"}
 ! CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_4]]) {uniq_name = "_QFtest4Etest4"} : (!fir.ref<!fir.array<4xi64>>, !fir.shape<1>) -> (!fir.ref<!fir.array<4xi64>>, !fir.ref<!fir.array<4xi64>>)
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 4 : index

diff  --git a/flang/test/Lower/HLFIR/custom-intrinsic.f90 b/flang/test/Lower/HLFIR/custom-intrinsic.f90
index cb894cadd5e26..2743dbeeb36fa 100644
--- a/flang/test/Lower/HLFIR/custom-intrinsic.f90
+++ b/flang/test/Lower/HLFIR/custom-intrinsic.f90
@@ -104,7 +104,7 @@ function max_array(a, b)
 ! CHECK:           %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_6]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFmax_arrayEb"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_8:.*]] = arith.constant 42 : index
-! CHECK:           %[[VAL_9:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "max_array", uniq_name = "_QFmax_arrayEmax_array"}
+! CHECK:           %[[VAL_9:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "max_array", fir.must_be_stack = true, uniq_name = "_QFmax_arrayEmax_array"}
 ! CHECK:           %[[VAL_10:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]](%[[VAL_10]]) {uniq_name = "_QFmax_arrayEmax_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_12:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
@@ -139,7 +139,7 @@ function max_dynamic_optional_array(a, b, c)
 ! CHECK:           %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_8]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFmax_dynamic_optional_arrayEc"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:           %[[VAL_10:.*]] = arith.constant 10 : index
-! CHECK:           %[[VAL_11:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "max_dynamic_optional_array", uniq_name = "_QFmax_dynamic_optional_arrayEmax_dynamic_optional_array"}
+! CHECK:           %[[VAL_11:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "max_dynamic_optional_array", fir.must_be_stack = true, uniq_name = "_QFmax_dynamic_optional_arrayEmax_dynamic_optional_array"}
 ! CHECK:           %[[VAL_12:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_12]]) {uniq_name = "_QFmax_dynamic_optional_arrayEmax_dynamic_optional_array"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:           %[[VAL_14:.*]] = fir.is_present %[[VAL_9]]#0 : (!fir.ref<!fir.array<10xi32>>) -> i1
@@ -268,7 +268,7 @@ function min_array(a, b)
 ! CHECK:           %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]](%[[VAL_6]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFmin_arrayEb"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_8:.*]] = arith.constant 42 : index
-! CHECK:           %[[VAL_9:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "min_array", uniq_name = "_QFmin_arrayEmin_array"}
+! CHECK:           %[[VAL_9:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "min_array", fir.must_be_stack = true, uniq_name = "_QFmin_arrayEmin_array"}
 ! CHECK:           %[[VAL_10:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]](%[[VAL_10]]) {uniq_name = "_QFmin_arrayEmin_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_12:.*]] = hlfir.elemental %[[VAL_3]] unordered : (!fir.shape<1>) -> !hlfir.expr<42xi32> {
@@ -303,7 +303,7 @@ function min_dynamic_optional_array(a, b, c)
 ! CHECK:           %[[VAL_8:.*]] = fir.shape %[[VAL_7]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_2]](%[[VAL_8]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<optional>, uniq_name = "_QFmin_dynamic_optional_arrayEc"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:           %[[VAL_10:.*]] = arith.constant 10 : index
-! CHECK:           %[[VAL_11:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "min_dynamic_optional_array", uniq_name = "_QFmin_dynamic_optional_arrayEmin_dynamic_optional_array"}
+! CHECK:           %[[VAL_11:.*]] = fir.alloca !fir.array<10xi32> {bindc_name = "min_dynamic_optional_array", fir.must_be_stack = true, uniq_name = "_QFmin_dynamic_optional_arrayEmin_dynamic_optional_array"}
 ! CHECK:           %[[VAL_12:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_11]](%[[VAL_12]]) {uniq_name = "_QFmin_dynamic_optional_arrayEmin_dynamic_optional_array"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)
 ! CHECK:           %[[VAL_14:.*]] = fir.is_present %[[VAL_9]]#0 : (!fir.ref<!fir.array<10xi32>>) -> i1
@@ -542,7 +542,7 @@ function ishftc_array(i, shift, size)
 ! CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFishftc_arrayEi"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 42 : index
-! CHECK:           %[[VAL_7:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "ishftc_array", uniq_name = "_QFishftc_arrayEishftc_array"}
+! CHECK:           %[[VAL_7:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "ishftc_array", fir.must_be_stack = true, uniq_name = "_QFishftc_arrayEishftc_array"}
 ! CHECK:           %[[VAL_8:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {uniq_name = "_QFishftc_arrayEishftc_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_10:.*]] = arith.constant 42 : index
@@ -609,7 +609,7 @@ function ishftc_dynamically_optional_array(i, shift, size)
 ! CHECK:           %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_4]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFishftc_dynamically_optional_arrayEi"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_6:.*]] = arith.constant 42 : index
-! CHECK:           %[[VAL_7:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "ishftc_dynamically_optional_array", uniq_name = "_QFishftc_dynamically_optional_arrayEishftc_dynamically_optional_array"}
+! CHECK:           %[[VAL_7:.*]] = fir.alloca !fir.array<42xi32> {bindc_name = "ishftc_dynamically_optional_array", fir.must_be_stack = true, uniq_name = "_QFishftc_dynamically_optional_arrayEishftc_dynamically_optional_array"}
 ! CHECK:           %[[VAL_8:.*]] = fir.shape %[[VAL_6]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_7]](%[[VAL_8]]) {uniq_name = "_QFishftc_dynamically_optional_arrayEishftc_dynamically_optional_array"} : (!fir.ref<!fir.array<42xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<42xi32>>, !fir.ref<!fir.array<42xi32>>)
 ! CHECK:           %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFishftc_dynamically_optional_arrayEshift"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)

diff  --git a/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90 b/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
index ee35a681172a4..16a3b402c33bd 100644
--- a/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
+++ b/flang/test/Lower/HLFIR/intrinsic-dynamically-optional.f90
@@ -171,7 +171,7 @@ function test_elemental_optional_as_value(real, imaginary)
 ! CHECK:           %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_0]](%[[VAL_6]]) dummy_scope %{{[0-9]+}} arg {{[0-9]+}} {uniq_name = "_QFtest_elemental_optional_as_valueEreal"} : (!fir.ref<!fir.array<3xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<3xf32>>, !fir.ref<!fir.array<3xf32>>)
 ! CHECK:           %[[VAL_8:.*]] = arith.constant 3 : index
-! CHECK:           %[[VAL_9:.*]] = fir.alloca !fir.array<3xcomplex<f32>> {bindc_name = "test_elemental_optional_as_value", uniq_name = "_QFtest_elemental_optional_as_valueEtest_elemental_optional_as_value"}
+! CHECK:           %[[VAL_9:.*]] = fir.alloca !fir.array<3xcomplex<f32>> {bindc_name = "test_elemental_optional_as_value", fir.must_be_stack = true, uniq_name = "_QFtest_elemental_optional_as_valueEtest_elemental_optional_as_value"}
 ! CHECK:           %[[VAL_10:.*]] = fir.shape %[[VAL_8]] : (index) -> !fir.shape<1>
 ! CHECK:           %[[VAL_11:.*]]:2 = hlfir.declare %[[VAL_9]](%[[VAL_10]]) {uniq_name = "_QFtest_elemental_optional_as_valueEtest_elemental_optional_as_value"} : (!fir.ref<!fir.array<3xcomplex<f32>>>, !fir.shape<1>) -> (!fir.ref<!fir.array<3xcomplex<f32>>>, !fir.ref<!fir.array<3xcomplex<f32>>>)
 ! CHECK:           %[[VAL_12:.*]] = fir.is_present %[[VAL_4]]#0 : (!fir.ref<!fir.array<3xf32>>) -> i1

diff  --git a/flang/test/Lower/HLFIR/maxloc.f90 b/flang/test/Lower/HLFIR/maxloc.f90
index 57cb1f85d30d4..39d3039bf19c2 100644
--- a/flang/test/Lower/HLFIR/maxloc.f90
+++ b/flang/test/Lower/HLFIR/maxloc.f90
@@ -300,7 +300,7 @@ function testOptionalScalar(array, mask)
 ! CHECK-SAME:                                     %[[MASK_ARG:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "mask", fir.optional}) -> !fir.array<1xi32>
 ! CHECK:           %[[ARRAY_VAR:.*]]:2 = hlfir.declare %[[ARRAY_ARG]]
 ! CHECK:           %[[MASK_VAR:.*]]:2 = hlfir.declare %[[MASK_ARG]]
-! CHECK:           %[[RET_ALLOC:.*]] = fir.alloca !fir.array<1xi32> {bindc_name = "testoptionalscalar", uniq_name = "_QFtestoptionalscalarEtestoptionalscalar"}
+! CHECK:           %[[RET_ALLOC:.*]] = fir.alloca !fir.array<1xi32> {bindc_name = "testoptionalscalar", fir.must_be_stack = true, uniq_name = "_QFtestoptionalscalarEtestoptionalscalar"}
 ! CHECK:           %[[RET_VAR:.*]]:2 = hlfir.declare %[[RET_ALLOC]]
 ! CHECK:           %[[MASK_IS_PRESENT:.*]] = fir.is_present %[[MASK_VAR]]#0 : (!fir.ref<!fir.logical<4>>) -> i1
 ! CHECK:           %[[MASK_BOX:.*]] = fir.embox %[[MASK_VAR]]#0

diff  --git a/flang/test/Lower/HLFIR/minloc.f90 b/flang/test/Lower/HLFIR/minloc.f90
index 587359265c75e..0b9224c78c27e 100644
--- a/flang/test/Lower/HLFIR/minloc.f90
+++ b/flang/test/Lower/HLFIR/minloc.f90
@@ -300,7 +300,7 @@ function testOptionalScalar(array, mask)
 ! CHECK-SAME:                                     %[[MASK_ARG:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "mask", fir.optional}) -> !fir.array<1xi32>
 ! CHECK:           %[[ARRAY_VAR:.*]]:2 = hlfir.declare %[[ARRAY_ARG]]
 ! CHECK:           %[[MASK_VAR:.*]]:2 = hlfir.declare %[[MASK_ARG]]
-! CHECK:           %[[RET_ALLOC:.*]] = fir.alloca !fir.array<1xi32> {bindc_name = "testoptionalscalar", uniq_name = "_QFtestoptionalscalarEtestoptionalscalar"}
+! CHECK:           %[[RET_ALLOC:.*]] = fir.alloca !fir.array<1xi32> {bindc_name = "testoptionalscalar", fir.must_be_stack = true, uniq_name = "_QFtestoptionalscalarEtestoptionalscalar"}
 ! CHECK:           %[[RET_VAR:.*]]:2 = hlfir.declare %[[RET_ALLOC]]
 ! CHECK:           %[[MASK_IS_PRESENT:.*]] = fir.is_present %[[MASK_VAR]]#0 : (!fir.ref<!fir.logical<4>>) -> i1
 ! CHECK:           %[[MASK_BOX:.*]] = fir.embox %[[MASK_VAR]]#0

diff  --git a/flang/test/Lower/submodule.f90 b/flang/test/Lower/submodule.f90
index 77a36748341b8..c3547f7e86958 100644
--- a/flang/test/Lower/submodule.f90
+++ b/flang/test/Lower/submodule.f90
@@ -31,7 +31,7 @@ end function fff
   ! CHECK:     %[[V_4:.*]] = fir.convert %[[V_3]] : (i64) -> index
   ! CHECK:     %[[V_5:.*]] = arith.cmpi sgt, %[[V_4]], %c0{{.*}} : index
   ! CHECK:     %[[V_6:.*]] = arith.select %[[V_5]], %[[V_4]], %c0{{.*}} : index
-  ! CHECK:     %[[V_7:.*]] = fir.alloca !fir.array<?xi32>, %[[V_6]] {bindc_name = "ff2", uniq_name = "_QMmmSss1Fff2Eff2"}
+  ! CHECK:     %[[V_7:.*]] = fir.alloca !fir.array<?xi32>, %[[V_6]] {bindc_name = "ff2", fir.must_be_stack = true, uniq_name = "_QMmmSss1Fff2Eff2"}
   ! CHECK:     %[[V_8:.*]] = fir.shape %[[V_6]] : (index) -> !fir.shape<1>
   ! CHECK:     %[[V_9:.*]]:2 = hlfir.declare %[[V_7]](%[[V_8]]) {uniq_name = "_QMmmSss1Fff2Eff2"}
   ! CHECK:     %[[V_10:.*]] = fir.call @_QMmmSss1Pfff(%[[V_0]]#0) {{.*}} : (!fir.ref<i32>) -> i32
@@ -56,7 +56,7 @@ end function fff
   ! CHECK:     %[[V_6:.*]] = fir.convert %[[V_5]] : (i64) -> index
   ! CHECK:     %[[V_7:.*]] = arith.cmpi sgt, %[[V_6]], %c0{{.*}} : index
   ! CHECK:     %[[V_8:.*]] = arith.select %[[V_7]], %[[V_6]], %c0{{.*}} : index
-  ! CHECK:     %[[V_9:.*]] = fir.alloca !fir.array<?xi32>, %[[V_8]] {bindc_name = "ff1", uniq_name = "_QMmmSss1Sss2Fff1Eff1"}
+  ! CHECK:     %[[V_9:.*]] = fir.alloca !fir.array<?xi32>, %[[V_8]] {bindc_name = "ff1", fir.must_be_stack = true, uniq_name = "_QMmmSss1Sss2Fff1Eff1"}
   ! CHECK:     %[[V_10:.*]] = fir.shape %[[V_8]] : (index) -> !fir.shape<1>
   ! CHECK:     %[[V_11:.*]]:2 = hlfir.declare %[[V_9]](%[[V_10]]) {uniq_name = "_QMmmSss1Sss2Fff1Eff1"}
   ! CHECK:     %[[V_12:.*]] = fir.load %[[V_1]]#0 : !fir.ref<i32>
@@ -102,7 +102,7 @@ end function ff1
   ! CHECK:     %[[V_6:.*]] = fir.convert %[[V_5]] : (i64) -> index
   ! CHECK:     %[[V_7:.*]] = arith.cmpi sgt, %[[V_6]], %c0{{.*}} : index
   ! CHECK:     %[[V_8:.*]] = arith.select %[[V_7]], %[[V_6]], %c0{{.*}} : index
-  ! CHECK:     %[[V_9:.*]] = fir.alloca !fir.array<?xi32>, %[[V_8]] {bindc_name = "ff3", uniq_name = "_QMmmSsssFff3Eff3"}
+  ! CHECK:     %[[V_9:.*]] = fir.alloca !fir.array<?xi32>, %[[V_8]] {bindc_name = "ff3", fir.must_be_stack = true, uniq_name = "_QMmmSsssFff3Eff3"}
   ! CHECK:     %[[V_10:.*]] = fir.shape %[[V_8]] : (index) -> !fir.shape<1>
   ! CHECK:     %[[V_11:.*]]:2 = hlfir.declare %[[V_9]](%[[V_10]]) {uniq_name = "_QMmmSsssFff3Eff3"}
   ! CHECK-DAG: %[[V_12:.*]] = fir.load %[[V_2]]#0 : !fir.ref<i32>


        


More information about the flang-commits mailing list