diff options
-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 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 |