llvm.org GIT mirror llvm / 02f541f
[PM] Teach LoopDeletion to correctly update the LPM when loops are deleted. I've expanded its test coverage a bit including adding one test that will crash clearly without this change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292332 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 2 years ago
4 changed file(s) with 67 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
9999 /// This entire process relies pretty heavily on LoopSimplify form and LCSSA in
100100 /// order to make various safety checks work.
101101 ///
102 /// \returns true if any changes are made, even if the loop is not deleted.
102 /// \returns true if the loop is deleted.
103 ///
104 /// This also sets the \p Changed output parameter to `true` if any changes
105 /// were made. This may mutate the loop even if it is unable to delete it due
106 /// to hoisting trivially loop invariant instructions out of the loop.
103107 ///
104108 /// This also updates the relevant analysis information in \p DT, \p SE, and \p
105109 /// LI.
106110 static bool deleteLoopIfDead(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
107 LoopInfo &LI) {
111 LoopInfo &LI, bool &Changed) {
108112 assert(L->isLCSSAForm(DT) && "Expected LCSSA!");
109113
110114 // We can only remove the loop if there is a preheader that we can
134138 return false;
135139
136140 // Finally, we have to check that the loop really is dead.
137 bool Changed = false;
138141 if (!isLoopDead(L, SE, ExitingBlocks, ExitBlock, Changed, Preheader))
139 return Changed;
142 return false;
140143
141144 // Don't remove loops for which we can't solve the trip count.
142145 // They could be infinite, in which case we'd be changing program behavior.
143146 const SCEV *S = SE.getMaxBackedgeTakenCount(L);
144147 if (isa(S))
145 return Changed;
148 return false;
146149
147150 // Now that we know the removal is safe, remove the loop by changing the
148151 // branch from the preheader to go to the single exit block.
214217
215218 ++NumDeleted;
216219
217 return Changed;
220 return true;
218221 }
219222
220223 PreservedAnalyses LoopDeletionPass::run(Loop &L, LoopAnalysisManager &AM,
221224 LoopStandardAnalysisResults &AR,
222 LPMUpdater &) {
223 bool Changed = deleteLoopIfDead(&L, AR.DT, AR.SE, AR.LI);
224 if (!Changed)
225 LPMUpdater &Updater) {
226 bool Changed = false;
227
228 if (deleteLoopIfDead(&L, AR.DT, AR.SE, AR.LI, Changed)) {
229 assert(Changed && "Cannot delete a loop without changing something!");
230 // Need to update the LPM about this loop going away.
231 Updater.markLoopAsDeleted(L);
232 } else if (!Changed) {
225233 return PreservedAnalyses::all();
234 }
226235
227236 return getLoopPassPreservedAnalyses();
228237 }
261270 ScalarEvolution &SE = getAnalysis().getSE();
262271 LoopInfo &LI = getAnalysis().getLoopInfo();
263272
264 return deleteLoopIfDead(L, DT, SE, LI);
265 }
273 bool Changed = false;
274 return deleteLoopIfDead(L, DT, SE, LI, Changed) || Changed;
275 }
0 ; Ensure we don't run analyses over loops after they've been deleted. We run
1 ; one version with a no-op loop pass to make sure that the loop doesn't get
2 ; simplified away.
3 ;
4 ; RUN: opt < %s -passes='require,no-op-loop,require' -S \
5 ; RUN: | FileCheck %s --check-prefixes=CHECK,BEFORE
6 ; RUN: opt < %s -passes='require,loop-deletion,require' -S \
7 ; RUN: | FileCheck %s --check-prefixes=CHECK,AFTER
8
9
10 define void @foo(i64 %n, i64 %m) nounwind {
11 ; CHECK-LABEL: @foo(
12
13 entry:
14 br label %bb
15 ; CHECK: entry:
16 ; BEFORE-NEXT: br label %bb
17 ; AFTER-NEXT: br label %return
18
19 bb:
20 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb2 ]
21 %t0 = add i64 %x.0, 1
22 %t1 = icmp slt i64 %x.0, %n
23 br i1 %t1, label %bb2, label %return
24 ; BEFORE: bb:
25 ; BEFORE: br i1 {{.*}}, label %bb2, label %return
26 ; AFTER-NOT: bb:
27 ; AFTER-NOT: br
28
29 bb2:
30 %t2 = icmp slt i64 %x.0, %m
31 br i1 %t1, label %bb, label %return
32 ; BEFORE: bb2:
33 ; BEFORE: br i1 {{.*}}, label %bb, label %return
34 ; AFTER-NOT: bb2:
35 ; AFTER-NOT: br
36
37 return:
38 ret void
39 ; CHECK: return:
40 ; CHECK-NEXT: ret void
41 }
0 ; RUN: opt < %s -loop-deletion -S | FileCheck %s
1 ; RUN: opt < %s -passes='require,loop(loop-deletion)' -S | FileCheck %s
1 ; RUN: opt < %s -passes='loop(loop-deletion)' -S | FileCheck %s
22
33 ; ScalarEvolution can prove the loop iteration is finite, even though
44 ; it can't represent the exact trip count as an expression. That's
44 ;
55 ; RUN: opt < %s -loop-simplify -lcssa -S | FileCheck %s --check-prefixes=CHECK,BEFORE
66 ; RUN: opt < %s -loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
7 ;
8 ; RUN: opt < %s -passes=no-op-loop -S | FileCheck %s --check-prefixes=CHECK,BEFORE
9 ; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s --check-prefixes=CHECK,AFTER
710
811
912 define void @foo(i64 %n, i64 %m) nounwind {