llvm / llvm-project

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

Missed elimination of comparison with zero #46623

Open davidbolvansky opened 4 years ago

davidbolvansky commented 4 years ago
Bugzilla Link 47279
Version trunk
OS Linux
CC @fhahn,@RKSimon,@rotateright

Extended Description

extern void foo (void);

void bar (int z, unsigned int y) { long long x = z; y &= 0xf; if (x >= 0 && x < (int) y) foo (); }

Clang -O3: bar: # @​bar test edi, edi js .LBB0_2 and esi, 15 cmp esi, edi jbe .LBB0_2 jmp foo # TAILCALL .LBB0_2: ret

GCC -O3: bar: and esi, 15 cmp edi, esi jb .L4 ret .L4: jmp foo

rotateright commented 3 years ago

A variation of the example in comment 1: https://alive2.llvm.org/ce/z/GTrSpN

define i1 @​src(i32 %x, i32 %y) { %s = sext i32 %x to i64 %z = zext i32 %y to i64 %r = icmp ugt i64 %s, %z ret i1 %r }

define i1 @​tgt(i32 %x, i32 %y) { %s = icmp slt i32 %x, 0 %c = icmp ugt i32 %x, %y %a = or i1 %s, %c ret i1 %a }

rotateright commented 4 years ago

Not sure if it changes anything for this particular example, but we have a potential missing canonicalization from cmp-of-casts to logic-of-cmps: https://alive2.llvm.org/ce/z/ZQCZq-

define i1 @​src(i32 %x, i32 %y) { %s = sext i32 %x to i64 %z = zext i32 %y to i64 %r = icmp ult i64 %s, %z ret i1 %r }

define i1 @​tgt(i32 %x, i32 %y) { %s = icmp sgt i32 %x, -1 %c = icmp ult i32 %x, %y %a = and i1 %s, %c ret i1 %a }