<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/96455>96455</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Bad codegen using `@llvm.ctlz.i8/i16`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
CrazyboyQCD
</td>
</tr>
</table>
<pre>
`llvm.ctlz.i8/i16` generates worse code than `llvm.ctlz.i32/i64`, and by doing cast and shift it will be better.
```rust
pub fn u8_leading_ones(v: u8) -> usize {
v.leading_ones() as _
}
pub fn u16_leading_ones(v: u16) -> usize {
v.leading_ones() as _
}
pub fn u8_leading_ones_shift(v: u8) -> usize {
((v as u32) << (u32::BITS - u8::BITS)).leading_ones() as _
}
pub fn u16_leading_ones_shift(v: u16) -> usize {
((v as u32) << (u32::BITS - u16::BITS)).leading_ones() as _
}
pub fn u32_leading_ones(v: u32) -> usize {
v.leading_ones() as _
}
pub fn u64_leading_ones(v: u64) -> usize {
v.leading_ones() as _
}
```
`lzcnt` disabled: [Godbolt Link](https://godbolt.org/z/6K3zcKsoM).
```asm
u8_leading_ones:
xor dil, -1
je .LBB0_1
movzx eax, dil
bsr eax, eax
xor eax, 7
movzx eax, al
ret
.LBB0_1:
mov al, 8
movzx eax, al
ret
u16_leading_ones:
xor di, -1
je .LBB1_1
bsr ax, di
xor eax, 15
movzx eax, ax
ret
.LBB1_1:
mov ax, 16
movzx eax, ax
ret
u8_leading_ones_shift:
shl edi, 24
not edi
bsr eax, edi
xor eax, 31
ret
u16_leading_ones_shift:
shl edi, 16
not edi
bsr eax, edi
xor eax, 31
ret
u32_leading_ones:
xor edi, -1
je .LBB4_1
bsr eax, edi
xor eax, 31
mov eax, eax
ret
.LBB4_1:
mov eax, 32
mov eax, eax
ret
u64_leading_ones:
xor rdi, -1
je .LBB5_2
bsr rax, rdi
xor rax, 63
ret
.LBB5_2:
mov eax, 64
ret
```
`lzcnt` enabled: [Godbolt link](https://godbolt.org/z/x1zGvnba3).
```asm
u8_leading_ones:
not dil
movzx eax, dil
lzcnt eax, eax
add eax, -24
movzx eax, al
ret
u16_leading_ones:
not edi
lzcnt ax, di
movzx eax, ax
ret
u8_leading_ones_shift:
shl edi, 24
not edi
lzcnt eax, edi
ret
u16_leading_ones_shift:
shl edi, 16
not edi
lzcnt eax, edi
ret
u32_leading_ones:
not edi
lzcnt eax, edi
ret
u64_leading_ones:
not rdi
lzcnt rax, rdi
ret
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEV11zqzYQ_TXiZccMSCDDAw-xXd_p3NuHTvvuESBjpTJkkHAc__qO-IhjBfxxm7aaJJpovXuOjnZXFlNKFCXnCQoXKFw5rNG7qk6WNTu9pdXb78uVk1b5W4KoJ-Vh72ZanlwRIbwWPkXUg4KXvGaaK3itasUhq3IOesdKuHQh2PjQAFEP4SWwMof0DfJKlAVkTOl2Re3EVoPQ8CqkhJRDyrXmtYu8FfKe-r_U637qRulu6aVJYVtCE20kZ7koi01VcoVwdEDkCZoI4RhmiPwCjRInDmi-6Pzg4FoO5pNMwaaHmq8-Ig8wPh3H8ekkEMBPYl1uadMKdMfGAKBFiA4GojHix4DIEpGlMZgF8oTI0-LXP_-AmYn0_i_CMcLxVwhjsb0uz0N0ffolfAkeP8gO_2sPkgbjWDT459k5VIRVJvKUldrUaC4USyXPDSAKF9-qPK2khh-i_AuFK4SjndYvykiK1wivi87uVnWB8PqE8Jp-J6fsu6p-M0pboEztuxW7_EjPBI5VbXSDXEhT-jP_rKUZz7yb3R-LhbexjPvqcDoCAGdH42tCdPZUdUF7g5kuHAfQ3j6_GpbJS3PN-84ycHrfy9m_nVm7o2gs-K3QvWh2M7GRzuJdaPdRNN8WbdBm0OyqMn54XZrjFWn8CWn6yPS-yLYkoz3PhlE72e2iEwYHl-ay0q1pVJchZ24oQ_wJguN97gZDW41_laHd2aayiltp1Y9n3iZWMJVYj9L7kBpT9XqRV8GVkhti495srU8H7qWxG_GYNPWkLO0wFMMNHtem7njUY9r0Nkqu7N0EvrF3Gnw69ltXAC_HbgB59w1w9E_fDmXKyE_dACbXob8B7mvv_Wj5jx0uy_OPiszs-p9q8I-234H5p1QfmI332P-91dnCvdv_u152N4VbzermGUy1o0dLfwA61-6AMFXUnwvQyROSxyRmDk_8uR9j3_MD4uySeJuyOY3InAUkirJtGmUZjnIWeH5GUhY5IsEeDjza_mJM3GAeYG_L8ywPo7kXcxR4fM-EdNtnVVUXjlCq4UlMgzB0JEu5VO07DuOSv0JrRBibZ12dGJ9Z2hQKBZ4USqtzFC205MmC5e3jreCl-SZaFuYBZz489uxzmlomVs8QetekblbtEV4bp36avdTVM8-08TWMFMLrjvEhwX8HAAD__zoy3iA">