diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp index 2fedc01bc77f..017bfd049d3d 100644 --- a/flang/lib/Lower/ConvertCall.cpp +++ b/flang/lib/Lower/ConvertCall.cpp @@ -366,7 +366,11 @@ std::pair Fortran::lower::genCallOpAndResult( resultLengths = lengths; } - if (!extents.empty() || !lengths.empty()) { + if ((!extents.empty() || !lengths.empty()) && !isElemental) { + // Note: in the elemental context, the alloca ownership inside the + // elemental region is implicit, and later pass in lowering (stack + // reclaim) fir.do_loop will be in charge of emitting any stack + // save/restore if needed. auto *bldr = &converter.getFirOpBuilder(); mlir::Value sp = bldr->genStackSave(loc); stmtCtx.attachCleanup( diff --git a/flang/test/Lower/HLFIR/elemental-array-ops.f90 b/flang/test/Lower/HLFIR/elemental-array-ops.f90 index 9929c17ec339..18e1fb0a787e 100644 --- a/flang/test/Lower/HLFIR/elemental-array-ops.f90 +++ b/flang/test/Lower/HLFIR/elemental-array-ops.f90 @@ -182,12 +182,10 @@ end subroutine char_return ! CHECK: %[[VAL_23:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_24:.*]] = arith.cmpi sgt, %[[VAL_22]], %[[VAL_23]] : index ! CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_24]], %[[VAL_22]], %[[VAL_23]] : index -! CHECK: %[[VAL_26:.*]] = llvm.intr.stacksave : !llvm.ptr ! CHECK: %[[VAL_27:.*]] = fir.call @_QPcallee(%[[VAL_2]], %[[VAL_25]], %[[VAL_20]]) fastmath : (!fir.ref>, index, !fir.boxchar<1>) -> !fir.boxchar<1> ! CHECK: %[[VAL_28:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_25]] {uniq_name = ".tmp.func_result"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) ! CHECK: %[[MustFree:.*]] = arith.constant false ! CHECK: %[[ResultTemp:.*]] = hlfir.as_expr %[[VAL_28]]#0 move %[[MustFree]] : (!fir.ref>, i1) -> !hlfir.expr> -! CHECK: llvm.intr.stackrestore %[[VAL_26]] : !llvm.ptr ! CHECK: hlfir.yield_element %[[ResultTemp]] : !hlfir.expr> ! CHECK: } ! CHECK: %[[VAL_29:.*]] = arith.constant 0 : index diff --git a/flang/test/Lower/HLFIR/elemental-user-procedure-stacksave.f90 b/flang/test/Lower/HLFIR/elemental-user-procedure-stacksave.f90 new file mode 100644 index 000000000000..839342f2da6d --- /dev/null +++ b/flang/test/Lower/HLFIR/elemental-user-procedure-stacksave.f90 @@ -0,0 +1,22 @@ +! Check that stack save and restore needed for elemental function result +! allocation inside loops are not emitted directly in lowering, but inserted if +! needed in the stack-reclaim pass. + +! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --check-prefix=CHECK-HLFIR +! RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-LLVM +subroutine foo(c1, c2) + character(*), dimension(100) :: c1, c2 + interface + elemental pure function func(c) + character(*), intent(in) :: c + character(len(c)) :: func + end function + end interface + c1 = func(c2) +end subroutine + +! CHECK-HLFIR-NOT: stacksave +! CHECK: return + +! CHECK-LLVM: stacksave +! CHECK-LLVM: stackrestore