summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2012-01-08 21:12:51 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2012-01-08 21:12:51 +0000
commit6609f741b9b02dd169cc2625b5100fce5336f5f9 (patch)
treed5a05eafc90fce0accb133d6806bc2237f9a408a
parent4882e488f794db0426b648dc0f0d5bb1046f11af (diff)
downloadbcm5719-llvm-6609f741b9b02dd169cc2625b5100fce5336f5f9.tar.gz
bcm5719-llvm-6609f741b9b02dd169cc2625b5100fce5336f5f9.zip
Tweak my last commit to be less conservative about uses.
We still save an instruction when just the "and" part is replaced. Also change the code to match comments more closely. llvm-svn: 147753
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp48
-rw-r--r--llvm/test/Transforms/InstCombine/sign-test-and-or.ll24
2 files changed, 35 insertions, 37 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 96ca40a3cf9..b4d3e625ae0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/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/llvm/test/Transforms/InstCombine/sign-test-and-or.ll b/llvm/test/Transforms/InstCombine/sign-test-and-or.ll
index 2a5f7725066..3f2141d7a9f 100644
--- a/llvm/test/Transforms/InstCombine/sign-test-and-or.ll
+++ b/llvm/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
OpenPOWER on IntegriCloud