[PATCH] D63618: Exploit a zero LoopExit count to eliminate loop exits

Philip Reames via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 12:29:09 PDT 2019


reames created this revision.
reames added reviewers: nikic, sanjoy, apilipenko.
Herald added subscribers: javed.absar, bollu, mcrosier.
Herald added a project: LLVM.

This turned out to be surprisingly effective.  I was originally doing this just for completeness sake, but it seems like there are a lot of cases where SCEV's exit count reasoning is stronger than it's isKnownPredicate reasoning.

Once this is in, I'm thinking about trying to build on the same infrastructure to eliminate provably untaken checks.  There may be something generally interesting here.


Repository:
  rL LLVM

https://reviews.llvm.org/D63618

Files:
  lib/Transforms/Scalar/IndVarSimplify.cpp
  test/Transforms/IndVarSimplify/eliminate-comparison.ll
  test/Transforms/IndVarSimplify/eliminate-trunc.ll


Index: test/Transforms/IndVarSimplify/eliminate-trunc.ll
===================================================================
--- test/Transforms/IndVarSimplify/eliminate-trunc.ll
+++ test/Transforms/IndVarSimplify/eliminate-trunc.ll
@@ -174,7 +174,7 @@
 ; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
 ; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ;
@@ -354,7 +354,7 @@
 ; CHECK-NEXT:    [[IV_NEXT]] = add nsw i64 [[IV]], 1
 ; CHECK-NEXT:    [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
-; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK-NEXT:    br i1 false, label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ;
Index: test/Transforms/IndVarSimplify/eliminate-comparison.ll
===================================================================
--- test/Transforms/IndVarSimplify/eliminate-comparison.ll
+++ test/Transforms/IndVarSimplify/eliminate-comparison.ll
@@ -284,7 +284,7 @@
 ; CHECK-NEXT:    [[SEXT21:%.*]] = shl i32 [[TMP57]], 16
 ; CHECK-NEXT:    [[TMP76:%.*]] = icmp ne i32 [[SEXT34]], [[SEXT21]]
 ; CHECK-NEXT:    [[TMP81]] = add nuw nsw i32 [[__KEY8_0]], 1
-; CHECK-NEXT:    br i1 [[TMP76]], label [[FORCOND38]], label [[ASSERT77:%.*]]
+; CHECK-NEXT:    br i1 false, label [[FORCOND38]], label [[ASSERT77:%.*]]
 ; CHECK:       assert77:
 ; CHECK-NEXT:    tail call void @llvm.trap()
 ; CHECK-NEXT:    unreachable
@@ -897,5 +897,4 @@
   ret void
 }
 
-
 !0 = !{i32 0, i32 2147483647}
Index: lib/Transforms/Scalar/IndVarSimplify.cpp
===================================================================
--- lib/Transforms/Scalar/IndVarSimplify.cpp
+++ lib/Transforms/Scalar/IndVarSimplify.cpp
@@ -2724,9 +2724,21 @@
       if (isa<SCEVCouldNotCompute>(ExitCount))
         continue;
 
-      // Better to fold to true (TODO: do so!)
-      if (ExitCount->isZero())
+      // If we know we'd exit on the first iteration, rewrite the exit to
+      // reflect this.  This does not imply the loop must exit through this
+      // exit; there may be an earlier one taken on the first iteration.
+      // TODO: Given we know the backedge can't be taken, we should go ahead
+      // and break it.  Or at least, kill all the header phis and simplify.
+      if (ExitCount->isZero()) {
+        auto *BI = cast<BranchInst>(ExitingBB->getTerminator());
+        bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
+        auto *NewCond = ExitIfTrue ?
+          ConstantInt::getTrue(BI->getCondition()->getType()) :
+          ConstantInt::getFalse(BI->getCondition()->getType());
+        BI->setCondition(NewCond);
+        Changed = true;
         continue;
+      }
       
       PHINode *IndVar = FindLoopCounter(L, ExitingBB, ExitCount, SE, DT);
       if (!IndVar)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D63618.205876.patch
Type: text/x-patch
Size: 3087 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190620/4208bb8f/attachment.bin>


More information about the llvm-commits mailing list