1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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, i32* @G, align 4
12 ; CHECK-NEXT: br i1 false, label [[LOOP_LOOP_CRIT_EDGE:%.*]], label [[EXIT:%.*]]
13 ; CHECK: loop.loop_crit_edge:
14 ; CHECK-NEXT: unreachable
16 ; CHECK-NEXT: ret void
23 br i1 false, label %loop, label %exit
30 define void @test_bottom_tested() {
31 ; CHECK-LABEL: @test_bottom_tested(
33 ; CHECK-NEXT: br label [[LOOP:%.*]]
35 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
36 ; CHECK-NEXT: store i32 0, i32* @G, align 4
37 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
38 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
39 ; CHECK-NEXT: br i1 [[BE_TAKEN]], label [[LOOP_LOOP_CRIT_EDGE:%.*]], label [[EXIT:%.*]]
40 ; CHECK: loop.loop_crit_edge:
41 ; CHECK-NEXT: unreachable
43 ; CHECK-NEXT: ret void
49 %iv = phi i32 [ 0, %entry], [ %iv.inc, %loop ]
51 %iv.inc = add i32 %iv, 1
52 %be_taken = icmp ne i32 %iv.inc, 1
53 br i1 %be_taken, label %loop, label %exit
59 define void @test_early_exit() {
60 ; CHECK-LABEL: @test_early_exit(
62 ; CHECK-NEXT: br label [[LOOP:%.*]]
64 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
65 ; CHECK-NEXT: store i32 0, i32* @G, align 4
66 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
67 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
68 ; CHECK-NEXT: br i1 [[BE_TAKEN]], label [[LATCH:%.*]], label [[EXIT:%.*]]
70 ; CHECK-NEXT: br label [[LATCH_SPLIT:%.*]]
72 ; CHECK-NEXT: unreachable
74 ; CHECK-NEXT: ret void
80 %iv = phi i32 [ 0, %entry], [ %iv.inc, %latch ]
82 %iv.inc = add i32 %iv, 1
83 %be_taken = icmp ne i32 %iv.inc, 1
84 br i1 %be_taken, label %latch, label %exit
92 define void @test_multi_exit1() {
93 ; CHECK-LABEL: @test_multi_exit1(
95 ; CHECK-NEXT: br label [[LOOP:%.*]]
97 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
98 ; CHECK-NEXT: store i32 0, i32* @G, align 4
99 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
100 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
101 ; CHECK-NEXT: br i1 [[BE_TAKEN]], label [[LATCH:%.*]], label [[EXIT:%.*]]
103 ; CHECK-NEXT: store i32 1, i32* @G, align 4
104 ; CHECK-NEXT: [[COND2:%.*]] = icmp ult i32 [[IV_INC]], 30
105 ; CHECK-NEXT: br i1 [[COND2]], label [[LATCH_LOOP_CRIT_EDGE:%.*]], label [[EXIT]]
106 ; CHECK: latch.loop_crit_edge:
107 ; CHECK-NEXT: unreachable
109 ; CHECK-NEXT: ret void
115 %iv = phi i32 [ 0, %entry], [ %iv.inc, %latch ]
117 %iv.inc = add i32 %iv, 1
118 %be_taken = icmp ne i32 %iv.inc, 1
119 br i1 %be_taken, label %latch, label %exit
122 %cond2 = icmp ult i32 %iv.inc, 30
123 br i1 %cond2, label %loop, label %exit
129 define void @test_multi_exit2() {
130 ; CHECK-LABEL: @test_multi_exit2(
132 ; CHECK-NEXT: br label [[LOOP:%.*]]
134 ; CHECK-NEXT: store i32 0, i32* @G, align 4
135 ; CHECK-NEXT: br i1 true, label [[LATCH:%.*]], label [[EXIT:%.*]]
137 ; CHECK-NEXT: store i32 1, i32* @G, align 4
138 ; CHECK-NEXT: br i1 false, label [[LATCH_LOOP_CRIT_EDGE:%.*]], label [[EXIT]]
139 ; CHECK: latch.loop_crit_edge:
140 ; CHECK-NEXT: unreachable
142 ; CHECK-NEXT: ret void
149 br i1 true, label %latch, label %exit
152 br i1 false, label %loop, label %exit
158 define void @test_multi_exit3(i1 %cond1) {
159 ; CHECK-LABEL: @test_multi_exit3(
161 ; CHECK-NEXT: br label [[LOOP:%.*]]
163 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ]
164 ; CHECK-NEXT: store i32 0, i32* @G, align 4
165 ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LATCH:%.*]], label [[EXIT:%.*]]
167 ; CHECK-NEXT: store i32 1, i32* @G, align 4
168 ; CHECK-NEXT: [[IV_INC:%.*]] = add i32 [[IV]], 1
169 ; CHECK-NEXT: [[BE_TAKEN:%.*]] = icmp ne i32 [[IV_INC]], 1
170 ; CHECK-NEXT: br i1 [[BE_TAKEN]], label [[LATCH_LOOP_CRIT_EDGE:%.*]], label [[EXIT]]
171 ; CHECK: latch.loop_crit_edge:
172 ; CHECK-NEXT: unreachable
174 ; CHECK-NEXT: ret void
180 %iv = phi i32 [ 0, %entry], [ %iv.inc, %latch ]
182 br i1 %cond1, label %latch, label %exit
185 %iv.inc = add i32 %iv, 1
186 %be_taken = icmp ne i32 %iv.inc, 1
187 br i1 %be_taken, label %loop, label %exit
193 ; Subtle - This is either zero btc, or infinite, thus, can't break
195 define void @test_multi_exit4(i1 %cond1, i1 %cond2) {
196 ; CHECK-LABEL: @test_multi_exit4(
198 ; CHECK-NEXT: br label [[LOOP:%.*]]
200 ; CHECK-NEXT: store i32 0, i32* @G, align 4
201 ; CHECK-NEXT: br i1 [[COND1:%.*]], label [[LATCH:%.*]], label [[EXIT:%.*]]
203 ; CHECK-NEXT: store i32 1, i32* @G, align 4
204 ; CHECK-NEXT: br i1 [[COND2:%.*]], label [[LOOP]], label [[EXIT]]
206 ; CHECK-NEXT: ret void
213 br i1 %cond1, label %latch, label %exit
216 br i1 %cond2, label %loop, label %exit
222 ; A simple case with multiple exit blocks
223 define void @test_multi_exit5() {
224 ; CHECK-LABEL: @test_multi_exit5(
226 ; CHECK-NEXT: br label [[LOOP:%.*]]
228 ; CHECK-NEXT: store i32 0, i32* @G, align 4
229 ; CHECK-NEXT: br i1 true, label [[LATCH:%.*]], label [[EXIT1:%.*]]
231 ; CHECK-NEXT: store i32 1, i32* @G, align 4
232 ; CHECK-NEXT: br i1 false, label [[LATCH_LOOP_CRIT_EDGE:%.*]], label [[EXIT2:%.*]]
233 ; CHECK: latch.loop_crit_edge:
234 ; CHECK-NEXT: unreachable
236 ; CHECK-NEXT: ret void
238 ; CHECK-NEXT: ret void
245 br i1 true, label %latch, label %exit1
248 br i1 false, label %loop, label %exit2
256 define void @test_live_inner() {
257 ; CHECK-LABEL: @test_live_inner(
259 ; CHECK-NEXT: br label [[LOOP:%.*]]
261 ; CHECK-NEXT: store i32 0, i32* @G, align 4
262 ; CHECK-NEXT: br label [[INNER:%.*]]
264 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[LOOP]] ], [ [[IV_INC:%.*]], [[INNER]] ]
265 ; CHECK-NEXT: store i32 [[IV]], i32* @G, align 4
266 ; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1
267 ; CHECK-NEXT: [[CND:%.*]] = icmp ult i32 [[IV_INC]], 200
268 ; CHECK-NEXT: br i1 [[CND]], label [[INNER]], label [[LATCH:%.*]]
270 ; CHECK-NEXT: br i1 false, label [[LATCH_LOOP_CRIT_EDGE:%.*]], label [[EXIT:%.*]]
271 ; CHECK: latch.loop_crit_edge:
272 ; CHECK-NEXT: unreachable
274 ; CHECK-NEXT: ret void
284 %iv = phi i32 [0, %loop], [%iv.inc, %inner]
285 store i32 %iv, i32* @G
286 %iv.inc = add i32 %iv, 1
287 %cnd = icmp ult i32 %iv.inc, 200
288 br i1 %cnd, label %inner, label %latch
291 br i1 false, label %loop, label %exit
297 define void @test_live_outer() {
298 ; CHECK-LABEL: @test_live_outer(
300 ; CHECK-NEXT: br label [[LOOP:%.*]]
302 ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[LATCH:%.*]] ]
303 ; CHECK-NEXT: br label [[INNER:%.*]]
305 ; CHECK-NEXT: store i32 0, i32* @G, align 4
306 ; CHECK-NEXT: br i1 false, label [[INNER_INNER_CRIT_EDGE:%.*]], label [[LATCH]]
307 ; CHECK: inner.inner_crit_edge:
308 ; CHECK-NEXT: unreachable
310 ; CHECK-NEXT: store i32 [[IV]], i32* @G, align 4
311 ; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1
312 ; CHECK-NEXT: [[CND:%.*]] = icmp ult i32 [[IV_INC]], 200
313 ; CHECK-NEXT: br i1 [[CND]], label [[LOOP]], label [[EXIT:%.*]]
315 ; CHECK-NEXT: ret void
321 %iv = phi i32 [0, %entry], [%iv.inc, %latch]
326 br i1 false, label %inner, label %latch
329 store i32 %iv, i32* @G
330 %iv.inc = add i32 %iv, 1
331 %cnd = icmp ult i32 %iv.inc, 200
332 br i1 %cnd, label %loop, label %exit
338 ; Key point is that inner_latch drops out of the outer loop when
339 ; the inner loop is deleted, and thus the lcssa phi needs to be
340 ; in the inner_latch block to preserve LCSSA. We either have to
341 ; insert the LCSSA phi, or not break the inner backedge.
342 define void @loop_nest_lcssa() {
343 ; CHECK-LABEL: @loop_nest_lcssa(
345 ; CHECK-NEXT: [[TMP0:%.*]] = add i32 1, 2
346 ; CHECK-NEXT: br label [[OUTER_HEADER:%.*]]
347 ; CHECK: outer_header:
348 ; CHECK-NEXT: br label [[INNER_HEADER:%.*]]
349 ; CHECK: inner_header:
350 ; CHECK-NEXT: br i1 false, label [[INNER_LATCH:%.*]], label [[OUTER_LATCH:%.*]]
351 ; CHECK: inner_latch:
352 ; CHECK-NEXT: [[DOTLCSSA:%.*]] = phi i32 [ [[TMP0]], [[INNER_HEADER]] ]
353 ; CHECK-NEXT: br i1 false, label [[INNER_LATCH_INNER_HEADER_CRIT_EDGE:%.*]], label [[LOOPEXIT:%.*]]
354 ; CHECK: inner_latch.inner_header_crit_edge:
355 ; CHECK-NEXT: unreachable
356 ; CHECK: outer_latch:
357 ; CHECK-NEXT: br label [[OUTER_HEADER]]
359 ; CHECK-NEXT: [[DOTLCSSA32:%.*]] = phi i32 [ [[DOTLCSSA]], [[INNER_LATCH]] ]
360 ; CHECK-NEXT: unreachable
363 br label %outer_header
367 br label %inner_header
370 br i1 false, label %inner_latch, label %outer_latch
373 br i1 false, label %inner_header, label %loopexit
376 br label %outer_header
379 %.lcssa32 = phi i32 [ %0, %inner_latch ]