aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineAndOrXor.cpp')
-rw-r--r--lib/Transforms/InstCombine/InstCombineAndOrXor.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 4b1e7feef0..96ca40a3cf 100644
--- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -743,6 +743,22 @@ 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;
+ }
+ }
// From here on, we only handle:
// (icmp1 A, C1) & (icmp2 A, C2) --> something simpler.
@@ -1442,6 +1458,22 @@ 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;
+ }
+ }
+
// (icmp ult (X + CA), C1) | (icmp eq X, C2) -> (icmp ule (X + CA), C1)
// iff C2 + CA == C1.
if (LHSCC == ICmpInst::ICMP_ULT && RHSCC == ICmpInst::ICMP_EQ) {