1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=loop-deletion -S | FileCheck %s
4 @G = external global i32
6 define void @test_trivial() {
7 ; CHECK-LABEL: @test_trivial(
9 ; CHECK-NEXT: br label [[LOOP:%.*]]
11 ; CHECK-NEXT: store i32 0, ptr @G, align 4
12 ; CHECK-NEXT: br label [[EXIT:%.*]]
14 ; CHECK-NEXT: ret void
21 br i1 false, label %loop, label %exit
28 define void @test_bottom_tested() {
29 ; CHECK-LABEL: @test_bottom_tested(
31 ; CHECK-NEXT: br label [[LOOP:%.*]]
33 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
34 ; CHECK-NEXT: store i32 0, ptr @G, align 4
35 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
36 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
37 ; CHECK-NEXT: br label [[EXIT:%.*]]
39 ; CHECK-NEXT: ret void
45 %iv = phi i32 [ 0, %entry], [ %iv.inc, %loop ]
47 %iv.inc = add i32 %iv, 1
48 %be_taken = icmp ne i32 %iv.inc, 1
49 br i1 %be_taken, label %loop, label %exit
55 define void @test_early_exit() {
56 ; CHECK-LABEL: @test_early_exit(
58 ; CHECK-NEXT: br label [[LOOP:%.*]]
60 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
61 ; CHECK-NEXT: store i32 0, ptr @G, align 4
62 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
63 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
64 ; CHECK-NEXT: br i1 [[BE_TAKEN]], label [[LATCH:%.*]], label [[EXIT:%.*]]
66 ; CHECK-NEXT: unreachable
68 ; CHECK-NEXT: ret void
74 %iv = phi i32 [ 0, %entry], [ %iv.inc, %latch ]
76 %iv.inc = add i32 %iv, 1
77 %be_taken = icmp ne i32 %iv.inc, 1
78 br i1 %be_taken, label %latch, label %exit
86 define void @test_multi_exit1() {
87 ; CHECK-LABEL: @test_multi_exit1(
89 ; CHECK-NEXT: br label [[LOOP:%.*]]
91 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
92 ; CHECK-NEXT: store i32 0, ptr @G, align 4
93 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
94 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
95 ; CHECK-NEXT: br i1 [[BE_TAKEN]], label [[LATCH:%.*]], label [[EXIT:%.*]]
97 ; CHECK-NEXT: store i32 1, ptr @G, align 4
98 ; CHECK-NEXT: [[COND2:%.*]] = icmp ult i32 [[IV_INC]], 30
99 ; CHECK-NEXT: br label [[EXIT]]
101 ; CHECK-NEXT: ret void
107 %iv = phi i32 [ 0, %entry], [ %iv.inc, %latch ]
109 %iv.inc = add i32 %iv, 1
110 %be_taken = icmp ne i32 %iv.inc, 1
111 br i1 %be_taken, label %latch, label %exit
114 %cond2 = icmp ult i32 %iv.inc, 30
115 br i1 %cond2, label %loop, label %exit
121 define void @test_multi_exit2() {
122 ; CHECK-LABEL: @test_multi_exit2(
124 ; CHECK-NEXT: br label [[LOOP:%.*]]
126 ; CHECK-NEXT: store i32 0, ptr @G, align 4
127 ; CHECK-NEXT: br i1 true, label [[LATCH:%.*]], label [[EXIT:%.*]]
129 ; CHECK-NEXT: store i32 1, ptr @G, align 4
130 ; CHECK-NEXT: br label [[EXIT]]
132 ; CHECK-NEXT: ret void
139 br i1 true, label %latch, label %exit
142 br i1 false, label %loop, label %exit
148 define void @test_multi_exit3(i1 %cond1) {
149 ; CHECK-LABEL: @test_multi_exit3(
151 ; CHECK-NEXT: br label [[LOOP:%.*]]
153 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
154 ; CHECK-NEXT: store i32 0, ptr @G, align 4
155 ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LATCH:%.*]], label [[EXIT:%.*]]
157 ; CHECK-NEXT: store i32 1, ptr @G, align 4
158 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
159 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
160 ; CHECK-NEXT: br label [[EXIT]]
162 ; CHECK-NEXT: ret void
168 %iv = phi i32 [ 0, %entry], [ %iv.inc, %latch ]
170 br i1 %cond1, label %latch, label %exit
173 %iv.inc = add i32 %iv, 1
174 %be_taken = icmp ne i32 %iv.inc, 1
175 br i1 %be_taken, label %loop, label %exit
181 ; Subtle - This is either zero btc, or infinite, thus, can't break
183 define void @test_multi_exit4(i1 %cond1, i1 %cond2) {
184 ; CHECK-LABEL: @test_multi_exit4(
186 ; CHECK-NEXT: br label [[LOOP:%.*]]
188 ; CHECK-NEXT: store i32 0, ptr @G, align 4
189 ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LATCH:%.*]], label [[EXIT:%.*]]
191 ; CHECK-NEXT: store i32 1, ptr @G, align 4
192 ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]]
194 ; CHECK-NEXT: ret void
201 br i1 %cond1, label %latch, label %exit
204 br i1 %cond2, label %loop, label %exit
210 ; A simple case with multiple exit blocks
211 define void @test_multi_exit5() {
212 ; CHECK-LABEL: @test_multi_exit5(
214 ; CHECK-NEXT: br label [[LOOP:%.*]]
216 ; CHECK-NEXT: store i32 0, ptr @G, align 4
217 ; CHECK-NEXT: br i1 true, label [[LATCH:%.*]], label [[EXIT1:%.*]]
219 ; CHECK-NEXT: store i32 1, ptr @G, align 4
220 ; CHECK-NEXT: br label [[EXIT2:%.*]]
222 ; CHECK-NEXT: ret void
224 ; CHECK-NEXT: ret void
231 br i1 true, label %latch, label %exit1
234 br i1 false, label %loop, label %exit2
242 declare i1 @unknown()
244 ; We can't compute an exit count for the latch, but we know the upper
245 ; bound on the trip count is zero anyways.
246 define void @test_dead_latch1() {
247 ; CHECK-LABEL: @test_dead_latch1(
249 ; CHECK-NEXT: br label [[LOOP:%.*]]
251 ; CHECK-NEXT: store i32 0, ptr @G, align 4
252 ; CHECK-NEXT: br i1 false, label [[LATCH:%.*]], label [[EXIT1:%.*]]
254 ; CHECK-NEXT: [[LATCHCOND:%.*]] = call i1 @unknown()
255 ; CHECK-NEXT: br label [[EXIT2:%.*]]
257 ; CHECK-NEXT: ret void
259 ; CHECK-NEXT: ret void
266 br i1 false, label %latch, label %exit1
268 %latchcond = call i1 @unknown()
269 br i1 %latchcond, label %loop, label %exit2
278 define void @test_live_inner() {
279 ; CHECK-LABEL: @test_live_inner(
281 ; CHECK-NEXT: br label [[LOOP:%.*]]
283 ; CHECK-NEXT: store i32 0, ptr @G, align 4
284 ; CHECK-NEXT: br label [[INNER:%.*]]
286 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP]] ], [ [[IV_INC:%.*]], [[INNER]] ]
287 ; CHECK-NEXT: store i32 [[IV]], ptr @G, align 4
288 ; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1
289 ; CHECK-NEXT: [[CND:%.*]] = icmp ult i32 [[IV_INC]], 200
290 ; CHECK-NEXT: br i1 [[CND]], label [[INNER]], label [[LATCH:%.*]]
292 ; CHECK-NEXT: br label [[EXIT:%.*]]
294 ; CHECK-NEXT: ret void
304 %iv = phi i32 [0, %loop], [%iv.inc, %inner]
305 store i32 %iv, ptr @G
306 %iv.inc = add i32 %iv, 1
307 %cnd = icmp ult i32 %iv.inc, 200
308 br i1 %cnd, label %inner, label %latch
311 br i1 false, label %loop, label %exit
317 define void @test_live_outer() {
318 ; CHECK-LABEL: @test_live_outer(
320 ; CHECK-NEXT: br label [[LOOP:%.*]]
322 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LATCH:%.*]] ]
323 ; CHECK-NEXT: br label [[INNER:%.*]]
325 ; CHECK-NEXT: store i32 0, ptr @G, align 4
326 ; CHECK-NEXT: br label [[LATCH]]
328 ; CHECK-NEXT: store i32 [[IV]], ptr @G, align 4
329 ; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1
330 ; CHECK-NEXT: [[CND:%.*]] = icmp ult i32 [[IV_INC]], 200
331 ; CHECK-NEXT: br i1 [[CND]], label [[LOOP]], label [[EXIT:%.*]]
333 ; CHECK-NEXT: ret void
339 %iv = phi i32 [0, %entry], [%iv.inc, %latch]
344 br i1 false, label %inner, label %latch
347 store i32 %iv, ptr @G
348 %iv.inc = add i32 %iv, 1
349 %cnd = icmp ult i32 %iv.inc, 200
350 br i1 %cnd, label %loop, label %exit
356 ; Key point is that inner_latch drops out of the outer loop when
357 ; the inner loop is deleted, and thus the lcssa phi needs to be
358 ; in the inner_latch block to preserve LCSSA. We either have to
359 ; insert the LCSSA phi, or not break the inner backedge.
360 define void @loop_nest_lcssa() {
361 ; CHECK-LABEL: @loop_nest_lcssa(
363 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 1, 2
364 ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
365 ; CHECK: outer_header:
366 ; CHECK-NEXT: br label [[INNER_HEADER:%.*]]
367 ; CHECK: inner_header:
368 ; CHECK-NEXT: br i1 false, label [[INNER_LATCH:%.*]], label [[OUTER_LATCH:%.*]]
369 ; CHECK: inner_latch:
370 ; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i32 [ [[TMP0]], [[INNER_HEADER]] ]
371 ; CHECK-NEXT: br label [[LOOPEXIT:%.*]]
372 ; CHECK: outer_latch:
373 ; CHECK-NEXT: br label [[OUTER_HEADER]]
375 ; CHECK-NEXT: [[DOTLCSSA32:%.*]] = phi i32 [ [[DOTLCSSA]], [[INNER_LATCH]] ]
376 ; CHECK-NEXT: unreachable
379 br label %outer_header
383 br label %inner_header
386 br i1 false, label %inner_latch, label %outer_latch
389 br i1 false, label %inner_header, label %loopexit
392 br label %outer_header
395 %.lcssa32 = phi i32 [ %0, %inner_latch ]