Skip to content

Commit 94c024a

Browse files
authored
[flang][lowering] delay stack save/restor emission in elemental calls (#109142)
stack save/restore emitted for character elemental function result allocation inside hlfir.elemental in lowering created memory bugs because result memory is actually still used after the stack restore when lowering the elemental into a loop where the result element is copied into the array result storage. Instead of adding special handling for stack save/restore in lowering, just avoid emitting those since the stack reclaim pass is able to emit them in the generated loop. Not having those stack save/restore will also help optimizations that want to elide the temporary allocation for the element result when that is possible.
1 parent 96ac627 commit 94c024a

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

flang/lib/Lower/ConvertCall.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,11 @@ std::pair<fir::ExtendedValue, bool> Fortran::lower::genCallOpAndResult(
366366
resultLengths = lengths;
367367
}
368368

369-
if (!extents.empty() || !lengths.empty()) {
369+
if ((!extents.empty() || !lengths.empty()) && !isElemental) {
370+
// Note: in the elemental context, the alloca ownership inside the
371+
// elemental region is implicit, and later pass in lowering (stack
372+
// reclaim) fir.do_loop will be in charge of emitting any stack
373+
// save/restore if needed.
370374
auto *bldr = &converter.getFirOpBuilder();
371375
mlir::Value sp = bldr->genStackSave(loc);
372376
stmtCtx.attachCleanup(

flang/test/Lower/HLFIR/elemental-array-ops.f90

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,10 @@ end subroutine char_return
182182
! CHECK: %[[VAL_23:.*]] = arith.constant 0 : index
183183
! CHECK: %[[VAL_24:.*]] = arith.cmpi sgt, %[[VAL_22]], %[[VAL_23]] : index
184184
! CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_24]], %[[VAL_22]], %[[VAL_23]] : index
185-
! CHECK: %[[VAL_26:.*]] = llvm.intr.stacksave : !llvm.ptr
186185
! CHECK: %[[VAL_27:.*]] = fir.call @_QPcallee(%[[VAL_2]], %[[VAL_25]], %[[VAL_20]]) fastmath<contract> : (!fir.ref<!fir.char<1,3>>, index, !fir.boxchar<1>) -> !fir.boxchar<1>
187186
! CHECK: %[[VAL_28:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_25]] {uniq_name = ".tmp.func_result"} : (!fir.ref<!fir.char<1,3>>, index) -> (!fir.ref<!fir.char<1,3>>, !fir.ref<!fir.char<1,3>>)
188187
! CHECK: %[[MustFree:.*]] = arith.constant false
189188
! CHECK: %[[ResultTemp:.*]] = hlfir.as_expr %[[VAL_28]]#0 move %[[MustFree]] : (!fir.ref<!fir.char<1,3>>, i1) -> !hlfir.expr<!fir.char<1,3>>
190-
! CHECK: llvm.intr.stackrestore %[[VAL_26]] : !llvm.ptr
191189
! CHECK: hlfir.yield_element %[[ResultTemp]] : !hlfir.expr<!fir.char<1,3>>
192190
! CHECK: }
193191
! CHECK: %[[VAL_29:.*]] = arith.constant 0 : index
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
! Check that stack save and restore needed for elemental function result
2+
! allocation inside loops are not emitted directly in lowering, but inserted if
3+
! needed in the stack-reclaim pass.
4+
5+
! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s --check-prefix=CHECK-HLFIR
6+
! RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-LLVM
7+
subroutine foo(c1, c2)
8+
character(*), dimension(100) :: c1, c2
9+
interface
10+
elemental pure function func(c)
11+
character(*), intent(in) :: c
12+
character(len(c)) :: func
13+
end function
14+
end interface
15+
c1 = func(c2)
16+
end subroutine
17+
18+
! CHECK-HLFIR-NOT: stacksave
19+
! CHECK: return
20+
21+
! CHECK-LLVM: stacksave
22+
! CHECK-LLVM: stackrestore

0 commit comments

Comments
 (0)