diff --git a/llvm/lib/Transforms/Utils/LoopPeel.cpp b/llvm/lib/Transforms/Utils/LoopPeel.cpp index bd025fddd0cf7..cd6fdcce7d2a6 100644 --- a/llvm/lib/Transforms/Utils/LoopPeel.cpp +++ b/llvm/lib/Transforms/Utils/LoopPeel.cpp @@ -374,6 +374,9 @@ static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred, L.getLoopPredecessor()->getTerminator())) return false; + auto Guards = ScalarEvolution::LoopGuards::collect(&L, SE); + BTC = SE.applyLoopGuards(BTC, Guards); + RightSCEV = SE.applyLoopGuards(RightSCEV, Guards); const SCEV *ValAtLastIter = LeftAR->evaluateAtIteration(BTC, SE); const SCEV *ValAtSecondToLastIter = LeftAR->evaluateAtIteration( SE.getMinusSCEV(BTC, SE.getOne(BTC->getType())), SE); diff --git a/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll b/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll index af07a97131322..824e23fcf3e6e 100644 --- a/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll +++ b/llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll @@ -13,14 +13,33 @@ define void @peel_with_guard_known_nonnegative_1(i32 %n) { ; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i64 ; CHECK-NEXT: [[N_1:%.*]] = add i32 [[N]], 1 ; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N_1]] to i64 +; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[WIDE_TRIP_COUNT]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[TMP0]], 0 +; CHECK-NEXT: br i1 [[TMP1]], label %[[PH_SPLIT:.*]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN:.*]] +; CHECK: [[PH_SPLIT]]: ; CHECK-NEXT: br label %[[LOOP:.*]] ; CHECK: [[LOOP]]: -; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[PH_SPLIT]] ], [ [[IV_NEXT1:%.*]], %[[LOOP]] ] +; CHECK-NEXT: [[IV_NEXT1]] = add nuw nsw i64 [[IV1]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[WIDE_TRIP_COUNT]], 1 +; CHECK-NEXT: [[EC1:%.*]] = icmp eq i64 [[IV_NEXT1]], [[TMP2]] +; CHECK-NEXT: br i1 [[EC1]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK: [[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT]]: +; CHECK-NEXT: [[DOTPH:%.*]] = phi i64 [ [[IV_NEXT1]], %[[LOOP]] ] +; CHECK-NEXT: br label %[[EXIT_LOOPEXIT_PEEL_BEGIN]] +; CHECK: [[EXIT_LOOPEXIT_PEEL_BEGIN]]: +; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[PH]] ], [ [[DOTPH]], %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT]] ] +; CHECK-NEXT: br label %[[LOOP_PEEL:.*]] +; CHECK: [[LOOP_PEEL]]: ; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[IV]], [[N_EXT]] ; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C]], i32 10, i32 20 -; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1 +; CHECK-NEXT: [[IV_NEXT:%.*]] = add i64 [[IV]], 1 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]] -; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP]] +; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_NEXT:.*]], label %[[EXIT_LOOPEXIT_PEEL_NEXT]] +; CHECK: [[EXIT_LOOPEXIT_PEEL_NEXT]]: +; CHECK-NEXT: br label %[[LOOP_PEEL_NEXT:.*]] +; CHECK: [[LOOP_PEEL_NEXT]]: +; CHECK-NEXT: br label %[[EXIT_LOOPEXIT:.*]] ; CHECK: [[EXIT_LOOPEXIT]]: ; CHECK-NEXT: br label %[[EXIT]] ; CHECK: [[EXIT]]: @@ -137,7 +156,7 @@ define void @peel_with_guard2(i32 %n) { ; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1 ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[N]], 1 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], [[TMP2]] -; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP0:![0-9]+]] +; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP2:![0-9]+]] ; CHECK: [[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT]]: ; CHECK-NEXT: [[DOTPH:%.*]] = phi i32 [ [[IV_NEXT]], %[[LOOP_LATCH]] ] ; CHECK-NEXT: br label %[[EXIT_LOOPEXIT_PEEL_BEGIN]] @@ -188,4 +207,5 @@ exit: ;. ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]} ; CHECK: [[META1]] = !{!"llvm.loop.peeled.count", i32 1} +; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META1]]} ;.