diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1465,8 +1465,15 @@ 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 @@ 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 --- a/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll +++ b/llvm/test/Transforms/IndVarSimplify/eliminate-backedge.ll @@ -15,7 +15,6 @@ ; 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 @@ ; 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