diff options
author | Benjamin Kramer <benny.kra@googlemail.com> | 2012-01-08 21:12:51 +0000 |
---|---|---|
committer | Benjamin Kramer <benny.kra@googlemail.com> | 2012-01-08 21:12:51 +0000 |
commit | d4242d8ab11b0da74867299cec7c2f6354c037dd (patch) | |
tree | 19ea87c88e227555c78e1522905c011730d6ed68 | |
parent | 79aa048d2102a7d4c8abbba82b4b8a41dbc32214 (diff) | |
download | llvm-d4242d8ab11b0da74867299cec7c2f6354c037dd.tar.gz llvm-d4242d8ab11b0da74867299cec7c2f6354c037dd.tar.bz2 llvm-d4242d8ab11b0da74867299cec7c2f6354c037dd.tar.xz |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147753 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 48 | ||||
-rw-r--r-- | test/Transforms/InstCombine/sign-test-and-or.ll | 24 |
2 files changed, 35 insertions, 37 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 96ca40a3cf..b4d3e625ae 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 2a5f772506..3f2141d7a9 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 |