[llvm] r364233 - InstCombine: Preserve nuw when reassociating nuw ops [1/3]

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 24 14:36:59 PDT 2019


Author: arsenm
Date: Mon Jun 24 14:36:59 2019
New Revision: 364233

URL: http://llvm.org/viewvc/llvm-project?rev=364233&view=rev
Log:
InstCombine: Preserve nuw when reassociating nuw ops [1/3]

Alive says this is OK.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll
    llvm/trunk/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=364233&r1=364232&r2=364233&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon Jun 24 14:36:59 2019
@@ -223,6 +223,11 @@ static bool MaintainNoSignedWrap(BinaryO
   return !Overflow;
 }
 
+static bool hasNoUnsignedWrap(BinaryOperator &I) {
+  OverflowingBinaryOperator *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
+  return OBO && OBO->hasNoUnsignedWrap();
+}
+
 /// Conservatively clears subclassOptionalData after a reassociation or
 /// commutation. We preserve fast-math flags when applicable as they can be
 /// preserved.
@@ -329,14 +334,19 @@ bool InstCombiner::SimplifyAssociativeOr
           I.setOperand(1, V);
           // Conservatively clear the optional flags, since they may not be
           // preserved by the reassociation.
-          if (MaintainNoSignedWrap(I, B, C) &&
+          bool IsNUW = hasNoUnsignedWrap(I) && hasNoUnsignedWrap(*Op0);
+          bool IsNSW = MaintainNoSignedWrap(I, B, C);
+
+          ClearSubclassDataAfterReassociation(I);
+
+          if (IsNUW)
+            I.setHasNoUnsignedWrap(true);
+
+          if (IsNSW &&
               (!Op0 || (isa<BinaryOperator>(Op0) && Op0->hasNoSignedWrap()))) {
             // Note: this is only valid because SimplifyBinOp doesn't look at
             // the operands to Op0.
-            I.clearSubclassOptionalData();
             I.setHasNoSignedWrap(true);
-          } else {
-            ClearSubclassDataAfterReassociation(I);
           }
 
           Changed = true;

Modified: llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll?rev=364233&r1=364232&r2=364233&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/reassociate-nuw.ll Mon Jun 24 14:36:59 2019
@@ -3,7 +3,7 @@
 
 define i32 @reassoc_add_nuw(i32 %x) {
 ; CHECK-LABEL: @reassoc_add_nuw(
-; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[X:%.*]], 68
+; CHECK-NEXT:    [[ADD1:%.*]] = add nuw i32 [[X:%.*]], 68
 ; CHECK-NEXT:    ret i32 [[ADD1]]
 ;
   %add0 = add nuw i32 %x, 4

Modified: llvm/trunk/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll?rev=364233&r1=364232&r2=364233&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll (original)
+++ llvm/trunk/test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll Mon Jun 24 14:36:59 2019
@@ -172,7 +172,7 @@ define void @test3(i64 %trip, i64 %add)
 ; PROLOG:  loop_exiting_bb1.7:
 ; PROLOG-NEXT:     switch i64 %sum.next.6, label %loop_latch.7
 ; PROLOG:  loop_latch.7:
-; PROLOG-NEXT:     %iv_next.7 = add nsw i64 %iv, 8
+; PROLOG-NEXT:     %iv_next.7 = add nuw nsw i64 %iv, 8
 ; PROLOG-NEXT:     %sum.next.7 = add i64 %sum.next.6, %add
 ; PROLOG-NEXT:     %cmp.7 = icmp eq i64 %iv_next.7, %trip
 ; PROLOG-NEXT:     br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header
@@ -426,7 +426,7 @@ define i64 @test5(i64 %trip, i64 %add, i
 ; PROLOG-NEXT:      %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ]
 ; PROLOG-NEXT:      ret i64 %result
 ; PROLOG:   loop_latch.7:
-; PROLOG:      %iv_next.7 = add nsw i64 %iv, 8
+; PROLOG:      %iv_next.7 = add nuw nsw i64 %iv, 8
 entry:
   br label %loop_header
 
@@ -560,7 +560,7 @@ loopexit1:
 }
 
 ; Nested loop and inner loop is unrolled
-; FIXME: we cannot unroll with epilog remainder currently, because 
+; FIXME: we cannot unroll with epilog remainder currently, because
 ; the outer loop does not contain the epilog preheader and epilog exit (while
 ; infact it should). This causes us to choke up on LCSSA form being incorrect in
 ; outer loop. However, the exit block where LCSSA fails, is infact still within
@@ -578,7 +578,7 @@ define void @test8() {
 ; PROLOG:      %lcmp.mod = icmp eq i64
 ; PROLOG-NEXT: br i1 %lcmp.mod, label %innerH.prol.loopexit, label %innerH.prol.preheader
 ; PROLOG: latch.6:
-; PROLOG-NEXT: %tmp4.7 = add nsw i64 %tmp3, 8
+; PROLOG-NEXT: %tmp4.7 = add nuw nsw i64 %tmp3, 8
 ; PROLOG-NEXT: br i1 false, label %outerloop.loopexit.loopexit, label %latch.7
 ; PROLOG: latch.7
 ; PROLOG-NEXT: %tmp6.7 = icmp ult i64 %tmp4.7, 100




More information about the llvm-commits mailing list