void foo(void); void s(unsigned a, unsigned b) { unsigned x = ~b; if (x > 0 && x > a) foo(); } Clang -O3: s(unsigned int, unsigned int): # @s(unsigned int, unsigned int) cmp esi, -1 je .LBB0_2 not esi cmp esi, edi jbe .LBB0_2 jmp foo() # TAILCALL .LBB0_2: ret GCC -O3: s(unsigned int, unsigned int): not esi cmp esi, edi ja .L4 ret .L4: jmp foo()
define i1 @src(i32 %a, i32 %b) { %neg = xor i32 %b, -1 %cmp.not = icmp ne i32 %b, -1 %cmp1 = icmp ugt i32 %neg, %a %r = and i1 %cmp.not, %cmp1 ret i1 %r } define i1 @tgt(i32 %a, i32 %b) { %neg = xor i32 %b, -1 %cmp1 = icmp ugt i32 %neg, %a ret i1 %cmp1 } ------------------------------------------------------------------------- Logic-of-icmps - we probably want a generalization that matches a negated operand on 1 side and a signed or unsigned limit constant on the other.
Should be fixed with: https://reviews.llvm.org/rGe77ba263fe0e