diff options
author | khaki3 <47756807+khaki3@users.noreply.github.com> | 2024-11-15 08:44:42 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-15 08:44:42 -0800 |
commit | ff7fca7fa8646d73f884ab8a351e4178499c4d05 (patch) | |
tree | 063678b0e7bea66b973b4ba26004d7b374a27547 /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 798a8941824dc2f83a169812e0edf7971d5f772b (diff) | |
download | llvm-ff7fca7fa8646d73f884ab8a351e4178499c4d05.zip llvm-ff7fca7fa8646d73f884ab8a351e4178499c4d05.tar.gz llvm-ff7fca7fa8646d73f884ab8a351e4178499c4d05.tar.bz2 |
[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.
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
0 files changed, 0 insertions, 0 deletions