<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/102703>102703</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[AArch64] Fold `and` and `cmp` into `tst`
</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/Mh7q8TY99
InstCombine is able to fold `(x & 0xFF) < C)` into `(x & -C) != 0`
eg:
```c
bool ult32_u32(u32 x) { return (x & 0xFF) < 32; }
```
produces
```asm
ult32_u32:
tst w0, #0xe0
cset w0, eq
ret
```
But the same transform is not done in later stages, so if the and is introduced due to eg passing a u8 in a u32 register, the fold is not performed:
```c
bool ult32_u8(u8 x) { return x < 32; }
```
```asm
ult32_u8:
and w8, w0, #0xff
cmp w8, #32
cset w0, lo
ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyMlE-PszYQxj_NcBklMmMgcOCQP0Kqqt566akyMBB3AbO22ab76SuTrJLdfd_dN4pixX6YZ2Z-jJVzup-YS0gPkJ4itfizseXvI6snPUW1af8rz97PDuQeqAKqetPWZvBbY3ug6hWo-uO8e87__KsoQJxA7K-_v03OH81Y64lRO1T1wOgNdmZoETIBlF8QKENxqSqgAkEe8QhUQCZQT968E22Oq4RikCcUQfJoxX1I7rqRieu3uf6vjRlwGbykvxdJQPkiCS9rsN0BLfvFTvjDXCSBPCDsTh8CPxrP1rRLw-6DRLnxunM3fssPbx_v_Lr-K4COCCTFhcV7SePY3yX8_P7Usv8iscPi0Z8ZnRoZvVWT64wdA4fJeGxNYDLhoDxbdF717IKHM6i79Tk1tUGsJ3-tsMV2WfFxj3N4ZaYeFS55iKIw9NRyr51nG-KECCvnm9_MNthze8f0Law8sMo_obr8Mpuf0sg_wQjVrp3OQ_YPSLruJmzG-UEBJCV9BWsw38GK2lK2hSxUxGW8I0lJmqVxdC4TUSRUqDjrmLtY5XUSx0LW8U5kSaZSFemSBCUiFwVJEmm8zdtYxjsW1HHSdiKFRPCo9LAdhpcxTGmknVu4jAXthIwGVfPg1nEnqlXzxFPgst_b5pwlQAR0BKJRO8ftxsxej_pVeW2mcJaeIluGwJt66R0kYtDOu7uV135Y75K3eOkJq9vIq6kNkxu6HZiP8-Ooe-dDWxY7fLxutD8v9bYxI1AVfG7LZrbmH248ULXW54CqW4kvJf0fAAD__6OCU_0">