diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/IR/Constants.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp | 18 | 
2 files changed, 34 insertions, 8 deletions
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp index b5df4ea8af6..7ea5cb8b167 100644 --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -150,6 +150,30 @@ bool Constant::isOneValue() const {    return false;  } +bool Constant::isNotOneValue() const { +  // Check for 1 integers +  if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) +    return !CI->isOneValue(); + +  // Check for FP which are bitcasted from 1 integers +  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this)) +    return !CFP->getValueAPF().bitcastToAPInt().isOneValue(); + +  // Check that vectors don't contain 1 +  if (this->getType()->isVectorTy()) { +    unsigned NumElts = this->getType()->getVectorNumElements(); +    for (unsigned i = 0; i != NumElts; ++i) { +      Constant *Elt = this->getAggregateElement(i); +      if (!Elt || !Elt->isNotOneValue()) +        return false; +    } +    return true; +  } + +  // It *may* contain 1, we can't tell. +  return false; +} +  bool Constant::isMinSignedValue() const {    // Check for INT_MIN integers    if (const ConstantInt *CI = dyn_cast<ConstantInt>(this)) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp index 8bc34825f8a..5b71f9d9c2e 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1896,14 +1896,16 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {                                    Builder.CreateNot(Y, Y->getName() + ".not"));      // 0 - (X sdiv C)  -> (X sdiv -C)  provided the negation doesn't overflow. -    // TODO: This could be extended to match arbitrary vector constants. -    const APInt *DivC; -    if (match(Op0, m_Zero()) && match(Op1, m_SDiv(m_Value(X), m_APInt(DivC))) && -        !DivC->isMinSignedValue() && *DivC != 1) { -      Constant *NegDivC = ConstantInt::get(I.getType(), -(*DivC)); -      Instruction *BO = BinaryOperator::CreateSDiv(X, NegDivC); -      BO->setIsExact(cast<BinaryOperator>(Op1)->isExact()); -      return BO; +    if (match(Op0, m_Zero())) { +      Constant *Op11C; +      if (match(Op1, m_SDiv(m_Value(X), m_Constant(Op11C))) && +          !Op11C->containsUndefElement() && Op11C->isNotMinSignedValue() && +          Op11C->isNotOneValue()) { +        Instruction *BO = +            BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(Op11C)); +        BO->setIsExact(cast<BinaryOperator>(Op1)->isExact()); +        return BO; +      }      }      // 0 - (X << Y)  -> (-X << Y)   when X is freely negatable.  | 

