llvm.org GIT mirror llvm / 32acc1f
Exploit a zero LoopExit count to eliminate loop exits 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 Philip Reames 2 months ago
3 changed file(s) with 17 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
27232723 if (isa(ExitCount))
27242724 continue;
27252725
2726 // Better to fold to true (TODO: do so!)
2727 if (ExitCount->isZero())
2726 // If we know we'd exit on the first iteration, rewrite the exit to
2727 // reflect this. This does not imply the loop must exit through this
2728 // exit; there may be an earlier one taken on the first iteration.
2729 // TODO: Given we know the backedge can't be taken, we should go ahead
2730 // and break it. Or at least, kill all the header phis and simplify.
2731 if (ExitCount->isZero()) {
2732 auto *BI = cast(ExitingBB->getTerminator());
2733 bool ExitIfTrue = !L->contains(*succ_begin(ExitingBB));
2734 auto *NewCond = ExitIfTrue ?
2735 ConstantInt::getTrue(BI->getCondition()->getType()) :
2736 ConstantInt::getFalse(BI->getCondition()->getType());
2737 BI->setCondition(NewCond);
2738 Changed = true;
27282739 continue;
2740 }
27292741
27302742 PHINode *IndVar = FindLoopCounter(L, ExitingBB, ExitCount, SE, DT);
27312743 if (!IndVar)
283283 ; CHECK-NEXT: [[SEXT21:%.*]] = shl i32 [[TMP57]], 16
284284 ; CHECK-NEXT: [[TMP76:%.*]] = icmp ne i32 [[SEXT34]], [[SEXT21]]
285285 ; CHECK-NEXT: [[TMP81]] = add nuw nsw i32 [[__KEY8_0]], 1
286 ; CHECK-NEXT: br i1 [[TMP76]], label [[FORCOND38]], label [[ASSERT77:%.*]]
286 ; CHECK-NEXT: br i1 false, label [[FORCOND38]], label [[ASSERT77:%.*]]
287287 ; CHECK: assert77:
288288 ; CHECK-NEXT: tail call void @llvm.trap()
289289 ; CHECK-NEXT: unreachable
896896 ret void
897897 }
898898
899
900899 !0 = !{i32 0, i32 2147483647}
173173 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
174174 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
175175 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[NARROW_IV]], [[N:%.*]]
176 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
176 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
177177 ; CHECK: exit:
178178 ; CHECK-NEXT: ret void
179179 ;
353353 ; CHECK-NEXT: [[IV_NEXT]] = add nsw i64 [[IV]], 1
354354 ; CHECK-NEXT: [[NARROW_IV:%.*]] = trunc i64 [[IV]] to i32
355355 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[NARROW_IV]], [[N:%.*]]
356 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
356 ; CHECK-NEXT: br i1 false, label [[LOOP]], label [[EXIT:%.*]]
357357 ; CHECK: exit:
358358 ; CHECK-NEXT: ret void
359359 ;