From 7f0170c1975fe55c58f6f2a968e1fc2248732fbe Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sun, 14 Aug 2011 03:41:33 +0000 Subject: [PATCH] Don't attempt to add 'nsw' when intermediate instructions had no such guarantee. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137572 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../InstCombine/InstructionCombining.cpp | 11 ++++--- test/Transforms/InstCombine/nsw.ll | 30 ++++++++++++++++++- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 85091afaf26..41666361141 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -146,7 +146,6 @@ static bool MaintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) { return !Overflow; } - /// SimplifyAssociativeOrCommutative - This performs a few simplifications for /// operators which are associative or commutative: // @@ -197,7 +196,10 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) { I.setOperand(1, V); // Conservatively clear the optional flags, since they may not be // preserved by the reassociation. - if (MaintainNoSignedWrap(I, B, C)) { + if (MaintainNoSignedWrap(I, B, C) && + (!Op0 || (isa(Op0) && Op0->hasNoSignedWrap()))) { + // Note: this is only valid because SimplifyBinOp doesn't look at + // the operands to Op0. I.clearSubclassOptionalData(); I.setHasNoSignedWrap(true); } else { @@ -292,10 +294,11 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) { I.setOperand(1, Folded); // Conservatively clear the optional flags, since they may not be // preserved by the reassociation. - if (MaintainNoSignedWrap(I, C1, C2)) { + if (MaintainNoSignedWrap(I, C1, C2) && Op0->hasNoSignedWrap() && + Op1->hasNoSignedWrap()) { + New->setHasNoSignedWrap(true); I.clearSubclassOptionalData(); I.setHasNoSignedWrap(true); - New->setHasNoSignedWrap(true); } else { I.clearSubclassOptionalData(); } diff --git a/test/Transforms/InstCombine/nsw.ll b/test/Transforms/InstCombine/nsw.ll index 698296384ae..0e715075fc3 100644 --- a/test/Transforms/InstCombine/nsw.ll +++ b/test/Transforms/InstCombine/nsw.ll @@ -46,10 +46,38 @@ define i32 @preserve1(i32 %x) nounwind { ret i32 %add3 } +; CHECK: @preserve2 +; CHECK: add nsw i8 %A, %B +; CHECK: add nsw i8 +define i8 @preserve2(i8 %A, i8 %B) nounwind { + %x = add nsw i8 %A, 10 + %y = add nsw i8 %B, 10 + %add = add nsw i8 %x, %y + ret i8 %add +} + ; CHECK: @nopreserve1 ; CHECK: add i8 %x, -126 define i8 @nopreserve1(i8 %x) nounwind { %add = add nsw i8 %x, 127 %add3 = add nsw i8 %add, 3 ret i8 %add3 -} \ No newline at end of file +} + +; CHECK: @nopreserve2 +; CHECK: add i8 %x, 3 +define i8 @nopreserve2(i8 %x) nounwind { + %add = add i8 %x, 1 + %add3 = add nsw i8 %add, 2 + ret i8 %add3 +} + +; CHECK: @nopreserve3 +; CHECK: add i8 %A, %B +; CHECK: add i8 +define i8 @nopreserve3(i8 %A, i8 %B) nounwind { + %x = add i8 %A, 10 + %y = add i8 %B, 10 + %add = add nsw i8 %x, %y + ret i8 %add +}