summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2019-04-09 14:09:06 +0000
committerSanjay Patel <spatel@rotateright.com>2019-04-09 14:09:06 +0000
commitf62dcea7ed69df95b037712b1860bb99c553c808 (patch)
tree594186b06c3428a0e9c117ecdbba11e3e6fde357 /llvm/lib
parentaf5834596bf885a1e4f71b79c222ffdb8a640656 (diff)
downloadbcm5719-llvm-f62dcea7ed69df95b037712b1860bb99c553c808.tar.gz
bcm5719-llvm-f62dcea7ed69df95b037712b1860bb99c553c808.zip
[InstCombine] prevent possible miscompile with negate+sdiv of vector op
// 0 - (X sdiv C) -> (X sdiv -C) provided the negation doesn't overflow. This fold has been around for many years and nobody noticed the potential vector miscompile from overflow until recently... So it seems unlikely that there's much demand for a vector sdiv optimization on arbitrary vector constants, so just limit the matching to splat constants to avoid the possible bug. Differential Revision: https://reviews.llvm.org/D60426 llvm-svn: 358005
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp9
1 files changed, 6 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index d5a36e025f6..19766d502c4 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -1692,9 +1692,12 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
Builder.CreateNot(Y, Y->getName() + ".not"));
// 0 - (X sdiv C) -> (X sdiv -C) provided the negation doesn't overflow.
- if (match(Op1, m_SDiv(m_Value(X), m_Constant(C))) && match(Op0, m_Zero()) &&
- C->isNotMinSignedValue() && !C->isOneValue()) {
- auto *BO = BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(C));
+ // 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;
}
OpenPOWER on IntegriCloud