diff --git a/flang/lib/Optimizer/Transforms/StackArrays.cpp b/flang/lib/Optimizer/Transforms/StackArrays.cpp --- a/flang/lib/Optimizer/Transforms/StackArrays.cpp +++ b/flang/lib/Optimizer/Transforms/StackArrays.cpp @@ -431,12 +431,14 @@ } LatticePoint point{func}; - func->walk([&](mlir::func::ReturnOp child) { - const LatticePoint *lattice = solver.lookupState(child); + auto joinOperationLattice = [&](mlir::Operation *op) { + const LatticePoint *lattice = solver.lookupState(op); // there will be no lattice for an unreachable block if (lattice) point.join(*lattice); - }); + }; + func->walk([&](mlir::func::ReturnOp child) { joinOperationLattice(child); }); + func->walk([&](fir::UnreachableOp child) { joinOperationLattice(child); }); llvm::DenseSet freedValues; point.appendFreedValues(freedValues); diff --git a/flang/test/Transforms/stack-arrays.fir b/flang/test/Transforms/stack-arrays.fir --- a/flang/test/Transforms/stack-arrays.fir +++ b/flang/test/Transforms/stack-arrays.fir @@ -307,3 +307,20 @@ // CHECK-NEXT: } // CHECK-NEXT: return // CHECK-NEXT: } + +// function terminated by stop statement +func.func @stop_terminator() { + %0 = fir.allocmem !fir.array<42xi32> + fir.freemem %0 : !fir.heap> + %c0_i32 = arith.constant 0 : i32 + %false = arith.constant false + %none = fir.call @_FortranAStopStatement(%c0_i32, %false, %false) : (i32, i1, i1) -> none + fir.unreachable +} +// CHECK: func.func @stop_terminator() { +// CHECK-NEXT: fir.alloca !fir.array<42xi32> +// CHECK-NEXT: %[[ZERO:.*]] = arith.constant 0 : i32 +// CHECK-NEXT: %[[FALSE:.*]] = arith.constant false +// CHECK-NEXT: %[[NONE:.*]] = fir.call @_FortranAStopStatement(%[[ZERO]], %[[FALSE]], %[[FALSE]]) : (i32, i1, i1) -> none +// CHECK-NEXT: fir.unreachable +// CHECK-NEXT: }