[llvm] [CodeGenPrepare] Don't sink icmp eq (and X, mask), 0 into return blocks (PR #200460)

Aayush Shrivastava via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 15 02:07:08 PDT 2026


iamaayushrivastava wrote:

> Have you investigated other icmp patterns? I'm trying to guess if there's any cases we need to be careful with that will cause bad codegen.
> 
> ```c
> bool testtopbits(uint64_t x, int *y) {
>   uint64_t c = (15LL << 60);
>   if (x & c)
>     *y = 0;
>   return !!(x & c);
> }
> ```
> 
> ```assembly
> testtopbits(unsigned long, int*): # @testtopbits(unsigned long, int*)
> # %bb.0: # %entry
>   shrq $60, %rdi
>   je .LBB0_2
> # %bb.1: # %if.then
>   movl $0, (%rsi)
> .LBB0_2: # %if.end
>   testq %rdi, %rdi
>   setne %al
>   retq
> ```
> 
> What about multiple active icmp results?

Thanks for the example! I tested it and that case doesn't go through an `and` at all, InstCombine turns it into `x > C` directly, so this fix doesn't apply there. I also tried skipping the sink for it manually and got the exact same assembly, so the extra test isn't caused by sinking, it's because flags don't carry over between blocks, a separate issue. I also checked a case with 3 uses of the same icmp (branch + return + something else), and it behaved correctly only the return use is protected, the rest still sink as before.

https://github.com/llvm/llvm-project/pull/200460


More information about the llvm-commits mailing list