[CIR] Avoid illegal copies of return values
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Because ABI calling convention lowering is deferred in CIR, we do not use `sret` parameters for functions that return a structure that can't be trivially copied. This might be OK except that we currently also generate a store to the `__retval` alloca and a reload from there to return the value. The following example shows this behavior:
```c++
struct S {
S();
S(const S&) = delete;
~S();
};
S foo();
S bar() {
return foo();
}
```
That compiles to the following CIR:
```
cir.func private @_Z3foov() -> !rec_S
cir.func dso_local @_Z3barb() -> !rec_S {
%0 = cir.alloca !rec_S, !cir.ptr, ["__retval"] {alignment = 1 : i64}
%1 = cir.call @_Z3foov() : () -> !rec_S
cir.store align(1) %1, %0 : !rec_S, !cir.ptr
%2 = cir.load %0 : !cir.ptr, !rec_S
cir.return %2 : !rec_S
}
```
We need to clean up the CIR generation to avoid such copies.
Note that this issue also concerns classes with non-trivial, but non deleted copy constructors.
While the store and reload shown in the example above will almost certainly be eliminated later in the compilation pipeline, the intent of this issue is to avoid having this semantically incorrect representation in any intermediate state.
Contributor guide
Assessment
This issue has not been assessed yet.