]> granicus.if.org Git - llvm/commitdiff
[LoopUnroll] Properly update loop structure in case of successful peeling.
authorDavide Italiano <davide@freebsd.org>
Mon, 28 Aug 2017 20:29:33 +0000 (20:29 +0000)
committerDavide Italiano <davide@freebsd.org>
Mon, 28 Aug 2017 20:29:33 +0000 (20:29 +0000)
When peeling kicks in, it updates the loop preheader.
Later, a successful full unroll of the loop needs to update a PHI
which i-th argument comes from the loop preheader, so it'd better look
at the correct block. Fixes PR33437.

Differential Revision:  https://reviews.llvm.org/D37153

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311922 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/LoopUnroll.cpp
test/Transforms/LoopUnroll/pr33437.ll [new file with mode: 0644]

index 835f43993320b7b54153d3760ad69742736abb7e..7759ac74d5600dc5fcd8a6819821ac045aee028e 100644 (file)
@@ -396,8 +396,19 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
          "Did not expect runtime trip-count unrolling "
          "and peeling for the same loop");
 
-  if (PeelCount)
-    peelLoop(L, PeelCount, LI, SE, DT, AC, PreserveLCSSA);
+  if (PeelCount) {
+    bool Peeled = peelLoop(L, PeelCount, LI, SE, DT, AC, PreserveLCSSA);
+
+    // Successful peeling may result in a change in the loop preheader/trip
+    // counts. If we later unroll the loop, we want these to be updated.
+    if (Peeled) {
+      BasicBlock *ExitingBlock = L->getExitingBlock();
+      assert(ExitingBlock && "Loop without exiting block?");
+      Preheader = L->getLoopPreheader();
+      TripCount = SE->getSmallConstantTripCount(L, ExitingBlock);
+      TripMultiple = SE->getSmallConstantTripMultiple(L, ExitingBlock);
+    }
+  }
 
   // Loops containing convergent instructions must have a count that divides
   // their TripMultiple.
diff --git a/test/Transforms/LoopUnroll/pr33437.ll b/test/Transforms/LoopUnroll/pr33437.ll
new file mode 100644 (file)
index 0000000..58fa91f
--- /dev/null
@@ -0,0 +1,30 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -loop-unroll %s -S | FileCheck %s
+
+declare zeroext i8 @patatino()
+
+define fastcc void @tinky() {
+; CHECK-LABEL: @tinky(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_COND93:%.*]]
+; CHECK:       for.cond93:
+; CHECK-NEXT:    br label [[FOR_BODY198:%.*]]
+; CHECK:       for.body198:
+; CHECK-NEXT:    [[CALL593:%.*]] = tail call zeroext i8 @patatino()
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.cond93
+
+for.cond93.loopexit:
+  ret void
+
+for.cond93:
+  br label %for.body198
+
+for.body198:
+  %l_249.12 = phi i8 [ undef, %for.cond93 ], [ %call593, %for.body198 ]
+  %l_522.01 = phi i32 [ 0, %for.cond93 ], [ 1, %for.body198 ]
+  %call593 = tail call zeroext i8 @patatino()
+  br i1 false, label %for.body198, label %for.cond93.loopexit
+}