aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp48
-rw-r--r--test/Transforms/InstCombine/sign-test-and-or.ll24
2 files changed, 35 insertions, 37 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 96ca40a..b4d3e62 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -745,18 +745,17 @@ Value *InstCombiner::FoldAndOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
}
// (X & C) == 0 & X > -1 -> (X & (C | SignBit)) == 0
- if (LHS->hasOneUse() && RHS->hasOneUse() &&
- ((LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero() &&
- RHSCC == ICmpInst::ICMP_SGT && RHSCst->isAllOnesValue()) ||
- (RHSCC == ICmpInst::ICMP_EQ && RHSCst->isZero() &&
- LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue()))) {
- BinaryOperator *BO =
- dyn_cast<BinaryOperator>(LHSCC == ICmpInst::ICMP_EQ ? Val : Val2);
- ConstantInt *AndCst;
- if (BO && match(BO, m_OneUse(m_And(m_Value(), m_ConstantInt(AndCst))))) {
- APInt New = AndCst->getValue() | APInt::getSignBit(AndCst->getBitWidth());
- BO->setOperand(1, ConstantInt::get(AndCst->getContext(), New));
- return BO == Val ? LHS : RHS;
+ if ((LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero() &&
+ RHSCC == ICmpInst::ICMP_SGT && RHSCst->isAllOnesValue()) ||
+ (RHSCC == ICmpInst::ICMP_EQ && RHSCst->isZero() &&
+ LHSCC == ICmpInst::ICMP_SGT && LHSCst->isAllOnesValue())) {
+ ICmpInst *I = LHSCC == ICmpInst::ICMP_EQ ? LHS : RHS;
+ Value *X; ConstantInt *C;
+ if (I->hasOneUse() &&
+ match(I->getOperand(0), m_OneUse(m_And(m_Value(X), m_ConstantInt(C))))){
+ APInt New = C->getValue() | APInt::getSignBit(C->getBitWidth());
+ return Builder->CreateICmpEQ(Builder->CreateAnd(X, Builder->getInt(New)),
+ I->getOperand(1));
}
}
@@ -1458,19 +1457,18 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
}
}
- // (X & C) != 0 & X < 0 -> (X & (C | SignBit)) != 0
- if (LHS->hasOneUse() && RHS->hasOneUse() &&
- ((LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero() &&
- RHSCC == ICmpInst::ICMP_SLT && RHSCst->isZero()) ||
- (RHSCC == ICmpInst::ICMP_NE && RHSCst->isZero() &&
- LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero()))) {
- BinaryOperator *BO =
- dyn_cast<BinaryOperator>(LHSCC == ICmpInst::ICMP_NE ? Val : Val2);
- ConstantInt *AndCst;
- if (BO && match(BO, m_OneUse(m_And(m_Value(), m_ConstantInt(AndCst))))) {
- APInt New = AndCst->getValue() | APInt::getSignBit(AndCst->getBitWidth());
- BO->setOperand(1, ConstantInt::get(AndCst->getContext(), New));
- return BO == Val ? LHS : RHS;
+ // (X & C) != 0 | X < 0 -> (X & (C | SignBit)) != 0
+ if ((LHSCC == ICmpInst::ICMP_NE && LHSCst->isZero() &&
+ RHSCC == ICmpInst::ICMP_SLT && RHSCst->isZero()) ||
+ (RHSCC == ICmpInst::ICMP_NE && RHSCst->isZero() &&
+ LHSCC == ICmpInst::ICMP_SLT && LHSCst->isZero())) {
+ ICmpInst *I = LHSCC == ICmpInst::ICMP_NE ? LHS : RHS;
+ Value *X; ConstantInt *C;
+ if (I->hasOneUse() &&
+ match(I->getOperand(0), m_OneUse(m_And(m_Value(X), m_ConstantInt(C))))){
+ APInt New = C->getValue() | APInt::getSignBit(C->getBitWidth());
+ return Builder->CreateICmpNE(Builder->CreateAnd(X, Builder->getInt(New)),
+ I->getOperand(1));
}
}
diff --git a/test/Transforms/InstCombine/sign-test-and-or.ll b/test/Transforms/InstCombine/sign-test-and-or.ll
index 2a5f772..3f2141d 100644
--- a/test/Transforms/InstCombine/sign-test-and-or.ll
+++ b/test/Transforms/InstCombine/sign-test-and-or.ll
@@ -86,9 +86,9 @@ define void @test5(i32 %a) nounwind {
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test5
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
if.then:
tail call void @foo() nounwind
@@ -106,9 +106,9 @@ define void @test6(i32 %a) nounwind {
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test6
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.then, label %if.end
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.then, label %if.end
if.then:
tail call void @foo() nounwind
@@ -126,9 +126,9 @@ define void @test7(i32 %a) nounwind {
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test7
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.end, label %if.the
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
if.then:
tail call void @foo() nounwind
@@ -146,9 +146,9 @@ define void @test8(i32 %a) nounwind {
br i1 %or.cond, label %if.then, label %if.end
; CHECK: @test8
-; CHECK-NEXT: %and = and i32 %a, -2013265920
-; CHECK-NEXT: %1 = icmp eq i32 %and, 0
-; CHECK-NEXT: br i1 %1, label %if.end, label %if.the
+; CHECK-NEXT: %1 = and i32 %a, -2013265920
+; CHECK-NEXT: %2 = icmp eq i32 %1, 0
+; CHECK-NEXT: br i1 %2, label %if.end, label %if.the
if.then:
tail call void @foo() nounwind