diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2019-04-09 14:09:06 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2019-04-09 14:09:06 +0000 |
| commit | f62dcea7ed69df95b037712b1860bb99c553c808 (patch) | |
| tree | 594186b06c3428a0e9c117ecdbba11e3e6fde357 /llvm/lib | |
| parent | af5834596bf885a1e4f71b79c222ffdb8a640656 (diff) | |
| download | bcm5719-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.cpp | 9 |
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; } |

