[PATCH] D39417: InstCombine: Preserve nuw when reassociating nuw ops [1/3]

Matt Arsenault via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 24 07:44:04 PDT 2019


arsenm updated this revision to Diff 206215.
arsenm added a comment.

Correct diff


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D39417/new/

https://reviews.llvm.org/D39417

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


Index: test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
===================================================================
--- test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
+++ test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll
@@ -172,7 +172,7 @@
 ; 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 @@
 ; 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 @@
 }
 
 ; 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 @@
 ; 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
Index: test/Transforms/InstCombine/reassociate-nuw.ll
===================================================================
--- test/Transforms/InstCombine/reassociate-nuw.ll
+++ test/Transforms/InstCombine/reassociate-nuw.ll
@@ -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
Index: lib/Transforms/InstCombine/InstructionCombining.cpp
===================================================================
--- lib/Transforms/InstCombine/InstructionCombining.cpp
+++ lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -223,6 +223,11 @@
   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,20 @@
           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);
+          bool IsNSW = MaintainNoSignedWrap(I, B, C);
+
+          ClearSubclassDataAfterReassociation(I);
+
+          if (IsNUW && hasNoUnsignedWrap(*Op0))
+            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;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39417.206215.patch
Type: text/x-patch
Size: 3923 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190624/2a9a2d21/attachment.bin>


More information about the llvm-commits mailing list