Do (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1 rather than (A == C1 || A == C2) -> (A | (C1 ^ C2)) == C2 when C1 ^ C2 is a power of 2.

Differential Revision: http://reviews.llvm.org/D14223

Patch by Amaury SECHET!

llvm-svn: 254518
This commit is contained in:
David Majnemer 2015-12-02 16:15:07 +00:00
parent c5a6da0ed1
commit 942003acc6
4 changed files with 9 additions and 9 deletions

View File

@ -1962,14 +1962,14 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
case ICmpInst::ICMP_EQ: case ICmpInst::ICMP_EQ:
if (LHS->getOperand(0) == RHS->getOperand(0)) { if (LHS->getOperand(0) == RHS->getOperand(0)) {
// if LHSCst and RHSCst differ only by one bit: // if LHSCst and RHSCst differ only by one bit:
// (A == C1 || A == C2) -> (A & ~(C1 ^ C2)) == C1 // (A == C1 || A == C2) -> (A | (C1 ^ C2)) == C2
assert(LHSCst->getValue().ule(LHSCst->getValue())); assert(LHSCst->getValue().ule(LHSCst->getValue()));
APInt Xor = LHSCst->getValue() ^ RHSCst->getValue(); APInt Xor = LHSCst->getValue() ^ RHSCst->getValue();
if (Xor.isPowerOf2()) { if (Xor.isPowerOf2()) {
Value *NegCst = Builder->getInt(~Xor); Value *Cst = Builder->getInt(Xor);
Value *And = Builder->CreateAnd(LHS->getOperand(0), NegCst); Value *Or = Builder->CreateOr(LHS->getOperand(0), Cst);
return Builder->CreateICmp(ICmpInst::ICMP_EQ, And, LHSCst); return Builder->CreateICmp(ICmpInst::ICMP_EQ, Or, RHSCst);
} }
} }

View File

@ -819,8 +819,8 @@ define i1 @test68(i32 %x) nounwind uwtable {
; PR14708 ; PR14708
; CHECK-LABEL: @test69( ; CHECK-LABEL: @test69(
; CHECK: %1 = and i32 %c, -33 ; CHECK: %1 = or i32 %c, 32
; CHECK: %2 = icmp eq i32 %1, 65 ; CHECK: %2 = icmp eq i32 %1, 97
; CHECK: ret i1 %2 ; CHECK: ret i1 %2
define i1 @test69(i32 %c) nounwind uwtable { define i1 @test69(i32 %c) nounwind uwtable {
%1 = icmp eq i32 %c, 97 %1 = icmp eq i32 %c, 97

View File

@ -148,8 +148,8 @@ define i1 @test8(i32 %X) {
%S = icmp eq i16 %R, 0 %S = icmp eq i16 %R, 0
ret i1 %S ret i1 %S
; CHECK-LABEL: @test8( ; CHECK-LABEL: @test8(
; CHECK-NEXT: and i32 %X, -2 ; CHECK-NEXT: or i32 %X, 1
; CHECK-NEXT: icmp eq i32 {{.*}}, 8 ; CHECK-NEXT: icmp eq i32 {{.*}}, 9
; CHECK-NEXT: ret i1 ; CHECK-NEXT: ret i1
} }

View File

@ -182,7 +182,7 @@ define i1 @test19(i32 %A) {
%D = or i1 %B, %C %D = or i1 %B, %C
ret i1 %D ret i1 %D
; CHECK-LABEL: @test19( ; CHECK-LABEL: @test19(
; CHECK: and i32 ; CHECK: or i32
; CHECK: icmp eq ; CHECK: icmp eq
; CHECK: ret i1 ; CHECK: ret i1
} }