[PATCH] D62418: [MustExecute] Improve MustExecute to correctly handle loop nest

Whitney via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri May 24 12:32:56 PDT 2019


Whitney created this revision.
Whitney added reviewers: kbarton, jdoerfert, Meinersbur, hfinkel, fhahn.
Whitney added a project: LLVM.
Herald added subscribers: llvm-commits, jsji, hiraditya.

  for.outer:
    br for.inner
  for.inner:
    LI <loop invariant load instruction>
  for.inner.latch:
    br for.inner, for.outer.latch
  for.outer.latch:
    br for.outer, for.outer.exit

LI is a loop invariant load instruction that post dominate for.outer, so LI should be able to move out of the loop nest. However, there is a bug in allLoopPathsLeadToBlock().

Current algorithm of allLoopPathsLeadToBlock()

1. get all the transitive predecessors of the basic block LI belongs to (for.inner) ==> for.outer, for.inner.latch
2. if any successors of any of the predecessors are not for.inner or for.inner's predecessors, then return false
3. return true

Although for.inner.latch is for.inner's predecessor, but for.inner dominates for.inner.latch, which means if for.inner.latch is ever executed, for.inner should be as well. It should not return false for cases like this.


Repository:
  rL LLVM

https://reviews.llvm.org/D62418

Files:
  llvm/lib/Analysis/MustExecute.cpp
  llvm/test/Analysis/MustExecute/loop-header.ll


Index: llvm/test/Analysis/MustExecute/loop-header.ll
===================================================================
--- llvm/test/Analysis/MustExecute/loop-header.ll
+++ llvm/test/Analysis/MustExecute/loop-header.ll
@@ -83,17 +83,15 @@
   ret i1 false
 }
 
-; FIXME: everything in inner loop header should be must execute
-; for outer as well
 define i1 @nested_no_throw(i32* noalias %p, i32 %high) {
 ; CHECK-LABEL: @nested_no_throw
 ; CHECK-LABEL: loop:                                             ; preds = %next
 ; CHECK:         %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ]	; (mustexec in: loop)
 ; CHECK:         br label %inner_loop	; (mustexec in: loop)
 ; CHECK-LABEL: inner_loop:
-; CHECK:         %v = load i32, i32* %p	; (mustexec in: inner_loop)
-; CHECK:         %inner.test = icmp eq i32 %v, 0	; (mustexec in: inner_loop)
-; CHECK:         br i1 %inner.test, label %inner_loop, label %next	; (mustexec in: inner_loop)
+; CHECK:         %v = load i32, i32* %p	; (mustexec in 2 loops: inner_loop, loop)
+; CHECK:         %inner.test = icmp eq i32 %v, 0	; (mustexec in 2 loops: inner_loop, loop)
+; CHECK:         br i1 %inner.test, label %inner_loop, label %next	; (mustexec in 2 loops: inner_loop, loop)
 ; CHECK-LABEL: next:
 ; CHECK:         %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop)
 ; CHECK:         %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop)
Index: llvm/lib/Analysis/MustExecute.cpp
===================================================================
--- llvm/lib/Analysis/MustExecute.cpp
+++ llvm/lib/Analysis/MustExecute.cpp
@@ -203,6 +203,11 @@
     // Predecessor block may throw, so it has a side exit.
     if (blockMayThrow(Pred))
       return false;
+
+    // BB dominates Pred, so if Pred runs, BB must run.
+    if (DT->dominates(BB, Pred))
+      continue;
+
     for (auto *Succ : successors(Pred))
       if (CheckedSuccessors.insert(Succ).second &&
           Succ != BB && !Predecessors.count(Succ))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62418.201311.patch
Type: text/x-patch
Size: 1974 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190524/b0f6d2cc/attachment.bin>


More information about the llvm-commits mailing list