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