<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">