Skip to content

Commit 3ef3306

Browse files
authored
[UnrollAndJam] Do not preserve loop nests if a loop was fully unrolled. (#133510)
If UnJ completely unrolls a loop and removes it entirely, the loop remains in the current loop nest. If the loop nest gets reused the loops will no longer be valid. As there is no way to remove a loop from a LoopNest, this patch removes the preserve of the LoopNestAnalysis so that it will be regenerated. Fixes #124518
1 parent 2ec8837 commit 3ef3306

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

llvm/lib/Transforms/Scalar/LoopUnrollAndJamPass.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ static bool tryToUnrollAndJamLoop(LoopNest &LN, DominatorTree &DT, LoopInfo &LI,
425425
const TargetTransformInfo &TTI,
426426
AssumptionCache &AC, DependenceInfo &DI,
427427
OptimizationRemarkEmitter &ORE, int OptLevel,
428-
LPMUpdater &U) {
428+
LPMUpdater &U, bool &AnyLoopRemoved) {
429429
bool DidSomething = false;
430430
ArrayRef<Loop *> Loops = LN.getLoops();
431431
Loop *OutmostLoop = &LN.getOutermostLoop();
@@ -441,8 +441,11 @@ static bool tryToUnrollAndJamLoop(LoopNest &LN, DominatorTree &DT, LoopInfo &LI,
441441
tryToUnrollAndJamLoop(L, DT, &LI, SE, TTI, AC, DI, ORE, OptLevel);
442442
if (Result != LoopUnrollResult::Unmodified)
443443
DidSomething = true;
444-
if (L == OutmostLoop && Result == LoopUnrollResult::FullyUnrolled)
445-
U.markLoopAsDeleted(*L, LoopName);
444+
if (Result == LoopUnrollResult::FullyUnrolled) {
445+
if (L == OutmostLoop)
446+
U.markLoopAsDeleted(*L, LoopName);
447+
AnyLoopRemoved = true;
448+
}
446449
}
447450

448451
return DidSomething;
@@ -457,11 +460,13 @@ PreservedAnalyses LoopUnrollAndJamPass::run(LoopNest &LN,
457460
DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
458461
OptimizationRemarkEmitter ORE(&F);
459462

463+
bool AnyLoopRemoved = false;
460464
if (!tryToUnrollAndJamLoop(LN, AR.DT, AR.LI, AR.SE, AR.TTI, AR.AC, DI, ORE,
461-
OptLevel, U))
465+
OptLevel, U, AnyLoopRemoved))
462466
return PreservedAnalyses::all();
463467

464468
auto PA = getLoopPassPreservedAnalyses();
465-
PA.preserve<LoopNestAnalysis>();
469+
if (!AnyLoopRemoved)
470+
PA.preserve<LoopNestAnalysis>();
466471
return PA;
467472
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes="loop(invalidate<all>,loop-unroll-and-jam,loop-unroll-and-jam)" -allow-unroll-and-jam -unroll-and-jam-count=4 < %s -S | FileCheck %s
3+
4+
; This test completely unrolls the middle loop out of a 3-deep loop nest.
5+
6+
define i16 @test_it() {
7+
; CHECK-LABEL: define i16 @test_it() {
8+
; CHECK-NEXT: [[ENTRY:.*:]]
9+
; CHECK-NEXT: br label %[[FOR_COND:.*]]
10+
; CHECK: [[FOR_COND_LOOPEXIT:.*]]:
11+
; CHECK-NEXT: br label %[[FOR_COND]]
12+
; CHECK: [[FOR_COND]]:
13+
; CHECK-NEXT: br label %[[DO_BODY2:.*]]
14+
; CHECK: [[DO_BODY2]]:
15+
; CHECK-NEXT: br label %[[WHILE_COND3:.*]]
16+
; CHECK: [[WHILE_COND3]]:
17+
; CHECK-NEXT: br i1 true, label %[[DO_COND:.*]], label %[[WHILE_COND3]]
18+
; CHECK: [[DO_COND]]:
19+
; CHECK-NEXT: br label %[[FOR_COND_LOOPEXIT]]
20+
;
21+
entry:
22+
br label %for.cond
23+
24+
for.cond: ; preds = %do.cond, %entry
25+
br label %do.body2
26+
27+
do.body2: ; preds = %do.cond, %for.cond
28+
br label %while.cond3
29+
30+
while.cond3: ; preds = %while.cond3, %do.body2
31+
br i1 true, label %do.cond, label %while.cond3
32+
33+
do.cond: ; preds = %while.cond3
34+
br i1 true, label %for.cond, label %do.body2
35+
}
36+

0 commit comments

Comments
 (0)