aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-08-22 07:56:32 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-08-22 07:56:32 +0000
commit42b83a5e3643c049eb4f89e9ca07de245d2979ea (patch)
tree342f3edb130a939a4ffcf163bc8e970cec86a362 /llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
parent987f1864caeb3b685e03d78c7316b97c506b649f (diff)
downloadllvm-42b83a5e3643c049eb4f89e9ca07de245d2979ea.zip
llvm-42b83a5e3643c049eb4f89e9ca07de245d2979ea.tar.gz
llvm-42b83a5e3643c049eb4f89e9ca07de245d2979ea.tar.bz2
InstCombine: Don't unconditionally preserve 'nsw' when shrinking constants
Consider: %add = add nsw 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 'nsw' from the instruction. This fixes PR20377. llvm-svn: 216261
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 1b42d3d..c26766a 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -43,6 +43,14 @@ static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo,
// This instruction is producing bits that are not demanded. Shrink the RHS.
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);
+
return true;
}