From 471217cff8e5c827f2ee52175a1c94584699cab2 Mon Sep 17 00:00:00 2001 From: Max Kazantsev Date: Mon, 20 Sep 2021 11:28:56 +0700 Subject: [PATCH] Revert "Revert "[IndVars] Replace PHIs if loop exits on 1st iteration"" This reverts commit 6fec6552f54885ae06bf76b35f9f1173a0561a4c. The patch was reverted on incorrect claim that this patch may break LCSSA form when the loop is not in a simplify form. All IndVars' transform insure that the loop is in simplify and LCSSA form, so if it wasn't broken before this transform, it will also not be broken after it. --- llvm/lib/Transforms/Scalar/IndVarSimplify.cpp | 16 ++++++++++++++-- .../test/Transforms/IndVarSimplify/eliminate-backedge.ll | 11 ++++------- .../Transforms/IndVarSimplify/eliminate-exit-no-dl.ll | 5 ++--- llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll | 4 +--- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp index 9b665bb..320e20c 100644 --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1309,6 +1309,17 @@ static void foldExit(const Loop *L, BasicBlock *ExitingBB, bool IsTaken, replaceExitCond(BI, NewCond, DeadInsts); } +static void replaceLoopPHINodesWithPreheaderValues( + Loop *L, SmallVectorImpl &DeadInsts) { + auto *LoopPreheader = L->getLoopPreheader(); + auto *LoopHeader = L->getHeader(); + for (auto &PN : LoopHeader->phis()) { + auto *PreheaderIncoming = PN.getIncomingValueForBlock(LoopPreheader); + PN.replaceAllUsesWith(PreheaderIncoming); + DeadInsts.emplace_back(&PN); + } +} + static void replaceWithInvariantCond( const Loop *L, BasicBlock *ExitingBB, ICmpInst::Predicate InvariantPred, const SCEV *InvariantLHS, const SCEV *InvariantRHS, SCEVExpander &Rewriter, @@ -1499,10 +1510,11 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) { // 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. + // We know that the backedge can't be taken, so we replace all + // the header PHIs with values coming from the preheader. if (ExitCount->isZero()) { foldExit(L, ExitingBB, true, DeadInsts); + replaceLoopPHINodesWithPreheaderValues(L, DeadInsts); Changed = true; continue; } diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll index 34bc4f6..e2ba6e0 100644 --- a/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll +++ b/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll @@ -15,16 +15,13 @@ 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 = phi i32 [ 0, %loop_preheader ], [ %iv.next, %exiting_3 ] -; CHECK-NEXT: %iv.wide = phi i64 [ 0, %loop_preheader ], [ %iv.wide.next, %exiting_3 ] -; CHECK-NEXT: %iv.next = add nuw nsw i32 %iv, 1 -; CHECK-NEXT: %iv.wide.next = add nuw nsw i64 %iv.wide, 1 -; CHECK-NEXT: %left_ptr = getelementptr inbounds i8, i8* %lhs, i32 %iv -; CHECK-NEXT: %right_ptr = getelementptr inbounds i8, i8* %rhs, i32 %iv +; 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) ; CHECK-NEXT: br i1 %result, label %exiting_1, label %exit.loopexit ; CHECK: exiting_1: -; CHECK-NEXT: %iv.wide.is_not_zero = icmp ne i64 %iv.wide, 0 +; CHECK-NEXT: %iv.wide.is_not_zero = icmp ne i64 0, 0 ; CHECK-NEXT: br i1 false, label %exiting_2, label %exit.loopexit ; CHECK: exiting_2: ; CHECK-NEXT: %bar_ret = call i1 @bar() diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-exit-no-dl.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-exit-no-dl.ll index 0abfb06..d8e0484 100644 --- a/llvm/test/Transforms/IndVarSimplify/eliminate-exit-no-dl.ll +++ b/llvm/test/Transforms/IndVarSimplify/eliminate-exit-no-dl.ll @@ -14,10 +14,9 @@ define void @foo() { ; CHECK-NEXT: bb: ; CHECK-NEXT: br label [[BB3:%.*]] ; CHECK: bb3: -; CHECK-NEXT: [[TMP:%.*]] = phi i8* [ [[TMP4:%.*]], [[BB7:%.*]] ], [ getelementptr inbounds ([0 x i8], [0 x i8]* @global, i64 0, i64 2), [[BB:%.*]] ] -; CHECK-NEXT: [[TMP4]] = getelementptr inbounds i8, i8* [[TMP]], i64 -1 +; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @global, i64 0, i64 2), i64 -1 ; CHECK-NEXT: [[TMP6:%.*]] = load i8, i8* [[TMP4]], align 1 -; CHECK-NEXT: br i1 false, label [[BB7]], label [[BB11:%.*]] +; CHECK-NEXT: br i1 false, label [[BB7:%.*]], label [[BB11:%.*]] ; CHECK: bb7: ; CHECK-NEXT: [[TMP8:%.*]] = zext i8 [[TMP6]] to i64 ; CHECK-NEXT: br i1 true, label [[BB11]], label [[BB3]] diff --git a/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll b/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll index f22e606..ca081e8 100644 --- a/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll +++ b/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll @@ -65,9 +65,7 @@ define void @test3() nounwind { ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[BB:%.*]] ; CHECK: bb: -; CHECK-NEXT: [[IV:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[BB]] ] -; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double [[IV]]) #[[ATTR0]] -; CHECK-NEXT: [[TMP1]] = fadd double [[IV]], 1.000000e+00 +; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @foo(double 0.000000e+00) #[[ATTR0]] ; CHECK-NEXT: br i1 false, label [[BB]], label [[RETURN:%.*]] ; CHECK: return: ; CHECK-NEXT: ret void -- 2.7.4