<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/145375>145375</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Bad codegen with multiple paths for small struct return
</td>
</tr>
<tr>
<th>Labels</th>
<td>
llvm:optimizations,
missed-optimization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
aengelke
</td>
</tr>
</table>
<pre>
Clang generates a single return, SROA inserts code to merge struct fields there, but the tail is never duplicated causing suboptimal codegen. (For a slightly simpler case without the ternary at the return, InstCombine will optimize to "good" code on x86-64, but not on AArch64.)
```c++
struct X2 { char a, b; };
X2 s(unsigned num) {
if (num < 3) [[likely]] {
static constexpr X2 data[] = {{1, 1}, {2, 2}, {3, 3}};
return data[num];
}
return num == 12 ? X2{8, 7} : X2{0, 0};
}
```
Clang:
```
s(unsigned int):
cmp edi, 2
ja .LBB0_2
mov ecx, edi
lea rdx, [rip + s(unsigned int)::data]
movzx eax, byte ptr [rdx + 2*rcx]
movzx ecx, byte ptr [rdx + 2*rcx + 1]
shl ecx, 8
movzx eax, ax
or eax, ecx
ret
.LBB0_2:
xor edx, edx
xor eax, eax
cmp edi, 12
sete al
mov ecx, 1792
cmovne ecx, edx
shl eax, 3
movzx eax, ax
or eax, ecx
ret
```
GCC:
```
s(unsigned int):
cmp edi, 2
ja .L2
mov edi, edi
movzx eax, WORD PTR s(unsigned int)::data[rdi+rdi]
ret
.L2:
xor eax, eax
mov edx, 1800
cmp edi, 12
cmove eax, edx
ret
```
https://godbolt.org/z/a3Wb38Taf
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysVVFvozgQ_jXOy6iRGUIgDzxAopxOWmlPvZW2byeDJ-Cuwcg2vbS__mQIbRJttftwCMWxZ-abb-YbYeGcanqinCUlSw4rMfrW2FxQ35D-QavKyNd8r0XfQEM9WeHJgQCn-kYTWPKj7Rnu4e_HrwWo3pH1DmojCbyBjmxD4Lwdaw8nRVo68C1ZChHV6MMGvFAalIOeXsiCHAetauFJQi3GkAbcWJnBq07oCbihfg0Ms6OxgYhWTev1KzjVDZos1MIR_Kt8axZ8sr2wryDm7QflP3vn96arVB8CtIYpi3qbqDPExhjJEOdqTA_nbPuw3SzUe-PDYVHYut1u1gx3jBfh3fL5rRmW4eXFpQFPCCwtoW6FBTHBsLgElh5YHLyeEBzDbOwnQST0Y8dwF0IYLwAA1CmU3Y8dsHgP8WQMopVa_SD9ypIDSw5X_uFxXnhVQ2165-k82EBCCi9mtYHFc0BaRoFQFMjgPhxhWPFjH4c1DvuF75JibuiCGlgni0fwnR0vTjP5Q0gbIbD4CE_I0jIL4ClLA6FiPuLhiL8nm5Hee8t4Mc0ki4u745sWqt4HXSanhW7dDdNKUs0l8gKexWxbfylL_g9eeXfmZfauz8E7BH0YNc1xVk5GlpRWDcCwhE9YxMXcpcNthrdzyCAmkOrVEwzeTmjyPKEhw8LW50vce0D9q4Dpf3SbzrX6uqDsBnGmIM5X_sbO68UWwm6kZ7xYunbT5rOxQPLStPOd4RrwJtudONG1FI48gdCfixOlO7zBMi89XUl3vmvDhUH8uRi_0Ym5BdcT-Md-_z-N5eV5FrD-8tOhnH1vh_KuhO9fHw_w17fHX41kaQPY9HszL4vEP5H3UxUDv4v2Ucb5b-ob9KIrSPlJf1vvBxfY4JHhsTGyMtqvjW0YHt8YHkX8vYqzb-K0knksd_FOrCiP0oSnPMIkW7X5qeLbWKY1zyQ_pbudQMrkCUUVpfEWd9uVypFjwrcYR2myibI1zzaCb7bVVm6jmKoT23DqhNJrrV-6kHulnBspjzZJnCYrLSrSbrpSEYMLi4vL5SK8Mr1jGL6vDLFTzpF8uDYGW3JY2TwEPlRj49iGa-W8-8jmldeUl0IuN-J040E3aq8GTTAI3zo4GQuuE1ovV_D8FV6NVud3XVS-Hat1bTqGx4nwvDwM1jxT7RkepwIdw-Olxpcc_wsAAP__xHNP8A">