From: Max Kazantsev Date: Mon, 13 Sep 2021 04:29:33 +0000 (+0700) Subject: [IndVars] Break backedge and replace PHIs if loop exits on 1st iteration X-Git-Tag: upstream/15.0.7~31647 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d9ca444835e67960df927d5b8cade57776fdd8cb;p=platform%2Fupstream%2Fllvm.git [IndVars] Break backedge and replace PHIs if loop exits on 1st iteration Implement TODO in optimizeLoopExits. Now if we have proved that some loop exit is taken on 1st iteration, we make all branches in the following exiting blocks always branch out of the loop and their conditions simplified away. Patch by Dmitry Makogon! Differential Revision: https://reviews.llvm.org/D108910 Reviewed By: lebedev.ri --- diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 320e20c..f6a6ea1 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1465,8 +1465,15 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) { bool Changed = false; bool SkipLastIter = false; + bool ExitsOnFirstIter = false; SmallSet DominatingExitCounts; for (BasicBlock *ExitingBB : ExitingBlocks) { + if (ExitsOnFirstIter) { + // If proved that some earlier exit is taken + // on 1st iteration, then fold this one. + foldExit(L, ExitingBB, true, DeadInsts); + continue; + } const SCEV *ExitCount = SE->getExitCount(L, ExitingBB); if (isa(ExitCount)) { // Okay, we do not know the exit count here. Can we at least prove that it @@ -1516,6 +1523,7 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) { foldExit(L, ExitingBB, true, DeadInsts); replaceLoopPHINodesWithPreheaderValues(L, DeadInsts); Changed = true; + ExitsOnFirstIter = true; continue; } diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll index e2ba6e0..6070178 100644 --- a/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll +++ b/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll @@ -15,7 +15,6 @@ define i1 @kill_backedge_and_phis(i8* align 1 %lhs, i8* align 1 %rhs, i32 %len) ; CHECK: loop_preheader: ; CHECK-NEXT: br label %loop ; CHECK: loop: -; CHECK-NEXT: %iv.next = add nuw nsw i32 0, 1 ; CHECK-NEXT: %left_ptr = getelementptr inbounds i8, i8* %lhs, i32 0 ; CHECK-NEXT: %right_ptr = getelementptr inbounds i8, i8* %rhs, i32 0 ; CHECK-NEXT: %result = call i1 @foo(i8* %left_ptr, i8* %right_ptr) @@ -25,12 +24,10 @@ define i1 @kill_backedge_and_phis(i8* align 1 %lhs, i8* align 1 %rhs, i32 %len) ; CHECK-NEXT: br i1 false, label %exiting_2, label %exit.loopexit ; CHECK: exiting_2: ; CHECK-NEXT: %bar_ret = call i1 @bar() -; CHECK-NEXT: br i1 %bar_ret, label %exit.loopexit, label %exiting_3 +; CHECK-NEXT: br i1 true, label %exit.loopexit, label %exiting_3 ; CHECK: exiting_3: ; CHECK-NEXT: %baz_ret = call i1 @baz() -; CHECK-NEXT: %continue = icmp ne i32 %iv.next, %len -; CHECK-NEXT: %or.cond = select i1 %baz_ret, i1 %continue, i1 false -; CHECK-NEXT: br i1 %or.cond, label %loop, label %exit.loopexit +; CHECK-NEXT: br i1 false, label %loop, label %exit.loopexit ; CHECK: exit.loopexit: ; CHECK-NEXT: %val.ph = phi i1 [ %baz_ret, %exiting_3 ], [ %bar_ret, %exiting_2 ], [ %iv.wide.is_not_zero, %exiting_1 ], [ %result, %loop ] ; CHECK-NEXT: br label %exit