Skip to content

Commit e5ff705

Browse files
authored
[LoopPeel] Use loop guards when checking if last iter can be peeled. (#142605)
Apply loop guards to BTC before checking if the last iteration should be peeled off. This also adds an assert to make sure applying the guards does not pessimize the results. I checked on a large test set and it did not trigger there, but it adds an additional guard to catch potential cases where loop-guards pessimize results. Peels ~15% more loops. PR: #142605
1 parent 20e8de9 commit e5ff705

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

llvm/lib/Transforms/Utils/LoopPeel.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred,
374374
L.getLoopPredecessor()->getTerminator()))
375375
return false;
376376

377+
auto Guards = ScalarEvolution::LoopGuards::collect(&L, SE);
378+
BTC = SE.applyLoopGuards(BTC, Guards);
379+
RightSCEV = SE.applyLoopGuards(RightSCEV, Guards);
377380
const SCEV *ValAtLastIter = LeftAR->evaluateAtIteration(BTC, SE);
378381
const SCEV *ValAtSecondToLastIter = LeftAR->evaluateAtIteration(
379382
SE.getMinusSCEV(BTC, SE.getOne(BTC->getType())), SE);

llvm/test/Transforms/LoopUnroll/peel-last-iteration-with-guards.ll

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,33 @@ define void @peel_with_guard_known_nonnegative_1(i32 %n) {
1313
; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i64
1414
; CHECK-NEXT: [[N_1:%.*]] = add i32 [[N]], 1
1515
; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N_1]] to i64
16+
; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[WIDE_TRIP_COUNT]], -1
17+
; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[TMP0]], 0
18+
; CHECK-NEXT: br i1 [[TMP1]], label %[[PH_SPLIT:.*]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN:.*]]
19+
; CHECK: [[PH_SPLIT]]:
1620
; CHECK-NEXT: br label %[[LOOP:.*]]
1721
; CHECK: [[LOOP]]:
18-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
22+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[PH_SPLIT]] ], [ [[IV_NEXT1:%.*]], %[[LOOP]] ]
23+
; CHECK-NEXT: [[IV_NEXT1]] = add nuw nsw i64 [[IV1]], 1
24+
; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[WIDE_TRIP_COUNT]], 1
25+
; CHECK-NEXT: [[EC1:%.*]] = icmp eq i64 [[IV_NEXT1]], [[TMP2]]
26+
; CHECK-NEXT: br i1 [[EC1]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP]], !llvm.loop [[LOOP0:![0-9]+]]
27+
; CHECK: [[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT]]:
28+
; CHECK-NEXT: [[DOTPH:%.*]] = phi i64 [ [[IV_NEXT1]], %[[LOOP]] ]
29+
; CHECK-NEXT: br label %[[EXIT_LOOPEXIT_PEEL_BEGIN]]
30+
; CHECK: [[EXIT_LOOPEXIT_PEEL_BEGIN]]:
31+
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[PH]] ], [ [[DOTPH]], %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT]] ]
32+
; CHECK-NEXT: br label %[[LOOP_PEEL:.*]]
33+
; CHECK: [[LOOP_PEEL]]:
1934
; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[IV]], [[N_EXT]]
2035
; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C]], i32 10, i32 20
21-
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
36+
; CHECK-NEXT: [[IV_NEXT:%.*]] = add i64 [[IV]], 1
2237
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[WIDE_TRIP_COUNT]]
23-
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT:.*]], label %[[LOOP]]
38+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_NEXT:.*]], label %[[EXIT_LOOPEXIT_PEEL_NEXT]]
39+
; CHECK: [[EXIT_LOOPEXIT_PEEL_NEXT]]:
40+
; CHECK-NEXT: br label %[[LOOP_PEEL_NEXT:.*]]
41+
; CHECK: [[LOOP_PEEL_NEXT]]:
42+
; CHECK-NEXT: br label %[[EXIT_LOOPEXIT:.*]]
2443
; CHECK: [[EXIT_LOOPEXIT]]:
2544
; CHECK-NEXT: br label %[[EXIT]]
2645
; CHECK: [[EXIT]]:
@@ -137,7 +156,7 @@ define void @peel_with_guard2(i32 %n) {
137156
; CHECK-NEXT: [[IV_NEXT]] = add nuw i32 [[IV]], 1
138157
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 [[N]], 1
139158
; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], [[TMP2]]
140-
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP0:![0-9]+]]
159+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT:.*]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP2:![0-9]+]]
141160
; CHECK: [[EXIT_LOOPEXIT_PEEL_BEGIN_LOOPEXIT]]:
142161
; CHECK-NEXT: [[DOTPH:%.*]] = phi i32 [ [[IV_NEXT]], %[[LOOP_LATCH]] ]
143162
; CHECK-NEXT: br label %[[EXIT_LOOPEXIT_PEEL_BEGIN]]
@@ -188,4 +207,5 @@ exit:
188207
;.
189208
; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]]}
190209
; CHECK: [[META1]] = !{!"llvm.loop.peeled.count", i32 1}
210+
; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META1]]}
191211
;.

0 commit comments

Comments
 (0)