[flang-commits] [flang] 9df4aed - [flang] add some missing stackrestore with -fstack-arrays (#208161)
via flang-commits
flang-commits at lists.llvm.org
Wed Jul 8 09:10:49 PDT 2026
Author: jeanPerier
Date: 2026-07-08T18:10:43+02:00
New Revision: 9df4aed204020bc79be55afa7b177822759856fb
URL: https://github.com/llvm/llvm-project/commit/9df4aed204020bc79be55afa7b177822759856fb
DIFF: https://github.com/llvm/llvm-project/commit/9df4aed204020bc79be55afa7b177822759856fb.diff
LOG: [flang] add some missing stackrestore with -fstack-arrays (#208161)
In the StackArray pass that moves array temporaries from the heap to the
stack under -fstack-arrays, when visiting FreeMemOp to insert
stackrestore, the code was not unwrapping converts as done in other
parts of the code leading to the allocation conversion and stacksave
insertion to happen without the emission of the stackrestore.
Reuse the same utility as in the rest of the pass to get consistent
behavior and fix the memory leak.
Added:
Modified:
flang/lib/Optimizer/Transforms/StackArrays.cpp
flang/test/Transforms/stack-arrays.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/Transforms/StackArrays.cpp b/flang/lib/Optimizer/Transforms/StackArrays.cpp
index cfbd273b88ea6..4af26415a39d2 100644
--- a/flang/lib/Optimizer/Transforms/StackArrays.cpp
+++ b/flang/lib/Optimizer/Transforms/StackArrays.cpp
@@ -804,17 +804,11 @@ AllocMemConversion::insertAlloca(fir::AllocMemOp &oldAlloc,
static void
visitFreeMemOp(fir::AllocMemOp oldAlloc,
const std::function<void(mlir::Operation *)> &callBack) {
- for (mlir::Operation *user : oldAlloc->getUsers()) {
- if (auto declareOp = mlir::dyn_cast_if_present<fir::DeclareOp>(user)) {
- for (mlir::Operation *user : declareOp->getUsers()) {
- if (mlir::isa<fir::FreeMemOp>(user))
- callBack(user);
- }
- }
-
- if (mlir::isa<fir::FreeMemOp>(user))
- callBack(user);
- }
+ mlir::Operation *parent = oldAlloc->getParentOp();
+ parent->walk([&](fir::FreeMemOp freeOp) {
+ if (lookThroughDeclaresAndConverts(freeOp->getOperand(0)) == oldAlloc)
+ callBack(freeOp);
+ });
}
void AllocMemConversion::insertStackSaveRestore(
diff --git a/flang/test/Transforms/stack-arrays.fir b/flang/test/Transforms/stack-arrays.fir
index 25fc73153003a..7a005c69a1b04 100644
--- a/flang/test/Transforms/stack-arrays.fir
+++ b/flang/test/Transforms/stack-arrays.fir
@@ -495,5 +495,35 @@ func.func @finding_freemem_in_block() {
return
}
// CHECK-LABEL: func.func @finding_freemem_in_block()
+// CHECK: llvm.intr.stacksave
// CHECK: fir.alloca !fir.array<?xi32>
+// CHECK: llvm.intr.stackrestore
// CHECK-NOT: fir.freemem
+
+// Test temporary inside a CFG loop where freemem is reached via a convert
+// chain.
+func.func private @_QPuse_array(!fir.ref<!fir.array<?xf64>>) -> ()
+func.func @freemem_through_convert_in_loop(%arg0: i1, %n: index) {
+ cf.br ^bb1
+^bb1: // 2 preds: ^bb0, ^bb2
+ cf.cond_br %arg0, ^bb2, ^bb3
+^bb2: // pred: ^bb1
+ %shape = fir.shape %n : (index) -> !fir.shape<1>
+ %mem = fir.allocmem !fir.array<?xf64>, %n {bindc_name = ".tmp.array", uniq_name = ""}
+ %decl = fir.declare %mem(%shape) {uniq_name = ".tmp.array"} : (!fir.heap<!fir.array<?xf64>>, !fir.shape<1>) -> !fir.heap<!fir.array<?xf64>>
+ %ref = fir.convert %decl : (!fir.heap<!fir.array<?xf64>>) -> !fir.ref<!fir.array<?xf64>>
+ fir.call @_QPuse_array(%ref) : (!fir.ref<!fir.array<?xf64>>) -> ()
+ %heap = fir.convert %ref : (!fir.ref<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
+ fir.freemem %heap : !fir.heap<!fir.array<?xf64>>
+ cf.br ^bb1
+^bb3: // pred: ^bb1
+ return
+}
+// CHECK-LABEL: func.func @freemem_through_convert_in_loop(
+// CHECK: ^bb2:
+// CHECK: %[[SP:.*]] = llvm.intr.stacksave : !llvm.ptr
+// CHECK: fir.alloca !fir.array<?xf64>
+// CHECK: fir.call @_QPuse_array(
+// CHECK: llvm.intr.stackrestore %[[SP]] : !llvm.ptr
+// CHECK-NOT: fir.freemem
+// CHECK: cf.br ^bb1
More information about the flang-commits
mailing list