[PATCH] D65292: [Loop Peeling] Fix idom detection algorithm

Serguei Katkov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 25 12:32:48 PDT 2019


This revision was not accepted when it landed; it landed in state "Needs Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL367044: [Loop Peeling] Fix idom detection algorithm. (authored by skatkov, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D65292?vs=211786&id=211801#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D65292

Files:
  llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp
  llvm/trunk/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll


Index: llvm/trunk/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
===================================================================
--- llvm/trunk/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
+++ llvm/trunk/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
@@ -0,0 +1,46 @@
+; REQUIRES: asserts
+; RUN: opt < %s -S -debug-only=loop-unroll -loop-unroll -unroll-runtime -unroll-peel-multi-deopt-exit 2>&1 | FileCheck %s
+; RUN: opt < %s -S -debug-only=loop-unroll -unroll-peel-multi-deopt-exit -passes='require<profile-summary>,function(require<opt-remark-emit>,unroll)' 2>&1 | FileCheck %s
+
+; Regression test for setting the correct idom for exit blocks.
+
+; CHECK: Loop Unroll: F[basic]
+; CHECK: PEELING loop %for.body with iteration count 1!
+
+define i32 @basic(i32* %p, i32 %k, i1 %c1, i1 %c2) #0 !prof !3 {
+entry:
+  br label %for.body
+
+for.body:
+  %i.05 = phi i32 [ 0, %entry ], [ %inc, %latch ]
+  %p.addr.04 = phi i32* [ %p, %entry ], [ %incdec.ptr, %latch ]
+  %incdec.ptr = getelementptr inbounds i32, i32* %p.addr.04, i32 1
+  store i32 %i.05, i32* %p.addr.04, align 4
+  %inc = add nsw i32 %i.05, 1
+  %cmp = icmp slt i32 %inc, %k
+  br i1 %c1, label %left, label %right
+
+left:
+  br label %latch
+
+right:
+  br i1 %c1, label %latch, label %side_exit, !prof !2
+
+latch:
+  br i1 %cmp, label %for.body, label %for.end, !prof !1
+
+for.end:
+  ret i32 %inc
+
+side_exit:
+  %rval = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %inc) ]
+  ret i32 %rval
+}
+
+declare i32 @llvm.experimental.deoptimize.i32(...)
+
+attributes #0 = { nounwind }
+
+!1 = !{!"branch_weights", i32 1, i32 1}
+!2 = !{!"branch_weights", i32 1, i32 0}
+!3 = !{!"function_entry_count", i64 1}
Index: llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp
===================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp
+++ llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp
@@ -575,11 +575,30 @@
 
   DenseMap<BasicBlock *, BasicBlock *> ExitIDom;
   if (DT) {
+    // We'd like to determine the idom of exit block after peeling one
+    // iteration.
+    // Let Exit is exit block.
+    // Let ExitingSet - is a set of predecessors of Exit block. They are exiting
+    // blocks.
+    // Let Latch' and ExitingSet' are copies after a peeling.
+    // We'd like to find an idom'(Exit) - idom of Exit after peeling.
+    // It is an evident that idom'(Exit) will be the nearest common dominator
+    // of ExitingSet and ExitingSet'.
+    // idom(Exit) is a nearest common dominator of ExitingSet.
+    // idom(Exit)' is a nearest common dominator of ExitingSet'.
+    // Taking into account that we have a single Latch, Latch' will dominate
+    // Header and idom(Exit).
+    // So the idom'(Exit) is nearest common dominator of idom(Exit)' and Latch'.
+    // All these basic blocks are in the same loop, so what we find is
+    // (nearest common dominator of idom(Exit) and Latch)'.
+    // In the loop below we remember nearest common dominator of idom(Exit) and
+    // Latch to update idom of Exit later.
     assert(L->hasDedicatedExits() && "No dedicated exits?");
     for (auto Edge : ExitEdges) {
       if (ExitIDom.count(Edge.second))
         continue;
-      BasicBlock *BB = DT->getNode(Edge.second)->getIDom()->getBlock();
+      BasicBlock *BB = DT->findNearestCommonDominator(
+          DT->getNode(Edge.second)->getIDom()->getBlock(), Latch);
       assert(L->contains(BB) && "IDom is not in a loop");
       ExitIDom[Edge.second] = BB;
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D65292.211801.patch
Type: text/x-patch
Size: 3564 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190725/a0dbfc65/attachment.bin>


More information about the llvm-commits mailing list