llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.09k stars 12k forks source link

Dead Code Elimination Regression at -O3 (trunk vs. 14.0.4) #56049

Open thetheodor opened 2 years ago

thetheodor commented 2 years ago
static struct { int a; } b, c;
static int d = -1;
void foo();
int main() {
    if (b.a)
        d = 2 | (b.a <= 0);
    for (; b.a; b.a++)
        c = b;
    if (!d)
        foo();
}

llvm-4c2bccfda3892ae13e97b6bfdbc99ec8cf5d095d (trunk) -O3 can not eliminate foo but llvm-llvmorg-14.0.4 -O3 can.

Target: x86_64-unknown-linux-gnu


llvm-4c2bccfda3892ae13e97b6bfdbc99ec8cf5d095d (trunk) -O3 -S -o /dev/stdout case.c

Reduced assembly

```asm main: # @main .cfi_startproc # %bb.0: pushq %rax .cfi_def_cfa_offset 16 cmpl $0, d(%rip) je .LBB0_1 # %bb.2: xorl %eax, %eax popq %rcx .cfi_def_cfa_offset 8 retq .LBB0_1: .cfi_def_cfa_offset 16 xorl %eax, %eax callq foo@PLT xorl %eax, %eax popq %rcx .cfi_def_cfa_offset 8 retq .Lfunc_end0: .size main, .Lfunc_end0-main ```


llvm-llvmorg-14.0.4 -O3 -S -o /dev/stdout case.c

Reduced assembly

```asm main: # @main .cfi_startproc # %bb.0: xorl %eax, %eax retq .Lfunc_end0: .size main, .Lfunc_end0-main ```


Bisection

Bisected to: 6990e7477d24ff585ae86549f5280f0be65422a6 Committed by: @alexander-shaposhnikov

nikic commented 2 years ago

During IPSCCP, we have the following code:

 %conv = zext i1 %cmp to i32
 %or = or i32 2, %conv

So we compute the range [2, 2] | [0, 1]. Previously, this resulted in [2,-1]. Now we get the more precise range [2,3]. This is combined with the range [-1, -1] from the initializer, so we now get [-1, 3] rather than [2, -1]. The new range is much more precise, but happens to cross zero, so the zero comparison is not folded.

I think this is an acceptable result of ConstantRange lattice value imprecision.

fhahn commented 2 years ago

Yeah that's an issue we've seen before in other cases as well I think. Given how common null/non-null checks are it might be worth exploring a way to track whether a range includes 0 or not

vfdff commented 2 years ago

Does we have a more precise range to expression [2,3] || [-1, -1], which doesn't include 0 ?

fhahn commented 2 years ago

Does we have a more precise range to expression [2,3] || [-1, -1], which doesn't include 0 ?

No, ConstantRange can only represent a single contiguous range.