summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Constants.cpp24
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp18
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.
OpenPOWER on IntegriCloud