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. |