From: Philip Reames Date: Wed, 31 Jul 2019 21:15:21 +0000 (+0000) Subject: [IndVars, RLEV] Support rewriting exit values in loops without known exits (prep... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d5a3ed48801378a7359534a0324e27d62dbdda73;p=llvm [IndVars, RLEV] Support rewriting exit values in loops without known exits (prep work) This is a prepatory patch for future work on support exit value rewriting in loops with a mixture of computable and non-computable exit counts. The intention is to be "mostly NFC" - i.e. not enable any interesting new transforms - but in practice, there are some small output changes. The test differences are caused by cases wherewhere getSCEVAtScope can simplify a single entry phi without needing any knowledge of the loop. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@367485 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index 41e22b4a212..4ccfba94e78 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -630,7 +630,8 @@ bool IndVarSimplify::rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter) { // and varies predictably *inside* the loop. Evaluate the value it // contains when the loop exits, if possible. const SCEV *ExitValue = SE->getSCEVAtScope(Inst, L->getParentLoop()); - if (!SE->isLoopInvariant(ExitValue, L) || + if (isa(ExitValue) || + !SE->isLoopInvariant(ExitValue, L) || !isSafeToExpand(ExitValue, *SE)) continue; @@ -804,7 +805,7 @@ bool IndVarSimplify::canLoopBeDeleted( L->getExitingBlocks(ExitingBlocks); SmallVector ExitBlocks; L->getUniqueExitBlocks(ExitBlocks); - if (ExitBlocks.size() > 1 || ExitingBlocks.size() > 1) + if (ExitBlocks.size() != 1 || ExitingBlocks.size() != 1) return false; BasicBlock *ExitBlock = ExitBlocks[0]; @@ -2774,14 +2775,11 @@ bool IndVarSimplify::run(Loop *L) { Rewriter.disableCanonicalMode(); Changed |= simplifyAndExtend(L, Rewriter, LI); - // Check to see if this loop has a computable loop-invariant execution count. - // If so, this means that we can compute the final value of any expressions + // Check to see if we can compute the final value of any expressions // that are recurrent in the loop, and substitute the exit values from the - // loop into any instructions outside of the loop that use the final values of - // the current expressions. - // - if (ReplaceExitValue != NeverRepl && - !isa(BackedgeTakenCount)) + // loop into any instructions outside of the loop that use the final values + // of the current expressions. + if (ReplaceExitValue != NeverRepl) Changed |= rewriteLoopExitValues(L, Rewriter); // Eliminate redundant IV cycles. diff --git a/test/Transforms/IndVarSimplify/lftr-pr20680.ll b/test/Transforms/IndVarSimplify/lftr-pr20680.ll index 096501e86b1..6f67662f298 100644 --- a/test/Transforms/IndVarSimplify/lftr-pr20680.ll +++ b/test/Transforms/IndVarSimplify/lftr-pr20680.ll @@ -62,7 +62,6 @@ define void @f() { ; CHECK: cond.false.us: ; CHECK-NEXT: br label [[COND_END_US]] ; CHECK: cond.end.us: -; CHECK-NEXT: [[COND_US:%.*]] = phi i32 [ [[DIV]], [[COND_FALSE_US]] ], [ [[INDVARS_IV]], [[FOR_BODY3_US]] ] ; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* @b, align 4 ; CHECK-NEXT: [[CMP91_US:%.*]] = icmp slt i32 [[TMP6]], 1 ; CHECK-NEXT: br i1 [[CMP91_US]], label [[FOR_INC_LR_PH_US:%.*]], label [[FOR_COND2_LOOPEXIT_US:%.*]] @@ -79,10 +78,9 @@ define void @f() { ; CHECK-NEXT: store i32 1, i32* @b, align 4 ; CHECK-NEXT: br label [[FOR_COND2_LOOPEXIT_US]] ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa.us.us-lcssa: -; CHECK-NEXT: [[COND_LCSSA_PH_US_PH:%.*]] = phi i32 [ [[COND_US]], [[FOR_COND2_LOOPEXIT_US]] ] ; CHECK-NEXT: br label [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US]] ; CHECK: for.cond2.for.inc13_crit_edge.us-lcssa.us: -; CHECK-NEXT: [[COND_LCSSA_PH_US:%.*]] = phi i32 [ [[COND_LCSSA_PH_US_PH]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA]] ], [ [[DIV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA_US]] ] +; CHECK-NEXT: [[COND_LCSSA_PH_US:%.*]] = phi i32 [ [[DIV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA]] ], [ [[DIV]], [[FOR_COND2_FOR_INC13_CRIT_EDGE_US_LCSSA_US_US_LCSSA_US]] ] ; CHECK-NEXT: br label [[FOR_COND2_FOR_INC13_CRIT_EDGE:%.*]] ; CHECK: for.body3.lr.ph.split: ; CHECK-NEXT: br i1 [[TOBOOL]], label [[FOR_BODY3_LR_PH_SPLIT_SPLIT_US:%.*]], label [[FOR_BODY3_LR_PH_SPLIT_FOR_BODY3_LR_PH_SPLIT_SPLIT_CRIT_EDGE:%.*]] diff --git a/test/Transforms/IndVarSimplify/pr38674.ll b/test/Transforms/IndVarSimplify/pr38674.ll index 78d59a372f2..1c839ffd2ac 100644 --- a/test/Transforms/IndVarSimplify/pr38674.ll +++ b/test/Transforms/IndVarSimplify/pr38674.ll @@ -92,15 +92,13 @@ define i32 @test_02(i32 %x) { ; CHECK: for.end: ; CHECK-NEXT: br i1 false, label [[FOR_COND4_PREHEADER]], label [[FOR_END9:%.*]] ; CHECK: for.end9: -; CHECK-NEXT: [[INC11:%.*]] = add nuw nsw i32 0, [[X]] ; CHECK-NEXT: br i1 false, label [[FOR_COND1_PREHEADER]], label [[RETURN_LOOPEXIT3:%.*]] ; CHECK: return.loopexit: ; CHECK-NEXT: unreachable ; CHECK: return.loopexit3: -; CHECK-NEXT: [[INC11_LCSSA:%.*]] = phi i32 [ [[INC11]], [[FOR_END9]] ] ; CHECK-NEXT: br label [[RETURN:%.*]] ; CHECK: return: -; CHECK-NEXT: ret i32 [[INC11_LCSSA]] +; CHECK-NEXT: ret i32 [[X]] ; entry: br label %for.cond1.preheader