Closed
Description
https://alive2.llvm.org/ce/z/on8IIK suggests
1 << cttz(z) = z & -z
is already folded by instcombine
Originally posted by @RKSimon in #90000 (comment)
This code:
export fn bar(y: u64) u64 {
if (y == 0) return 0;
return @as(u64, 1) << @intCast(@ctz(y));
}
Gives me this emit for the risc-v sifive u74:
bar:
neg a1, a0
and a0, a0, a1
ret
Exactly what we want.
Now, let's "upgrade" to the sifive x280:
bar:
ctz a1, a0
li a2, 1
sll a1, a2, a1
bnez a0, .LBB0_2
li a1, 0
.LBB0_2:
mv a0, a1
ret
Oops! Same problem occurs on x86 Zen 3:
bar:
tzcnt rax, rdi
mov ecx, 1
shlx rax, rcx, rax
cmovb rax, rdi
ret
And on aarch64 apple_latest:
bar:
rbit x8, x0
clz x8, x8
mov w9, #1
lsl x8, x9, x8
cmp x0, #0
csel x0, xzr, x8, eq
ret