[llvm] r216261 - InstCombine: Don't unconditionally preserve 'nsw' when shrinking constants
David Majnemer
david.majnemer at gmail.com
Fri Aug 22 00:56:33 PDT 2014
Author: majnemer
Date: Fri Aug 22 02:56:32 2014
New Revision: 216261
URL: http://llvm.org/viewvc/llvm-project?rev=216261&view=rev
Log:
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.
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/trunk/test/Transforms/InstCombine/cast.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp?rev=216261&r1=216260&r2=216261&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp Fri Aug 22 02:56:32 2014
@@ -43,6 +43,14 @@ static bool ShrinkDemandedConstant(Instr
// 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;
}
Modified: llvm/trunk/test/Transforms/InstCombine/cast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/cast.ll?rev=216261&r1=216260&r2=216261&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/cast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/cast.ll Fri Aug 22 02:56:32 2014
@@ -1022,7 +1022,19 @@ define i64 @test83(i16 %a, i64 %k) {
ret i64 %sh_prom1
; CHECK-LABEL: @test83(
-; CHECK: %sub = add nsw i64 %k, 4294967295
+; CHECK: %sub = add i64 %k, 4294967295
; CHECK: %sh_prom = trunc i64 %sub to i32
; CHECK: %shl = shl i32 %conv, %sh_prom
}
+
+define i8 @test84(i32 %a) {
+ %add = add nsw i32 %a, -16777216
+ %shr = lshr exact i32 %add, 23
+ %trunc = trunc i32 %shr to i8
+ ret i8 %trunc
+
+; CHECK-LABEL: @test84(
+; CHECK: [[ADD:%.*]] = add i32 %a, 2130706432
+; CHECK: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
+; CHECK: [[CST:%.*]] = trunc i32 [[SHR]] to i8
+}
More information about the llvm-commits
mailing list