summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp18
1 files changed, 14 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index ea7942ef9781..7a184a19d7c5 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1289,7 +1289,7 @@ static Instruction *foldAddToAshr(BinaryOperator &Add) {
// Note that, by the time we end up here, if possible, ugt has been
// canonicalized into eq.
const APInt *MaskC, *MaskCCmp;
- ICmpInst::Predicate Pred;
+ CmpPredicate Pred;
if (!match(Add.getOperand(1),
m_SExt(m_ICmp(Pred, m_And(m_Specific(X), m_APInt(MaskC)),
m_APInt(MaskCCmp)))))
@@ -1382,7 +1382,7 @@ Instruction *InstCombinerImpl::
// `select` itself may be appropriately extended, look past that.
SkipExtInMagic(Select);
- ICmpInst::Predicate Pred;
+ CmpPredicate Pred;
const APInt *Thr;
Value *SignExtendingValue, *Zero;
bool ShouldSignext;
@@ -1654,7 +1654,7 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
return replaceInstUsesWith(I, Constant::getNullValue(I.getType()));
// sext(A < B) + zext(A > B) => ucmp/scmp(A, B)
- ICmpInst::Predicate LTPred, GTPred;
+ CmpPredicate LTPred, GTPred;
if (match(&I,
m_c_Add(m_SExt(m_c_ICmp(LTPred, m_Value(A), m_Value(B))),
m_ZExt(m_c_ICmp(GTPred, m_Deferred(A), m_Deferred(B))))) &&
@@ -1841,7 +1841,7 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
// -->
// BW - ctlz(A - 1, false)
const APInt *XorC;
- ICmpInst::Predicate Pred;
+ CmpPredicate Pred;
if (match(&I,
m_c_Add(
m_ZExt(m_ICmp(Pred, m_Intrinsic<Intrinsic::ctpop>(m_Value(A)),
@@ -2280,6 +2280,16 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes()))))
return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X);
+ // if (C1 & C2) == C2 then (X & C1) - (X & C2) -> X & (C1 ^ C2)
+ Constant *C1, *C2;
+ if (match(Op0, m_And(m_Value(X), m_ImmConstant(C1))) &&
+ match(Op1, m_And(m_Specific(X), m_ImmConstant(C2)))) {
+ Value *AndC = ConstantFoldBinaryInstruction(Instruction::And, C1, C2);
+ if (C2->isElementWiseEqual(AndC))
+ return BinaryOperator::CreateAnd(
+ X, ConstantFoldBinaryInstruction(Instruction::Xor, C1, C2));
+ }
+
// Reassociate sub/add sequences to create more add instructions and
// reduce dependency chains:
// ((X - Y) + Z) - Op1 --> (X + Z) - (Y + Op1)