<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/115770>115770</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Missed optimisation: conditional shift by power-of-two can be replaced with a shift by shifted flag
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          AnthonyMikh
      </td>
    </tr>
</table>

<pre>
    Consider this code ([godbolt](https://godbolt.org/z/8on1GdYK9)):

```c
int nibble_to_byte(int nibble, _Bool is_high) {
    if (is_high) {
 return nibble << 4;
    } else {
        return nibble;
 }
}

int nibble_to_byte2(int nibble, _Bool is_high) {
    return nibble << (is_high << 2);
}
```

I expected the compiler to compile both functions the same way. Instead, clang 19.1.0 generates the following asm:

```
nibble_to_byte:
        mov     eax, edi
 shl     eax, 4
        test    esi, esi
        cmove   eax, edi
        ret

nibble_to_byte2:
        mov     eax, edi
 lea     ecx, [4*rsi]
        shl     eax, cl
 ret
```

I believe that the second version is more optimal since it touches less bits in flags register and thus is more amendable to instruction reordering in processor.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVNGO6jYQ_RrzMlqUOMkCD3lYFlFdVfcD-rRy7EkyrWMjzwQu_foqAS4L2lu1KCK2j2c4Z84whpm6gFiraquq3cKM0sdUvwXpYzh_p7_6RRPduX6PgclhAumJwUaHoPRaVdsuuiZ6UdVO6XUvcmBVvCm9V3p_hZYxdUrv_1Z6v44h_8398ftG6fkp3lS2U9nt-zW7PPaypyAQqGk8fkj8aM6CSq_vh0q_w8c2Rg_EHz11vdIbUKvtJRgAgNqJ5JdoQhlTuGYCVbyr4h1KVXyKVqsdoGd8zDl9HoLvMWq1uwr5ufiFDv0_hXzJ9i7tdqLnmm6fSdzK-pnTN8AfB7SCDqRHsHE4kJ_sjbc1NFF6aMdghWLg-RqbAeFkzkv4FljQuIm69SZ0kG-W-TKDDgMmI3i530bv44lCB4aHX7l92T4Zfbt7K_kQj_MbzY_pN9HRFefefwbKxzBBlhllmsOYHnE7xCN-lfbu9GfOzy7-Z5YezQWwM6Cqban0W2Ka_jcPKZ70WH9v2H-1s0FPeESQ3sjFK7QxODhiYooBiGGICSEehAbjgSlYBBKQONoeGTwyQ0PCQAFabzqGhB2xYAITpjYZ-WcWM2BwZmpGiUCBJY1zm0DCmBymyXIKcEjRInNMy4WrC7cpNmaBdb4q8qLaVK_Foq_XbbZ22jpTrdZ5sdGFLda2ca0ti6rFMl9QrTNd5nme6zzXZbEsWoNNW7Zam5V-xVdVZjgY8kvvj8M0bBbEPGKd59VqlS28adDzPN-0DniCGVVaT-Mu1VPQSzN2rMrMEwvf0wiJx_o7MaO71I3YTCpV8QZTcWnaTLXsqRVoznCIJ0wvsX2RUwRrAjQICQ_eWHRwIunB3C_PC3RzrRdj8vXT9CTpx2Zp46D0fuJ0fb0cUvwTrSi9n5Ww0vur1GOt_wkAAP__nRe_vg">