<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/102694>102694</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Suboptimal code for checking if nth bit is set
</td>
</tr>
<tr>
<th>Labels</th>
<td>
backend:AArch64,
missed-optimization
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Kmeakin
</td>
</tr>
</table>
<pre>
https://godbolt.org/z/h54KPcvKh
```c
bool contains_unchecked(u32 bits, u8 index) {
return (bits & (1 << index)) != 0;
}
bool contains_checked(u32 bits, u8 index) {
if (index >= 32) {
return false;
}
return (bits & (1 << index)) != 0;
}
```
For `contains_unchecked`, LLVM generates optimal assembly.
The naive implementation would be
```asm
contains_unchecked:
lsr w8, w0, w1
mov w8, #0x1
lsl w8, w8, w1
ands w8, #0x1
cset w0, ne
```
But in this case, LLVM is smart enough to rewrite `(bits & (1 << index)) != 0` to `(bits >> index) != 0` and so save 2 instructions:
```asm
contains_unchecked:
lsr w8, w0, w1
and w0, w8, #0x1
ret
```
However, LLVM fails to make the same optimization when bounds checking is added to avoid UB:
```asm
contains_checked:
mov w8, #1
and w9, w1, #0xff
lsl w8, w8, w1
tst w8, w0
mov w8, #32
ccmp w9, w8, #2, ne
cset w0, lo
ret
```
I believe the optimal assembly would be:
```asm
lsr w8, w0, w1
and w0, w8, #0x1
and w9, w1, #0xff
cmp w9, #32
csel w0, w0, wzr, ls
ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVl2P6jYQ_TXOy2hRsENIHvLALhe12lupUj9eKyceiLuOjTwO3Lu_vnL4ygJ3u1sVIRKYGc85Z45jJJHeWMSKzR7ZbJnIPrTOV88dyhdtk9qp71UbwpaYWDC-Yny1cap2Jkyc3zC-emV81c6y51-b3XPL0iVLFyxPD-_m8L12zkDjbJDa0l-9bVpsXlAxXvSCQ60DMf4EfQHaKvzGeAls_ngoBQDwGHpvgfEipgLjebyfAhNPTDydi4Y6PmViCSkTx3o2Xx5v7iD5JA69jn2HGDDxJTYS_CZrhHgtDeEZSgyc4fx_vE5aj2munIco_63keRopfv365y-wQYteBiRw26A7aUASYVeb75PDKr-3CFbqHYLutgY7tEEG7SzsXW8U1HiFQFJ3-OVOX7F4q5AhP1z3RcSzH1Dtp8eczu1GQcZF-m16XW7G5cWb8uNLWkXvr9IQhiFjaG-v-YwVfewDaAuh1QSNJDyrqAmokz4AWtdvWggOPO69DgiD2J-YbZ7G6nFVNNmXkRtHmdIqIAckdwgctKXg-yZOh85a_-fB3B3KRVW4aHZHW4_hHR1_cnvcoT_Lt5baUKTdyReE0CKQ7PDgSP16tFuLFmrXx3kOsLXdRN2lUqhirdw5reCPx48wv-F9Y7YfES6PcpwIr9ef92Sg8Nb2b6I3UAS_MmzTbU9ATjl87N37zjbu5vH0zoh-hhqNxt1hHNfPhsvm_7HYH9rkH_XTh8cQtblk3FOP0IxaHT5fBy8a-jeFElUJVYpSJlhN51zwTJR5lrTVdJZikanpel5KWahSFlhOy7mSeSFmPM0TXfGUZ2mRlpzPeJZN5s18Ni-FymUmmgwFy1LspDYTY3ZdPFUTTdRjNU15XmaJkTUaGo5nzmvZvKCN9l0sfNPmGePRAIzzThOhehjvnBibLRNfxYUf6n5DLEuNpkCXVkEHg9VvfX0adOMUwtr50VZbgw1tPB-Hpx2GpPfm-j-BDm1fTxrXMb6Kix8vD1vv_sYmML4aSBHjqyOvXcX_CQAA__9qD09V">