Files
clang-p2996/flang/lib/Lower/Bridge.cpp
khaki3 ff7fca7fa8 [flang][cuda] Support memory cleanup at a return statement (#116304)
We generate `cuf.free` and `func.return` twice if a return statement
exists at the end of program.

```f90
program test
  integer, device :: a(10)
  return
end
```

```
% flang -x cuda test.cuf -mmlir --mlir-print-ir-after-all
error: loc("/path/to/test.cuf":3:3): 'func.return' op must be the last operation in the parent block
// -----// IR Dump After Fortran::lower::VerifierPass Failed () //----- //
```

Dumped IR:
```mlir
  "func.func"() <{function_type = () -> (), sym_name = "_QQmain"}> ({
...
    "cuf.free"(%5#1) <{data_attr = #cuf.cuda<device>}> : (!fir.ref<!fir.array<10xi32>>) -> ()
    "func.return"() : () -> ()
    "cuf.free"(%5#1) <{data_attr = #cuf.cuda<device>}> : (!fir.ref<!fir.array<10xi32>>) -> ()
    "func.return"() : () -> ()
}
...
```

The routine `genExitRoutine` in `Bridge.cpp` is guarded by
`blockIsUnterminated()` to make sure that `func.return` is generated
only at the end of a block. However, we redundantly run
`bridge.fctCtx().finalizeAndKeep()` before `genExitRoutine` in this
case, resulting in two pairs of `cuf.free` and `func.return`. This PR
fixes `Bridge.cpp` by using `blockIsUnterminated()` to guard
`finalizeAndKeep` as well.
2024-11-15 08:44:42 -08:00

269 KiB