1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -loop-deletion -verify-dom-info --pass-remarks-output=%t --pass-remarks-filter=loop-delete -S | FileCheck %s
3 ; RUN: cat %t | FileCheck %s --check-prefix=REMARKS
5 ; Checking that we can delete loops that are never executed.
6 ; We do not change the constant conditional branch statement (where the not-taken target
7 ; is the loop) to an unconditional one.
9 ; delete the infinite loop because it is never executed.
10 define void @test1(i64 %n, i64 %m) nounwind {
11 ; CHECK-LABEL: @test1(
13 ; CHECK-NEXT: br i1 true, label [[RETURN:%.*]], label [[BB_PREHEADER:%.*]]
14 ; CHECK: bb.preheader:
15 ; CHECK-NEXT: br label [[RETURN_LOOPEXIT:%.*]]
16 ; CHECK: return.loopexit:
17 ; CHECK-NEXT: br label [[RETURN]]
19 ; CHECK-NEXT: ret void
21 ; REMARKS-LABEL: Function: test1
22 ; REMARKS: Loop deleted because it never executes
24 br i1 true, label %return, label %bb
27 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb ]
29 %t1 = icmp slt i64 %x.0, %n
30 %t3 = icmp sgt i64 %x.0, %m
32 br i1 true, label %bb, label %return
38 ; FIXME: We can delete this infinite loop. Currently we do not,
39 ; because the infinite loop has no exit block.
40 define void @test2(i64 %n, i64 %m) nounwind {
41 ; CHECK-LABEL: @test2(
43 ; CHECK-NEXT: br i1 true, label [[RETURN:%.*]], label [[BB_PREHEADER:%.*]]
44 ; CHECK: bb.preheader:
45 ; CHECK-NEXT: br label [[BB:%.*]]
47 ; CHECK-NEXT: [[X_0:%.*]] = phi i64 [ [[T0:%.*]], [[BB]] ], [ 0, [[BB_PREHEADER]] ]
48 ; CHECK-NEXT: [[T0]] = add i64 [[X_0]], 1
49 ; CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[X_0]], [[N:%.*]]
50 ; CHECK-NEXT: [[T3:%.*]] = icmp sgt i64 [[X_0]], [[M:%.*]]
51 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
52 ; CHECK-NEXT: br label [[BB]]
54 ; CHECK-NEXT: ret void
57 br i1 true, label %return, label %bb
60 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb ]
62 %t1 = icmp slt i64 %x.0, %n
63 %t3 = icmp sgt i64 %x.0, %m
71 ; There are multiple exiting blocks and a single exit block.
72 ; Since it is a never executed loop, we do not care about the values
73 ; from different exiting paths and we can
75 define i64 @test3(i64 %n, i64 %m, i64 %maybe_zero) nounwind {
76 ; CHECK-LABEL: @test3(
78 ; CHECK-NEXT: br i1 false, label [[BB_PREHEADER:%.*]], label [[RETURN:%.*]]
79 ; CHECK: bb.preheader:
80 ; CHECK-NEXT: br label [[RETURN_LOOPEXIT:%.*]]
81 ; CHECK: return.loopexit:
82 ; CHECK-NEXT: [[X_LCSSA_PH:%.*]] = phi i64 [ undef, [[BB_PREHEADER]] ]
83 ; CHECK-NEXT: br label [[RETURN]]
85 ; CHECK-NEXT: [[X_LCSSA:%.*]] = phi i64 [ 20, [[ENTRY:%.*]] ], [ [[X_LCSSA_PH]], [[RETURN_LOOPEXIT]] ]
86 ; CHECK-NEXT: ret i64 [[X_LCSSA]]
88 ; REMARKS-LABEL: Function: test3
89 ; REMARKS: Loop deleted because it never executes
91 br i1 false, label %bb, label %return
94 %x.0 = phi i64 [ 0, %entry ], [ %t0, %bb3 ]
96 %t1 = icmp slt i64 %x.0, %n
97 br i1 %t1, label %bb2, label %return
100 %t2 = icmp slt i64 %x.0, %m
101 %unused1 = udiv i64 42, %maybe_zero
102 br i1 %t2, label %bb3, label %return
105 %t3 = icmp slt i64 %x.0, %m
106 %unused2 = sdiv i64 42, %maybe_zero
107 br i1 %t3, label %bb, label %return
110 ; the only valid value fo x.lcssa is 20.
111 %x.lcssa = phi i64 [ 12, %bb ], [ 14, %bb2 ], [ 16, %bb3 ], [20, %entry ]
115 ; Cannot delete the loop, since it may be executed at runtime.
116 define void @test4(i64 %n, i64 %m, i1 %cond) {
117 ; CHECK-LABEL: @test4(
119 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOPPRED1:%.*]], label [[LOOPPRED2:%.*]]
121 ; CHECK-NEXT: br i1 true, label [[RETURN:%.*]], label [[BB_PREHEADER:%.*]]
123 ; CHECK-NEXT: br i1 false, label [[RETURN]], label [[BB_PREHEADER]]
124 ; CHECK: bb.preheader:
125 ; CHECK-NEXT: [[X_0_PH:%.*]] = phi i64 [ 1, [[LOOPPRED2]] ], [ 0, [[LOOPPRED1]] ]
126 ; CHECK-NEXT: br label [[BB:%.*]]
128 ; CHECK-NEXT: [[X_0:%.*]] = phi i64 [ [[T0:%.*]], [[BB]] ], [ [[X_0_PH]], [[BB_PREHEADER]] ]
129 ; CHECK-NEXT: [[T0]] = add i64 [[X_0]], 1
130 ; CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[X_0]], [[N:%.*]]
131 ; CHECK-NEXT: [[T3:%.*]] = icmp sgt i64 [[X_0]], [[M:%.*]]
132 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
133 ; CHECK-NEXT: br i1 true, label [[BB]], label [[RETURN_LOOPEXIT:%.*]]
134 ; CHECK: return.loopexit:
135 ; CHECK-NEXT: br label [[RETURN]]
137 ; CHECK-NEXT: ret void
140 br i1 %cond, label %looppred1, label %looppred2
143 br i1 true, label %return, label %bb
146 br i1 false, label %return, label %bb
149 %x.0 = phi i64 [ 0, %looppred1 ], [ 1, %looppred2 ], [ %t0, %bb ]
150 %t0 = add i64 %x.0, 1
151 %t1 = icmp slt i64 %x.0, %n
152 %t3 = icmp sgt i64 %x.0, %m
153 %t4 = and i1 %t1, %t3
154 br i1 true, label %bb, label %return
160 ; multiple constant conditional branches with loop not-taken in all cases.
161 define void @test5(i64 %n, i64 %m, i1 %cond) nounwind {
162 ; CHECK-LABEL: @test5(
164 ; CHECK-NEXT: br i1 [[COND:%.*]], label [[LOOPPRED1:%.*]], label [[LOOPPRED2:%.*]]
166 ; CHECK-NEXT: br i1 true, label [[RETURN:%.*]], label [[BB_PREHEADER:%.*]]
168 ; CHECK-NEXT: br i1 true, label [[RETURN]], label [[BB_PREHEADER]]
169 ; CHECK: bb.preheader:
170 ; CHECK-NEXT: [[X_0_PH:%.*]] = phi i64 [ 1, [[LOOPPRED2]] ], [ 0, [[LOOPPRED1]] ]
171 ; CHECK-NEXT: br label [[RETURN_LOOPEXIT:%.*]]
172 ; CHECK: return.loopexit:
173 ; CHECK-NEXT: br label [[RETURN]]
175 ; CHECK-NEXT: ret void
177 ; REMARKS-LABEL: Function: test5
178 ; REMARKS: Loop deleted because it never executes
180 br i1 %cond, label %looppred1, label %looppred2
183 br i1 true, label %return, label %bb
186 br i1 true, label %return, label %bb
189 %x.0 = phi i64 [ 0, %looppred1 ], [ 1, %looppred2 ], [ %t0, %bb ]
190 %t0 = add i64 %x.0, 1
191 %t1 = icmp slt i64 %x.0, %n
192 %t3 = icmp sgt i64 %x.0, %m
193 %t4 = and i1 %t1, %t3
194 br i1 true, label %bb, label %return
200 ; Don't delete this infinite loop because the loop
201 ; is executable at runtime.
202 define void @test6(i64 %n, i64 %m) nounwind {
203 ; CHECK-LABEL: @test6(
205 ; CHECK-NEXT: br i1 true, label [[BB_PREHEADER:%.*]], label [[BB_PREHEADER]]
206 ; CHECK: bb.preheader:
207 ; CHECK-NEXT: br label [[BB:%.*]]
209 ; CHECK-NEXT: [[X_0:%.*]] = phi i64 [ [[T0:%.*]], [[BB]] ], [ 0, [[BB_PREHEADER]] ]
210 ; CHECK-NEXT: [[T0]] = add i64 [[X_0]], 1
211 ; CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[X_0]], [[N:%.*]]
212 ; CHECK-NEXT: [[T3:%.*]] = icmp sgt i64 [[X_0]], [[M:%.*]]
213 ; CHECK-NEXT: [[T4:%.*]] = and i1 [[T1]], [[T3]]
214 ; CHECK-NEXT: br i1 true, label [[BB]], label [[RETURN:%.*]]
216 ; CHECK-NEXT: ret void
219 br i1 true, label %bb, label %bb
222 %x.0 = phi i64 [ 0, %entry ], [ 0, %entry ], [ %t0, %bb ]
223 %t0 = add i64 %x.0, 1
224 %t1 = icmp slt i64 %x.0, %n
225 %t3 = icmp sgt i64 %x.0, %m
226 %t4 = and i1 %t1, %t3
227 br i1 true, label %bb, label %return
233 declare i64 @foo(i64)
234 ; The loop L2 is never executed and is a subloop, with an
235 ; exit block that branches back to parent loop.
236 ; Here we can delete loop L2, while L1 still exists.
237 define i64 @test7(i64 %n) {
238 ; CHECK-LABEL: @test7(
240 ; CHECK-NEXT: br label [[L1:%.*]]
242 ; CHECK-NEXT: [[Y_NEXT:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[Y_ADD:%.*]], [[L1LATCH:%.*]] ]
243 ; CHECK-NEXT: br i1 true, label [[L1LATCH]], label [[L2_PREHEADER:%.*]]
244 ; CHECK: L2.preheader:
245 ; CHECK-NEXT: br label [[L1LATCH_LOOPEXIT:%.*]]
246 ; CHECK: L1Latch.loopexit:
247 ; CHECK-NEXT: [[Y_L2_LCSSA:%.*]] = phi i64 [ undef, [[L2_PREHEADER]] ]
248 ; CHECK-NEXT: br label [[L1LATCH]]
250 ; CHECK-NEXT: [[Y:%.*]] = phi i64 [ [[Y_NEXT]], [[L1]] ], [ [[Y_L2_LCSSA]], [[L1LATCH_LOOPEXIT]] ]
251 ; CHECK-NEXT: [[Y_ADD]] = add i64 [[Y]], [[N:%.*]]
252 ; CHECK-NEXT: [[COND2:%.*]] = icmp eq i64 [[Y_ADD]], 42
253 ; CHECK-NEXT: br i1 [[COND2]], label [[EXIT:%.*]], label [[L1]]
255 ; CHECK-NEXT: [[Y_ADD_LCSSA:%.*]] = phi i64 [ [[Y_ADD]], [[L1LATCH]] ]
256 ; CHECK-NEXT: ret i64 [[Y_ADD_LCSSA]]
258 ; REMARKS-LABEL: Function: test7
259 ; REMARKS: Loop deleted because it never executes
264 %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
265 br i1 true, label %L1Latch, label %L2
268 %x = phi i64 [ 0, %L1 ], [ %x.next, %L2 ]
269 %x.next = add i64 %x, 1
270 %y.L2 = call i64 @foo(i64 %x.next)
271 %cond = icmp slt i64 %x.next, %n
272 br i1 %cond, label %L2, label %L1Latch
275 %y = phi i64 [ %y.next, %L1 ], [ %y.L2, %L2 ]
276 %y.add = add i64 %y, %n
277 %cond2 = icmp eq i64 %y.add, 42
278 br i1 %cond2, label %exit, label %L1
285 ; Show recursive deletion of loops. Since we start with subloops and progress outward
286 ; to parent loop, we first delete the loop L2. Now loop L1 becomes a non-loop since it's backedge
287 ; from L2's preheader to L1's exit block is never taken. So, L1 gets deleted as well.
288 define void @test8(i64 %n) {
289 ; CHECK-LABEL: @test8(
291 ; CHECK-NEXT: br label [[EXIT:%.*]]
293 ; CHECK-NEXT: ret void
295 ; REMARKS-LABEL: Function: test8
296 ; REMARKS: Loop deleted because it never executes
301 br i1 true, label %exit, label %L2
304 %x = phi i64 [ 0, %L1 ], [ %x.next, %L2 ]
305 %x.next = add i64 %x, 1
306 %y.L2 = call i64 @foo(i64 %x.next)
307 %cond = icmp slt i64 %x.next, %n
308 br i1 %cond, label %L2, label %L1
315 ; Delete a loop (L2) which has subloop (L3).
316 ; Here we delete loop L2, but leave L3 as is.
317 define void @test9(i64 %n) {
318 ; CHECK-LABEL: @test9(
320 ; CHECK-NEXT: br label [[L1:%.*]]
321 ; CHECK: L1.loopexit:
322 ; CHECK-NEXT: br label [[L1]]
324 ; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[L2_PREHEADER:%.*]]
325 ; CHECK: L2.preheader:
326 ; CHECK-NEXT: br label [[L3_PREHEADER:%.*]]
327 ; CHECK: L3.preheader:
328 ; CHECK-NEXT: [[Y_L2_LCSSA:%.*]] = phi i64 [ undef, [[L2_PREHEADER]] ]
329 ; CHECK-NEXT: br label [[L3:%.*]]
331 ; CHECK-NEXT: [[COND2:%.*]] = icmp slt i64 [[Y_L2_LCSSA]], [[N:%.*]]
332 ; CHECK-NEXT: br i1 [[COND2]], label [[L3_L3_CRIT_EDGE:%.*]], label [[L1_LOOPEXIT:%.*]]
333 ; CHECK: L3.L3_crit_edge:
334 ; CHECK-NEXT: unreachable
336 ; CHECK-NEXT: ret void
338 ; REMARKS-LABEL: Function: test9
339 ; REMARKS: Loop deleted because it never executes
344 br i1 true, label %exit, label %L2
347 %x = phi i64 [ 0, %L1 ], [ %x.next, %L2 ]
348 %x.next = add i64 %x, 1
349 %y.L2 = call i64 @foo(i64 %x.next)
350 %cond = icmp slt i64 %x.next, %n
351 br i1 %cond, label %L2, label %L3
354 %cond2 = icmp slt i64 %y.L2, %n
355 br i1 %cond2, label %L3, label %L1
361 ; We cannot delete L3 because of call within it.
362 ; Since L3 is not deleted, and entirely contained within L2, L2 is also not
364 define void @test10(i64 %n) {
365 ; CHECK-LABEL: @test10(
367 ; CHECK-NEXT: br label [[EXIT:%.*]]
369 ; CHECK-NEXT: ret void
375 br i1 true, label %exit, label %L2
378 %x = phi i64 [ 0, %L1 ], [ %x.next, %L3 ]
379 %x.next = add i64 %x, 1
380 %y.L2 = call i64 @foo(i64 %x.next)
381 %cond = icmp slt i64 %x.next, %n
382 br i1 %cond, label %L1, label %L3
385 %y.L3 = phi i64 [ %y.L2, %L2 ], [ %y.L3.next, %L3 ]
386 %y.L3.next = add i64 %y.L3, 1
387 %dummy = call i64 @foo(i64 %y.L3.next)
388 %cond2 = icmp slt i64 %y.L3, %n
389 br i1 %cond2, label %L3, label %L2
395 ; same as test10, but L3 does not contain call.
396 ; So, in the first iteration, all statements of L3 are made invariant, and L3 is
398 ; In the next iteration, since L2 is never executed and has no subloops, we delete
399 ; L2 as well. Finally, the outermost loop L1 is deleted.
400 define void @test11(i64 %n) {
401 ; CHECK-LABEL: @test11(
403 ; CHECK-NEXT: br label [[EXIT:%.*]]
405 ; CHECK-NEXT: ret void
407 ; REMARKS-LABEL: Function: test11
408 ; REMARKS: Loop deleted because it is invariant
409 ; REMARKS-LABEL: Function: test11
410 ; REMARKS: Loop deleted because it never executes
411 ; REMARKS-LABEL: Function: test11
412 ; REMARKS: Loop deleted because it is invariant
417 br i1 true, label %exit, label %L2
420 %x = phi i64 [ 0, %L1 ], [ %x.next, %L3 ]
421 %x.next = add i64 %x, 1
422 %y.L2 = call i64 @foo(i64 %x.next)
423 %cond = icmp slt i64 %x.next, %n
424 br i1 %cond, label %L1, label %L3
427 %y.L3 = phi i64 [ %y.L2, %L2 ], [ %y.L3.next, %L3 ]
428 %y.L3.next = add i64 %y.L3, 1
429 %cond2 = icmp slt i64 %y.L3, %n
430 br i1 %cond2, label %L3, label %L2
437 ; 2 edges from a single exiting block to the exit block.
438 define i64 @test12(i64 %n){
439 ; CHECK-LABEL: @test12(
441 ; CHECK-NEXT: br i1 true, label [[EXIT1:%.*]], label [[L1_PREHEADER:%.*]]
442 ; CHECK: L1.preheader:
443 ; CHECK-NEXT: br label [[EXIT:%.*]]
445 ; CHECK-NEXT: ret i64 42
447 ; CHECK-NEXT: [[Y_PHI:%.*]] = phi i64 [ undef, [[L1_PREHEADER]] ]
448 ; CHECK-NEXT: ret i64 [[Y_PHI]]
450 ; REMARKS-LABEL: Function: test12
451 ; REMARKS: Loop deleted because it never executes
454 br i1 true, label %exit1, label %L1
459 L1: ; preds = %L1Latch, %entry
460 %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
461 br i1 true, label %L1Latch, label %exit
463 L1Latch: ; preds = %L1
464 %y = phi i64 [ %y.next, %L1 ]
465 %y.add = add i64 %y, %n
466 %cond2 = icmp eq i64 %y.add, 42
467 switch i64 %n, label %L1 [
472 exit: ; preds = %L1Latch, %L1Latch
473 %y.phi = phi i64 [ 10, %L1Latch ], [ 10, %L1Latch ], [ %y.next, %L1]
477 ; multiple edges to exit block from the same exiting blocks
478 define i64 @test13(i64 %n) {
479 ; CHECK-LABEL: @test13(
481 ; CHECK-NEXT: br i1 true, label [[EXIT1:%.*]], label [[L1_PREHEADER:%.*]]
482 ; CHECK: L1.preheader:
483 ; CHECK-NEXT: br label [[EXIT:%.*]]
485 ; CHECK-NEXT: ret i64 42
487 ; CHECK-NEXT: [[Y_PHI:%.*]] = phi i64 [ undef, [[L1_PREHEADER]] ]
488 ; CHECK-NEXT: ret i64 [[Y_PHI]]
490 ; REMARKS-LABEL: Function: test13
491 ; REMARKS: Loop deleted because it never executes
494 br i1 true, label %exit1, label %L1
499 L1: ; preds = %L1Latch, %entry
500 %y.next = phi i64 [ 0, %entry ], [ %y.add, %L1Latch ]
501 br i1 true, label %L1Block, label %exit
503 L1Block: ; preds = %L1
504 %y = phi i64 [ %y.next, %L1 ]
505 %y.add = add i64 %y, %n
506 %cond2 = icmp eq i64 %y.add, 42
507 switch i64 %n, label %L1Latch [
513 switch i64 %n, label %L1 [
518 exit: ; preds = %L1Block, %L1, %L1Latch
519 %y.phi = phi i64 [ 10, %L1Block ], [ 10, %L1Block ], [ %y.next, %L1 ], [ 30, %L1Latch ], [ 30, %L1Latch ]