diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-10-13 22:37:51 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-10-13 22:37:51 +0000 |
commit | db0773089f8a1944fa3c73e5be78e88b258318ca (patch) | |
tree | 7af69fa517a84411f253ca47d27b8377474d2df1 /llvm/lib/Transforms | |
parent | b75d8f300cbfba07aad4442a8ef600194e5a8a42 (diff) | |
download | bcm5719-llvm-db0773089f8a1944fa3c73e5be78e88b258318ca.tar.gz bcm5719-llvm-db0773089f8a1944fa3c73e5be78e88b258318ca.zip |
InstCombine: Fix miscompile in X % -Y -> X % Y transform
We assumed that negation operations of the form (0 - %Z) resulted in a
negative number. This isn't true if %Z was originally negative.
Substituting the negative number into the remainder operation may result
in undefined behavior because the dividend might be INT_MIN.
This fixes PR21256.
llvm-svn: 219639
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp index 846a3640930..840a25fb813 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -1324,15 +1324,15 @@ Instruction *InstCombiner::visitSRem(BinaryOperator &I) { if (Instruction *Common = commonIRemTransforms(I)) return Common; - if (Value *RHSNeg = dyn_castNegVal(Op1)) - if (!isa<Constant>(RHSNeg) || - (isa<ConstantInt>(RHSNeg) && - cast<ConstantInt>(RHSNeg)->getValue().isStrictlyPositive())) { - // X % -Y -> X % Y + { + const APInt *Y; + // X % -Y -> X % Y + if (match(Op1, m_APInt(Y)) && Y->isNegative() && !Y->isMinSignedValue()) { Worklist.AddValue(I.getOperand(1)); - I.setOperand(1, RHSNeg); + I.setOperand(1, ConstantInt::get(I.getType(), -*Y)); return &I; } + } // If the sign bits of both operands are zero (i.e. we can prove they are // unsigned inputs), turn this into a urem. |