<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/84183>84183</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[LLVM] Incorrect call lowering of aggregates in System-V ABI
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:X86,
llvm
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Sirraide
</td>
</tr>
</table>
<pre>
According to the System-V ABI, adjacent fields of small aggregates sometimes need to be packed into a single register, e.g. an aggregate type such as
```llvm
{ i8, i8, i8, i8 }
```
should be passed as a single `i32`. However, LLVM incorrectly promotes the fields and passes in separate registers, e.g. this
```llvm
%color = type { i8, i8, i8, i8 }
declare void @f(%color)
define void @g() {
call void @f(%color { i8 1, i8 2, i8 3, i8 4 })
ret void
}
```
emits the following on x86-64 linux
```asm
g:
push rax
mov edi, 1
mov esi, 2
mov edx, 3
mov ecx, 4
call f@PLT
pop rax
ret
```
even though the entire struct should be passed in `edi` as though it were one `i32`.
This works just fine for C and C++ because Clang codegen actually handles this upfront, but this negatively impacts users of LLVM who as a result have to implement this themselves. Imo, it would make sense to (also) handle this in LLVM rather than (just) in the frontend.
Afaik this is a known problem, but since I couldn’t find any other issues or prs referencing this (please let me know if I missed something, though), I wanted to document this here and also ask if there is any interest in improving support for this.
I’d be open to try and implement support for this myself, but my contributions here are mostly limited to Clang, so I’m not that familiar with this part of LLVM—as a result, I’m candidly not entirely sure where this should best be implemented.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyEVltv4zgP_TXKC9HAkXNxHvLQy1d8AWaBBWYw2FdFom1NdTFEOWn-_YJy0rTdzm5RRLAlHfIcHVJWRLYLiDuxehCrp5kacx_T7rtNSVmDs0M059291jEZGzrIEXKP8P1MGf3dT7h_2Av5CMr8UhpDhtaiMwSxBfLKOVBdl7BTGQkoeszWI0FANIx0QBiUfkEDNuQICsiGziEk7CxlTIyM824OKtyAIJ8HBBp1D4pE9SSqe7Gupn_njv7yavMAtmGAj78gNk-fNk2P1MfRmSklIjSg6JaQWFe2lmJdzeH_8YTHKbVv337-ATbomBLq7M4wpOgjU2WJLkqoYCZEAhuAcFCJSVwp0hvH3Nt_oSNXOrqYQNRPkwD_TdCgdiohHKM1IJZVK2RzxRFyewG-LG1tuK3sysotx5jmATQf5ldIl0RgcQkvL2N9GZcloWs4gIS54FyP6evTQG_zRcboXDyx9WKA12Z9t16Cs2F8_bRP0UWqTtT312DT3zBSz2NSrx8nfDyWEY3lbBe_maUyK3-395Vn69_M6jK7_DhbxASAViyrP7_9-JRtHODLbBPmr7U6YoDcx7Hri2IYsk0IlNOoM_zD1zawnZnyumKTX3baDCdMCDG8t_t7k_zoLcEppheCXyNxqQc-ngSPxeSPQj4I-QAH1GokhEenQgc6GuwwgNJ5VM6doVfBuFIilmAc2hRDZokOY57eBa5ye0R3BusHpTPBSJhKTykVd-rjVJwJaXQZenVE7ibWDw49N6GCk3v0hO6INIe9j8WOGU5FDa9eEAgDlY1CNspRZMdP2U0ANkzxkso9Jsi9CryUufNSGyZ_MgEM5oNU962yLxcUzvQlxFPg9nBw6K9syQaNsAfNKQXxPymaSmy3RVgDKpwhlsCWaESCmGBIBAlbTBh0acYcQMhmcKgIwWEGjyUY2Bb24G058dJ4exs6jjwdNxekfIQ9nFTIUzM2UY839Xr2Ah8rKwOKXhgxl7fMKJy5ZWNCyiyE9UOKR06JxmGIKRdfMNAHWfZvJIsh48DGjZDTuYS6HeBnFPBnQtdelfNn0DHkZA9jtjFcs00IPhI3Yme9vdAqNuSNFOEW30OIzFRlaJW3zqoEJ5v7KdqgUr7a7bpl-c5yRbp3WFoFY407F9Cp_NwZaEwIp5JaQX2rRMrM_o0tmvnM7GqzrbdqhrvFptpu6k29bmb9rt42yw2aGg-omlbLtVxiuzCmle1K6nY9sztZyWVVV-vFqpLLZn4wm-WqkVJtsakXilsMemXdnC-TeUzdrPhp1ywXTT1z6oCOyt0v5YHv4mBEff9XsxaSO7mQslxCUvK3Qdrxw91h7EgsK2cp0w022-zKV0RRbfUE--vNOPU7F0-YSh9v338V2PDhY2I2Jrfrcx6I27h8FvK5s7kfD3MdvZDPUzZluBtS_IU6C_k8lYiQz4XV3wEAAP__jLjCCg">