diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-08-22 17:11:04 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-08-22 17:11:04 +0000 |
commit | 49775e0173cb852b4f4e9e9105cddbbff4872dd3 (patch) | |
tree | a7e4c9cd7884ff3472dc12c3e0cb581873f9237c /llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | |
parent | 19ecd635fe4fa07ca6305e7074113efab8fb08ef (diff) | |
download | llvm-49775e0173cb852b4f4e9e9105cddbbff4872dd3.zip llvm-49775e0173cb852b4f4e9e9105cddbbff4872dd3.tar.gz llvm-49775e0173cb852b4f4e9e9105cddbbff4872dd3.tar.bz2 |
InstCombine: Don't unconditionally preserve 'nuw' when shrinking constants
Consider:
%add = add nuw i32 %a, -16777216
%and = and i32 %add, 255
Regardless of whether or not we demand the sign bit of %add, we cannot
replace -16777216 with 2130706432 without also removing 'nuw' from the
instruction.
llvm-svn: 216273
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index c26766a..f0c96bd 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -44,12 +44,18 @@ static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo, Demanded &= OpC->getValue(); I->setOperand(OpNo, ConstantInt::get(OpC->getType(), Demanded)); - // If 'nsw' is set and the constant is negative, removing *any* bits from the - // constant could make overflow occur. Remove 'nsw' from the instruction in - // this case. - if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I)) - if (OBO->hasNoSignedWrap() && OpC->getValue().isNegative()) - cast<BinaryOperator>(OBO)->setHasNoSignedWrap(false); + // If either 'nsw' or 'nuw' is set and the constant is negative, + // removing *any* bits from the constant could make overflow occur. + // Remove 'nsw' and 'nuw' from the instruction in this case. + if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I)) { + assert(OBO->getOpcode() == Instruction::Add); + if (OBO->hasNoSignedWrap() || OBO->hasNoUnsignedWrap()) { + if (OpC->getValue().isNegative()) { + cast<BinaryOperator>(OBO)->setHasNoSignedWrap(false); + cast<BinaryOperator>(OBO)->setHasNoUnsignedWrap(false); + } + } + } return true; } |