[llvm] c7b25e4 - [LoopDeletion] Use max trip count to break backedge in addition to exact one

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 27 14:24:40 PDT 2021


Author: Philip Reames
Date: 2021-08-27T14:19:44-07:00
New Revision: c7b25e4359962f69890345aaf1b3aa4e440fbda7

URL: https://github.com/llvm/llvm-project/commit/c7b25e4359962f69890345aaf1b3aa4e440fbda7
DIFF: https://github.com/llvm/llvm-project/commit/c7b25e4359962f69890345aaf1b3aa4e440fbda7.diff

LOG: [LoopDeletion] Use max trip count to break backedge in addition to exact one

We'd added support a while back from breaking the backedge if SCEV can prove the trip count is zero. However, we used the exact trip count which requires *all* exits be analyzeable. I noticed while writing test cases for another patch that this disallows cases where one exit is provably taken paired with another which is unknown. This patch adds the upper bound case.

We could use a symbolic max trip count here instead, but we use an isKnownNonZero filter (presumably for compile time?) for the first-iteration reasoning. I decided this was a more obvious incremental step, and we could go back and untangle the schemes separately.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/LoopDeletion.cpp
    llvm/test/Transforms/LoopDeletion/switch.ll
    llvm/test/Transforms/LoopDeletion/zero-btc.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
index f7e8442fae816..dd1fa1d081f82 100644
--- a/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopDeletion.cpp
@@ -393,11 +393,16 @@ breakBackedgeIfNotTaken(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
   if (!L->getLoopLatch())
     return LoopDeletionResult::Unmodified;
 
-  auto *BTC = SE.getBackedgeTakenCount(L);
-  if (!isa<SCEVCouldNotCompute>(BTC) && SE.isKnownNonZero(BTC))
-    return LoopDeletionResult::Unmodified;
-  if (!BTC->isZero() && !canProveExitOnFirstIteration(L, DT, LI))
-    return LoopDeletionResult::Unmodified;
+  auto *BTCMax = SE.getConstantMaxBackedgeTakenCount(L);
+  if (!BTCMax->isZero()) {
+    auto *BTC = SE.getBackedgeTakenCount(L);
+    if (!BTC->isZero()) {
+      if (!isa<SCEVCouldNotCompute>(BTC) && SE.isKnownNonZero(BTC))
+        return LoopDeletionResult::Unmodified;
+      if (!canProveExitOnFirstIteration(L, DT, LI))
+        return LoopDeletionResult::Unmodified;
+    }
+  }
 
   breakLoopBackedge(L, DT, SE, LI, MSSA);
   return LoopDeletionResult::Deleted;

diff  --git a/llvm/test/Transforms/LoopDeletion/switch.ll b/llvm/test/Transforms/LoopDeletion/switch.ll
index 571e31dddfba1..c8bddd52ae1cc 100644
--- a/llvm/test/Transforms/LoopDeletion/switch.ll
+++ b/llvm/test/Transforms/LoopDeletion/switch.ll
@@ -41,3 +41,38 @@ cleanup1169:
 unreachable:
   unreachable
 }
+
+define void @func_2() {
+; CHECK-LABEL: @func_2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LBL_2368:%.*]]
+; CHECK:       lbl_2368:
+; CHECK-NEXT:    br i1 false, label [[CLEANUP967:%.*]], label [[UNREACHABLE:%.*]]
+; CHECK:       cleanup967:
+; CHECK-NEXT:    switch i32 undef, label [[CLEANUP1169:%.*]] [
+; CHECK-NEXT:    i32 20, label [[CLEANUP967_LBL_2368_CRIT_EDGE:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       cleanup967.lbl_2368_crit_edge:
+; CHECK-NEXT:    unreachable
+; CHECK:       cleanup1169:
+; CHECK-NEXT:    ret void
+; CHECK:       unreachable:
+; CHECK-NEXT:    unreachable
+;
+entry:
+  br label %lbl_2368
+
+lbl_2368:
+  br i1 false, label %cleanup967, label %unreachable
+
+cleanup967:
+  switch i32 undef, label %cleanup1169 [
+  i32 20, label %lbl_2368
+  ]
+
+cleanup1169:
+  ret void
+
+unreachable:
+  unreachable
+}

diff  --git a/llvm/test/Transforms/LoopDeletion/zero-btc.ll b/llvm/test/Transforms/LoopDeletion/zero-btc.ll
index 161bb39ac1f3d..7b305d2cbbc59 100644
--- a/llvm/test/Transforms/LoopDeletion/zero-btc.ll
+++ b/llvm/test/Transforms/LoopDeletion/zero-btc.ll
@@ -239,6 +239,42 @@ exit2:
   ret void
 }
 
+declare i1 @unknown()
+
+; We can't compute an exit count for the latch, but we know the upper
+; bound on the trip count is zero anyways.
+define void @test_dead_latch1() {
+; CHECK-LABEL: @test_dead_latch1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    store i32 0, i32* @G, align 4
+; CHECK-NEXT:    br i1 false, label [[LATCH:%.*]], label [[EXIT1:%.*]]
+; CHECK:       latch:
+; CHECK-NEXT:    [[LATCHCOND:%.*]] = call i1 @unknown()
+; CHECK-NEXT:    br label [[EXIT2:%.*]]
+; CHECK:       exit1:
+; CHECK-NEXT:    ret void
+; CHECK:       exit2:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %loop
+
+loop:
+  store i32 0, i32* @G
+  br i1 false, label %latch, label %exit1
+latch:
+  %latchcond = call i1 @unknown()
+  br i1 %latchcond, label %loop, label %exit2
+
+exit1:
+  ret void
+exit2:
+  ret void
+}
+
+
 define void @test_live_inner() {
 ; CHECK-LABEL: @test_live_inner(
 ; CHECK-NEXT:  entry:


        


More information about the llvm-commits mailing list