aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-04-22 20:59:28 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-04-22 20:59:28 +0000
commitfe58d13a17a2824fe891274e1396e5fc1ca5ab38 (patch)
treeb70e49630309f2cbf60608f0ff7c0517b5efcda0 /llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
parenta32764453444da90e92ba0041f40b4d94fadf2d4 (diff)
downloadllvm-fe58d13a17a2824fe891274e1396e5fc1ca5ab38.zip
llvm-fe58d13a17a2824fe891274e1396e5fc1ca5ab38.tar.gz
llvm-fe58d13a17a2824fe891274e1396e5fc1ca5ab38.tar.bz2
[InstCombine] Clear out nsw/nuw if we modify computation in the chain
An nsw/nuw operation relies on the values feeding into it to not overflow if 'poison' is not to be produced. This means that optimizations which make modifications to the bottom of a chain (like SimplifyDemandedBits) must strip out nsw/nuw if they cannot ensure that they will be preserved. This fixes PR23309. llvm-svn: 235544
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp13
1 files changed, 10 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index cd391d0..0695ec1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -83,11 +83,18 @@ bool InstCombiner::SimplifyDemandedInstructionBits(Instruction &Inst) {
bool InstCombiner::SimplifyDemandedBits(Use &U, APInt DemandedMask,
APInt &KnownZero, APInt &KnownOne,
unsigned Depth) {
- Value *NewVal =
- SimplifyDemandedUseBits(U.get(), DemandedMask, KnownZero, KnownOne, Depth,
- dyn_cast<Instruction>(U.getUser()));
+ auto *UserI = dyn_cast<Instruction>(U.getUser());
+ Value *NewVal = SimplifyDemandedUseBits(U.get(), DemandedMask, KnownZero,
+ KnownOne, Depth, UserI);
if (!NewVal) return false;
U = NewVal;
+
+ // Shrinking a constant might cause a nsw/nuw violation to occur in
+ // instructions which are themselves demanded.
+ if (auto *UserOBO = dyn_cast<OverflowingBinaryOperator>(UserI)) {
+ cast<BinaryOperator>(UserOBO)->setHasNoSignedWrap(false);
+ cast<BinaryOperator>(UserOBO)->setHasNoUnsignedWrap(false);
+ }
return true;
}