diff options
Diffstat (limited to 'lib/Transforms/InstCombine/InstCombineAddSub.cpp')
| -rw-r--r-- | lib/Transforms/InstCombine/InstCombineAddSub.cpp | 18 | 
1 files changed, 16 insertions, 2 deletions
| diff --git a/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/lib/Transforms/InstCombine/InstCombineAddSub.cpp index aa31e0d850dd..83054588a9aa 100644 --- a/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -926,7 +926,13 @@ Instruction *InstCombiner::foldAddWithConstant(BinaryOperator &Add) {    if (Instruction *NV = foldBinOpIntoSelectOrPhi(Add))      return NV; -  Value *X; +  Value *X, *Y; + +  // add (sub X, Y), -1 --> add (not Y), X +  if (match(Op0, m_OneUse(m_Sub(m_Value(X), m_Value(Y)))) && +      match(Op1, m_AllOnes())) +    return BinaryOperator::CreateAdd(Builder.CreateNot(Y), X); +    // zext(bool) + C -> bool ? C + 1 : C    if (match(Op0, m_ZExt(m_Value(X))) &&        X->getType()->getScalarSizeInBits() == 1) @@ -1608,6 +1614,14 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {    if (match(Op0, m_Not(m_Value(X))) && match(Op1, m_Not(m_Value(Y))))      return BinaryOperator::CreateSub(Y, X); +  // (X + -1) - Y --> ~Y + X +  if (match(Op0, m_OneUse(m_Add(m_Value(X), m_AllOnes())))) +    return BinaryOperator::CreateAdd(Builder.CreateNot(Op1), X); + +  // Y - (X + 1) --> ~X + Y +  if (match(Op1, m_OneUse(m_Add(m_Value(X), m_One())))) +    return BinaryOperator::CreateAdd(Builder.CreateNot(X), Op0); +    if (Constant *C = dyn_cast<Constant>(Op0)) {      bool IsNegate = match(C, m_ZeroInt());      Value *X; @@ -1858,7 +1872,7 @@ Instruction *InstCombiner::visitFSub(BinaryOperator &I) {    Constant *C;    if (match(Op1, m_Constant(C)) && !isa<ConstantExpr>(Op1))      return BinaryOperator::CreateFAddFMF(Op0, ConstantExpr::getFNeg(C), &I); -   +    // X - (-Y) --> X + Y    if (match(Op1, m_FNeg(m_Value(Y))))      return BinaryOperator::CreateFAddFMF(Op0, Y, &I); | 
