Issue 91305
Summary `1 << cttz(z)` should be folded into `z & -z` even on machines with cttz built-in
Labels new issue
Assignees
Reporter Validark
    > https://alive2.llvm.org/ce/z/on8IIK suggests `1 << cttz(z) = z & -z` is already folded by instcombine

_Originally posted by @RKSimon in https://github.com/llvm/llvm-project/issues/90000#issuecomment-2081442262_

This code:

```zig
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:

```asm
bar:
        neg a1, a0
        and     a0, a0, a1
        ret
```

Exactly what we want.

Now, let's "upgrade" to the sifive x280:

```asm
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:

```asm
bar:
        tzcnt   rax, rdi
        mov     ecx, 1
        shlx    rax, rcx, rax
        cmovb   rax, rdi
 ret
```

And on aarch64 apple_latest:

```asm
bar:
 rbit    x8, x0
        clz     x8, x8
        mov     w9, #1
 lsl     x8, x9, x8
        cmp     x0, #0
        csel    x0, xzr, x8, eq
        ret
```

[Godbolt link](https://zig.godbolt.org/z/8be9Ef4h4)

Related: https://github.com/llvm/llvm-project/issues/84763 https://github.com/llvm/llvm-project/issues/90000
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to