]> granicus.if.org Git - llvm/commitdiff
Exploit a zero LoopExit count to eliminate loop exits
authorPhilip Reames <listmail@philipreames.com>
Sat, 22 Jun 2019 17:54:25 +0000 (17:54 +0000)
committerPhilip Reames <listmail@philipreames.com>
Sat, 22 Jun 2019 17:54:25 +0000 (17:54 +0000)
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.

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

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

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

index 69dd973c114d5ac031c0ee39165682534f8a7388..57f246373f0ccce0867282c9ad70d4b67e2fe0aa 100644 (file)
@@ -2724,9 +2724,21 @@ bool IndVarSimplify::run(Loop *L) {
       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)
index cd639f8d731a9015cc221f2db9999d35c22c9f6a..49088601125eda43166127c986db25993433b180 100644 (file)
@@ -284,7 +284,7 @@ define i32 @func_12() nounwind uwtable {
 ; 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 @@ leave:
   ret void
 }
 
-
 !0 = !{i32 0, i32 2147483647}
index f152c2368594201f87650b6ec68bc948eed60b27..eaa20b5bf6df87b308762bfc93d8c9b053c59025 100644 (file)
@@ -174,7 +174,7 @@ define void @test_06(i32 %n) {
 ; 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 @@ define void @test_06_unsigned(i32 %n) {
 ; 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
 ;