summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-08-22 17:11:04 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-08-22 17:11:04 +0000
commit49775e0173cb852b4f4e9e9105cddbbff4872dd3 (patch)
treea7e4c9cd7884ff3472dc12c3e0cb581873f9237c /llvm
parent19ecd635fe4fa07ca6305e7074113efab8fb08ef (diff)
downloadbcm5719-llvm-49775e0173cb852b4f4e9e9105cddbbff4872dd3.tar.gz
bcm5719-llvm-49775e0173cb852b4f4e9e9105cddbbff4872dd3.zip
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')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp18
-rw-r--r--llvm/test/Transforms/InstCombine/cast.ll12
2 files changed, 24 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index c26766a95ac..f0c96bdf768 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;
}
diff --git a/llvm/test/Transforms/InstCombine/cast.ll b/llvm/test/Transforms/InstCombine/cast.ll
index 81b0d7eff52..47f7e73f998 100644
--- a/llvm/test/Transforms/InstCombine/cast.ll
+++ b/llvm/test/Transforms/InstCombine/cast.ll
@@ -1038,3 +1038,15 @@ define i8 @test84(i32 %a) {
; CHECK: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
; CHECK: [[CST:%.*]] = trunc i32 [[SHR]] to i8
}
+
+define i8 @test85(i32 %a) {
+ %add = add nuw i32 %a, -16777216
+ %shr = lshr exact i32 %add, 23
+ %trunc = trunc i32 %shr to i8
+ ret i8 %trunc
+
+; CHECK-LABEL: @test85(
+; CHECK: [[ADD:%.*]] = add i32 %a, 2130706432
+; CHECK: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
+; CHECK: [[CST:%.*]] = trunc i32 [[SHR]] to i8
+}
OpenPOWER on IntegriCloud