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
This commit is contained in:
parent
4882e488f7
commit
6609f741b9
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue