Issue |
151288
|
Summary |
Missing optimizations involving byval arguments passing on x86_64
|
Labels |
new issue
|
Assignees |
|
Reporter |
akhvoshch
|
In System V x86_64 ABI large arguments are passed in stack. In IR code `byval` attribute is used for them.
Calling a function with `byval` argument requires making intermediate copy of argument bytes. But it seems like this copying is implemented in a target-specific way, somewhere in code generation. This results in poor generated code quality, since no IR optimizations can be done for `byval` arguments, including unnecessary loads/stores elimination.
Consider this example:
```cpp
#include <cstdint>
struct S
{
int64_t arr[12];
S()
{
for( int64_t i= 0; i < 12; ++i )
arr[i]= i * i * 3 + i * 7 + 13;
}
};
void Bar(S s);
void Foo()
{
Bar(S());
}
```
clang 20.1 produces following assembly:
```asm
Foo():
sub rsp, 200
mov qword ptr [rsp + 104], 13
mov qword ptr [rsp + 112], 23
mov qword ptr [rsp + 120], 39
mov qword ptr [rsp + 128], 61
mov qword ptr [rsp + 136], 89
mov qword ptr [rsp + 144], 123
mov qword ptr [rsp + 152], 163
mov qword ptr [rsp + 160], 209
mov qword ptr [rsp + 168], 261
mov qword ptr [rsp + 176], 319
mov qword ptr [rsp + 184], 383
mov qword ptr [rsp + 192], 453
movups xmm0, xmmword ptr [rsp + 184]
movups xmmword ptr [rsp + 80], xmm0
movups xmm0, xmmword ptr [rsp + 168]
movups xmmword ptr [rsp + 64], xmm0
movups xmm0, xmmword ptr [rsp + 104]
movups xmm1, xmmword ptr [rsp + 120]
movups xmm2, xmmword ptr [rsp + 136]
movups xmm3, xmmword ptr [rsp + 152]
movups xmmword ptr [rsp + 48], xmm3
movups xmmword ptr [rsp + 32], xmm2
movups xmmword ptr [rsp + 16], xmm1
movups xmmword ptr [rsp], xmm0
call Bar(S)@PLT
add rsp, 200
ret
```
https://godbolt.org/z/rzEzn18v9
It can be seen, that memory for a local variable is initialized first (first 12 `mov` instructions), then this memory is read and pushed to a new stack location in order to pass this variable to function `Bar`. Targeting a newer CPU (with `-march=skylake` option) only results in newer memory move instructions usage, but overall pattern remains the same.
I expect that LLVM can optimize such cases and move necessary values directly to the stack region of the argument. A lot of existing C++ code may benefit from such optimization, since it's nowadays pretty common to pass arguments by value (sine move-semantics was introduced).
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs