<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/103501>103501</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[x86-64 BMI2] Missed canonicalization on ~blsmsk
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
Validark
</td>
</tr>
</table>
<pre>
This code:
```zig
export fn foo(a: u64) u64 {
return ~blsmsk(a);
}
fn blsmsk(a: u64) u64 {
return (a ^ (a - 1));
}
```
Gives this emit:
```asm
foo:
mov rax, rdi
neg rax
xor rax, rdi
ret
```
With inline assembly, we can force the compiler to do the thing we want:
```asm
export fn bar(a: u64) u64 {
return ~blsmsk_asm(a);
}
inline fn blsmsk_asm(src: u64) u64 {
return asm ("blsmsk %[src], %[ret]"
: [ret] "=r" (-> u64),
: [src] "r" (src),
);
}
```
```asm
bar:
blsmsk rax, rdi
not rax
ret
```
In my real code, I was doing a bitwise AND on `~blsmsk(a)`. Meaning the `not` can be folded into an `ANDN` instruction.
```zig
export fn foo(a: u64, b: u64) u64 {
return ~blsmsk(a) & b;
}
```
```asm
foo:
mov rax, rdi
neg rax
xor rax, rdi
and rax, rsi
ret
```
Again, with inline assembly, we can get:
```asm
bar:
blsmsk rax, rdi
andn rax, rax, rsi
ret
```
[Godbolt link](https://zig.godbolt.org/z/GMcf56rj7)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVU1z4jgQ_TXypQtKbn8ABx8gDKkcktPW7nFLtoTRRJZSkghJDvvbt9p2SJiZwDCuVITVr5_647UsQtCtVapixYoV60Ts48756m9htBT-MamdfK3-2ukAjZOKZUvG14y__y_58Pem22FHvTw5H2FrYescw7lg2RL2Zc5wQQuw2WoAAgB4Fffewn-1CV147NG4YNmIYLP157O2Fj7hvmIdKQkDrPg2_JhASsS_5H7P4PNRt_pZBYiUtOp0_CppEboxNOeOGBifzj33qxcvDG_AS31qt6rtbSebL86fdfIqngn7Hx13oK3RVoEIQXW1eSWag4JGUEN8oyDuFDSue9JGeYgOpOu34k7blpAHYS8n_NHlWvjruvwvkZzv9JjCseGjS_DNpbaL0FHHGeLgCQwLVqzIs1hTKYZ3KiO942l1if1oBTJna88QiXLCsm_j0QxvRr_RYaAnh3c07XwGEvlvq-_nclORj_oaM_taWC4eNXSFeO4sdK_glTDDoOMN3MFBBJCOlCGg1vGgg4LlwxqcBVbyH-a25FO4V8ISnCTFSm5dZCXv1Vcr2DojlQRtowPRMywf1g8E0DZEv2-idnb6p_fLDdRX3zXAsCS3P-zLVXNPA__LvlwaemHliT3oD9GfCXfZCm378T9_LbTq8ryfCHB8LulQWGmPxh9D_y1JsmJ162TtTASj7WM_svNdjE-BgsENw82bbqftgJk639IOw83tfbMtSv99xnCRyCqTi2whElWlM8xKjgvEZFcJmc9rmecLkSOKdJtumzlPxZwLkTV1jYmukGPO52nOMSsQp7Mam0I1is-zsqxnKcu56oQ2U2OeOzo-0SHsVZXyrOBpYkStTOi_q4hWHaC30rVSrBNfkdOk3reB5dzoEMMHTdTR9B_kl3k5KXNY3d-RE9zrEJSkrjmrG2H0m6CRoXEcdZ3svalOS9TquNvX08Z1DDd0xLhMnrz7rprIcNMHFhhuxsifK_w_AAD__2F8LvI">