Skip to content

Commit 4083a70

Browse files
committed
!fixup address latest comments, thanks
1 parent 7a16a91 commit 4083a70

File tree

3 files changed

+52
-29
lines changed

3 files changed

+52
-29
lines changed

llvm/include/llvm/Transforms/Utils/LoopPeel.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ namespace llvm {
2121

2222
bool canPeel(const Loop *L);
2323

24+
/// Returns true if the last iteration of \p L can be peeled off. It makes sure
25+
/// the loop exit condition can be adjusted when peeling and that the loop
26+
/// executes at least 2 iterations.
27+
bool canPeelLastIteration(const Loop &L, ScalarEvolution &SE);
28+
2429
/// VMap is the value-map that maps instructions from the original loop to
2530
/// instructions in the last peeled-off iteration. If \p PeelLast is true, peel
26-
/// off the last \p PeelCount iterations from \p L. In that case, the caller has
27-
/// to make sure that the exit condition can be adjusted when peeling and that
28-
/// the loop executes at least 2 iterations.
31+
/// off the last \p PeelCount iterations from \p L (canPeelLastIteration must be
32+
/// true for \p L), otherwise peel off the first \p PeelCount iterations.
2933
bool peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
3034
ScalarEvolution *SE, DominatorTree &DT, AssumptionCache *AC,
3135
bool PreserveLCSSA, ValueToValueMapTy &VMap);

llvm/lib/Transforms/Utils/LoopPeel.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -326,13 +326,7 @@ static unsigned peelToTurnInvariantLoadsDerefencebale(Loop &L,
326326
return 0;
327327
}
328328

329-
/// Returns true if the last iteration can be peeled off and the condition (Pred
330-
/// LeftAR, RightSCEV) is known at the last iteration and the inverse condition
331-
/// is known at the second-to-last. This function also has to make sure the loop
332-
/// exit condition can be adjusted when peeling and that the loop executes at
333-
/// least 2 iterations.
334-
static bool canPeelLastIteration(Loop &L, const SCEVAddRecExpr *LeftAR,
335-
const SCEV *RightSCEV, ScalarEvolution &SE) {
329+
bool llvm::canPeelLastIteration(const Loop &L, ScalarEvolution &SE) {
336330
const SCEV *BTC = SE.getBackedgeTakenCount(&L);
337331
Value *Inc;
338332
CmpPredicate Pred;
@@ -351,16 +345,27 @@ static bool canPeelLastIteration(Loop &L, const SCEVAddRecExpr *LeftAR,
351345
// * the exit condition must be a NE/EQ compare of an induction with step
352346
// of 1.
353347
BasicBlock *Latch = L.getLoopLatch();
354-
if (Latch != L.getExitingBlock() ||
355-
!match(Latch->getTerminator(),
356-
m_Br(m_ICmp(Pred, m_Value(Inc), m_Value()), m_BasicBlock(Succ1),
357-
m_BasicBlock(Succ2))) ||
358-
!((Pred == CmpInst::ICMP_EQ && Succ2 == L.getHeader()) ||
359-
(Pred == CmpInst::ICMP_NE && Succ1 == L.getHeader())) ||
360-
!isa<SCEVAddRecExpr>(SE.getSCEV(Inc)) ||
361-
!cast<SCEVAddRecExpr>(SE.getSCEV(Inc))->getStepRecurrence(SE)->isOne())
348+
return Latch == L.getExitingBlock() &&
349+
match(Latch->getTerminator(),
350+
m_Br(m_ICmp(Pred, m_Value(Inc), m_Value()), m_BasicBlock(Succ1),
351+
m_BasicBlock(Succ2))) &&
352+
((Pred == CmpInst::ICMP_EQ && Succ2 == L.getHeader()) ||
353+
(Pred == CmpInst::ICMP_NE && Succ1 == L.getHeader())) &&
354+
isa<SCEVAddRecExpr>(SE.getSCEV(Inc)) &&
355+
cast<SCEVAddRecExpr>(SE.getSCEV(Inc))->getStepRecurrence(SE)->isOne();
356+
}
357+
358+
/// Returns true if the last iteration can be peeled off and the condition (Pred
359+
/// LeftAR, RightSCEV) is known at the last iteration and the inverse condition
360+
/// is known at the second-to-last.
361+
static bool shouldPeelLastIteration(Loop &L, CmpPredicate Pred,
362+
const SCEVAddRecExpr *LeftAR,
363+
const SCEV *RightSCEV,
364+
ScalarEvolution &SE) {
365+
if (!canPeelLastIteration(L, SE))
362366
return false;
363367

368+
const SCEV *BTC = SE.getBackedgeTakenCount(&L);
364369
const SCEV *ValAtLastIter =
365370
SE.applyLoopGuards(LeftAR->evaluateAtIteration(BTC, SE), &L);
366371
const SCEV *ValAtSecondToLastIter = LeftAR->evaluateAtIteration(
@@ -470,7 +475,7 @@ static int countToEliminateCompares(Loop &L, unsigned MaxPeelCount,
470475
const SCEV *Step = LeftAR->getStepRecurrence(SE);
471476
if (!PeelWhilePredicateIsKnown(NewPeelCount, IterVal, RightSCEV, Step,
472477
Pred)) {
473-
if (canPeelLastIteration(L, LeftAR, RightSCEV, SE))
478+
if (shouldPeelLastIteration(L, Pred, LeftAR, RightSCEV, SE))
474479
DesiredPeelCount = -1;
475480
return;
476481
}
@@ -987,8 +992,9 @@ bool llvm::peelLoop(Loop *L, unsigned PeelCount, bool PeelLast, LoopInfo *LI,
987992
bool PreserveLCSSA, ValueToValueMapTy &LVMap) {
988993
assert(PeelCount > 0 && "Attempt to peel out zero iterations?");
989994
assert(canPeel(L) && "Attempt to peel a loop which is not peelable?");
990-
assert((!PeelLast || PeelCount == 1) &&
991-
"can only peel off a single iteration from the end for now");
995+
assert((!PeelLast || (canPeelLastIteration(*L, *SE) && PeelCount == 1)) &&
996+
"when peeling the last iteration, the loop must be supported and can "
997+
"only peel a single iteration");
992998

993999
LoopBlocksDFS LoopBlocks(L);
9941000
LoopBlocks.perform(LI);

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,15 +87,27 @@ define i64 @peel_single_block_loop_iv_step_1_eq_pred() {
8787
; CHECK-NEXT: [[ENTRY:.*]]:
8888
; CHECK-NEXT: br label %[[LOOP:.*]]
8989
; CHECK: [[LOOP]]:
90-
; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ]
90+
; CHECK-NEXT: [[IV1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV:%.*]], %[[LOOP]] ]
91+
; CHECK-NEXT: call void @foo(i32 20)
92+
; CHECK-NEXT: [[IV]] = add nuw nsw i64 [[IV1]], 1
9193
; CHECK-NEXT: [[CMP18_NOT:%.*]] = icmp eq i64 [[IV]], 63
92-
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP18_NOT]], i32 10, i32 20
94+
; CHECK-NEXT: br i1 [[CMP18_NOT]], label %[[EXIT_PEEL_BEGIN:.*]], label %[[LOOP]], !llvm.loop [[LOOP2:![0-9]+]]
95+
; CHECK: [[EXIT_PEEL_BEGIN]]:
96+
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]
97+
; CHECK-NEXT: [[IV_LCSSA1:%.*]] = phi i64 [ [[IV1]], %[[LOOP]] ]
98+
; CHECK-NEXT: br label %[[LOOP_PEEL:.*]]
99+
; CHECK: [[LOOP_PEEL]]:
100+
; CHECK-NEXT: [[CMP_PEEL:%.*]] = icmp eq i64 [[IV_LCSSA]], 63
101+
; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_PEEL]], i32 10, i32 20
93102
; CHECK-NEXT: call void @foo(i32 [[COND]])
94-
; CHECK-NEXT: [[IV_NEXT]] = add i64 [[IV]], 1
103+
; CHECK-NEXT: [[IV_NEXT:%.*]] = add i64 [[IV_LCSSA]], 1
95104
; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 64
96-
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT:.*]], label %[[LOOP]]
105+
; CHECK-NEXT: br i1 [[EC]], label %[[EXIT_PEEL_NEXT:.*]], label %[[EXIT_PEEL_NEXT]]
106+
; CHECK: [[EXIT_PEEL_NEXT]]:
107+
; CHECK-NEXT: br label %[[LOOP_PEEL_NEXT:.*]]
108+
; CHECK: [[LOOP_PEEL_NEXT]]:
109+
; CHECK-NEXT: br label %[[EXIT:.*]]
97110
; CHECK: [[EXIT]]:
98-
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LOOP]] ]
99111
; CHECK-NEXT: ret i64 [[IV_LCSSA]]
100112
;
101113
entry:
@@ -157,7 +169,7 @@ define i64 @peel_single_block_loop_iv_step_1_nested_loop() {
157169
; CHECK-NEXT: call void @foo(i32 20)
158170
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
159171
; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 63
160-
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[OUTER_LATCH_PEEL_BEGIN:.*]], !llvm.loop [[LOOP2:![0-9]+]]
172+
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[OUTER_LATCH_PEEL_BEGIN:.*]], !llvm.loop [[LOOP3:![0-9]+]]
161173
; CHECK: [[OUTER_LATCH_PEEL_BEGIN]]:
162174
; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LOOP]] ]
163175
; CHECK-NEXT: br label %[[LOOP_PEEL:.*]]
@@ -217,7 +229,7 @@ define i64 @peel_multi_block_loop_iv_step_1() {
217229
; CHECK: [[LATCH]]:
218230
; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
219231
; CHECK-NEXT: [[EC:%.*]] = icmp ne i64 [[IV_NEXT]], 63
220-
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP3:![0-9]+]]
232+
; CHECK-NEXT: br i1 [[EC]], label %[[LOOP]], label %[[EXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP4:![0-9]+]]
221233
; CHECK: [[EXIT_PEEL_BEGIN]]:
222234
; CHECK-NEXT: [[IV_NEXT_LCSSA:%.*]] = phi i64 [ [[IV_NEXT]], %[[LATCH]] ]
223235
; CHECK-NEXT: [[IV_LCSSA:%.*]] = phi i64 [ [[IV]], %[[LATCH]] ]
@@ -429,7 +441,7 @@ define i32 @peel_loop_with_branch_and_phi_uses(ptr %x, i1 %c) {
429441
; CHECK-NEXT: [[ADD1]] = add nsw i32 [[L1]], [[RED1]]
430442
; CHECK-NEXT: [[IV_NEXT1]] = add nuw nsw i32 [[IV1]], 1
431443
; CHECK-NEXT: [[EC1:%.*]] = icmp ne i32 [[IV_NEXT1]], 99
432-
; CHECK-NEXT: br i1 [[EC1]], label %[[LOOP_HEADER]], label %[[LOOPEXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP4:![0-9]+]]
444+
; CHECK-NEXT: br i1 [[EC1]], label %[[LOOP_HEADER]], label %[[LOOPEXIT_PEEL_BEGIN:.*]], !llvm.loop [[LOOP5:![0-9]+]]
433445
; CHECK: [[LOOPEXIT_PEEL_BEGIN]]:
434446
; CHECK-NEXT: [[RED:%.*]] = phi i32 [ [[ADD1]], %[[LOOP_LATCH]] ]
435447
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ [[IV_NEXT1]], %[[LOOP_LATCH]] ]
@@ -497,4 +509,5 @@ declare i1 @cond()
497509
; CHECK: [[LOOP2]] = distinct !{[[LOOP2]], [[META1]]}
498510
; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META1]]}
499511
; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]]}
512+
; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META1]]}
500513
;.

0 commit comments

Comments
 (0)