1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; XFAIL: *
3; Tests complex_dead_subloop_branch and complex_dead_subloop_switch fail an
4; assertion, therefore the CFG simplification is temporarily disabled.
5; REQUIRES: asserts
6; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
7; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -passes='require<domtree>,loop(simplify-cfg)' -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
8; RUN: opt -S -enable-loop-simplifycfg-term-folding=true -loop-simplifycfg -enable-mssa-loop-dependency=true -verify-memoryssa -debug-only=loop-simplifycfg -verify-loop-info -verify-dom-info -verify-loop-lcssa 2>&1 < %s | FileCheck %s
9
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
11
12; Make sure that we can eliminate a provably dead backedge.
13define i32 @dead_backedge_test_branch_loop(i32 %end) {
14; CHECK-LABEL: @dead_backedge_test_branch_loop(
15; CHECK-NEXT:  preheader:
16; CHECK-NEXT:    br label [[HEADER:%.*]]
17; CHECK:       header:
18; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ]
19; CHECK-NEXT:    [[I_1:%.*]] = add i32 [[I]], 1
20; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100
21; CHECK-NEXT:    br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]]
22; CHECK:       header.backedge:
23; CHECK-NEXT:    [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ]
24; CHECK-NEXT:    br label [[HEADER]]
25; CHECK:       dead_backedge:
26; CHECK-NEXT:    [[I_2]] = add i32 [[I_1]], 10
27; CHECK-NEXT:    br i1 false, label [[HEADER_BACKEDGE]], label [[EXIT:%.*]]
28; CHECK:       exit:
29; CHECK-NEXT:    [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ]
30; CHECK-NEXT:    ret i32 [[I_2_LCSSA]]
31;
32preheader:
33  br label %header
34
35header:
36  %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge]
37  %i.1 = add i32 %i, 1
38  %cmp1 = icmp slt i32 %i.1, 100
39  br i1 %cmp1, label %header, label %dead_backedge
40
41dead_backedge:
42  %i.2 = add i32 %i.1, 10
43  br i1 false, label %header, label %exit
44
45exit:
46  ret i32 %i.2
47}
48
49; Make sure that we can eliminate a provably dead backedge with switch.
50define i32 @dead_backedge_test_switch_loop(i32 %end) {
51; CHECK-LABEL: @dead_backedge_test_switch_loop(
52; CHECK-NEXT:  preheader:
53; CHECK-NEXT:    br label [[HEADER:%.*]]
54; CHECK:       header:
55; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_BE:%.*]], [[HEADER_BACKEDGE:%.*]] ]
56; CHECK-NEXT:    [[I_1:%.*]] = add i32 [[I]], 1
57; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[I_1]], 100
58; CHECK-NEXT:    br i1 [[CMP1]], label [[HEADER_BACKEDGE]], label [[DEAD_BACKEDGE:%.*]]
59; CHECK:       header.backedge:
60; CHECK-NEXT:    [[I_BE]] = phi i32 [ [[I_1]], [[HEADER]] ], [ [[I_2:%.*]], [[DEAD_BACKEDGE]] ]
61; CHECK-NEXT:    br label [[HEADER]]
62; CHECK:       dead_backedge:
63; CHECK-NEXT:    [[I_2]] = add i32 [[I_1]], 10
64; CHECK-NEXT:    switch i32 1, label [[EXIT:%.*]] [
65; CHECK-NEXT:    i32 0, label [[HEADER_BACKEDGE]]
66; CHECK-NEXT:    ]
67; CHECK:       exit:
68; CHECK-NEXT:    [[I_2_LCSSA:%.*]] = phi i32 [ [[I_2]], [[DEAD_BACKEDGE]] ]
69; CHECK-NEXT:    ret i32 [[I_2_LCSSA]]
70;
71preheader:
72  br label %header
73
74header:
75  %i = phi i32 [0, %preheader], [%i.1, %header], [%i.2, %dead_backedge]
76  %i.1 = add i32 %i, 1
77  %cmp1 = icmp slt i32 %i.1, 100
78  br i1 %cmp1, label %header, label %dead_backedge
79
80dead_backedge:
81  %i.2 = add i32 %i.1, 10
82  switch i32 1, label %exit [i32 0, label %header]
83
84exit:
85  ret i32 %i.2
86}
87
88; Check that we can eliminate a triangle.
89define i32 @dead_block_test_branch_loop(i32 %end) {
90; CHECK-LABEL: @dead_block_test_branch_loop(
91; CHECK-NEXT:  preheader:
92; CHECK-NEXT:    br label [[HEADER:%.*]]
93; CHECK:       header:
94; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ]
95; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
96; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
97; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
98; CHECK:       exit:
99; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
100; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
101;
102preheader:
103  br label %header
104
105header:
106  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
107  br i1 true, label %backedge, label %dead
108
109dead:
110  %i.2 = add i32 %i, 1
111  br label %backedge
112
113backedge:
114  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
115  %i.inc = add i32 %i.1, 1
116  %cmp = icmp slt i32 %i.inc, %end
117  br i1 %cmp, label %header, label %exit
118
119exit:
120  ret i32 %i.inc
121}
122
123; Check that we can eliminate dead branches of a switch.
124define i32 @dead_block_test_switch_loop(i32 %end) {
125; CHECK-LABEL: @dead_block_test_switch_loop(
126; CHECK-NEXT:  preheader:
127; CHECK-NEXT:    br label [[HEADER:%.*]]
128; CHECK:       header:
129; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ]
130; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
131; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
132; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
133; CHECK:       exit:
134; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
135; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
136;
137preheader:
138  br label %header
139
140header:
141  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
142  switch i32 1, label %dead [i32 0, label %dead
143  i32 1, label %backedge
144  i32 2, label %dead]
145
146dead:
147  %i.2 = add i32 %i, 1
148  br label %backedge
149
150backedge:
151  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
152  %i.inc = add i32 %i.1, 1
153  %cmp = icmp slt i32 %i.inc, %end
154  br i1 %cmp, label %header, label %exit
155exit:
156  ret i32 %i.inc
157}
158
159; Check that we can eliminate several dead blocks.
160define i32 @dead_block_propogate_test_branch_loop(i32 %end) {
161; CHECK-LABEL: @dead_block_propogate_test_branch_loop(
162; CHECK-NEXT:  preheader:
163; CHECK-NEXT:    br label [[HEADER:%.*]]
164; CHECK:       header:
165; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ]
166; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
167; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
168; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
169; CHECK:       exit:
170; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
171; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
172;
173preheader:
174  br label %header
175
176header:
177  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
178  br i1 true, label %backedge, label %dead
179
180dead:
181  %i.2 = add i32 %i, 1
182  br label %dummy
183
184dummy:
185  br label %backedge
186
187backedge:
188  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
189  %i.inc = add i32 %i.1, 1
190  %cmp = icmp slt i32 %i.inc, %end
191  br i1 %cmp, label %header, label %exit
192
193exit:
194  ret i32 %i.inc
195}
196
197; Check that we can eliminate several blocks while removing a switch.
198define i32 @dead_block_propogate_test_switch_loop(i32 %end) {
199; CHECK-LABEL: @dead_block_propogate_test_switch_loop(
200; CHECK-NEXT:  preheader:
201; CHECK-NEXT:    br label [[HEADER:%.*]]
202; CHECK:       header:
203; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[HEADER]] ]
204; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
205; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
206; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
207; CHECK:       exit:
208; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
209; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
210;
211preheader:
212  br label %header
213
214header:
215  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
216  switch i32 1, label %dead [i32 0, label %dead
217  i32 1, label %backedge
218  i32 2, label %dead]
219
220dead:
221  %i.2 = add i32 %i, 1
222  br label %dummy
223
224dummy:
225  br label %backedge
226
227backedge:
228  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
229  %i.inc = add i32 %i.1, 1
230  %cmp = icmp slt i32 %i.inc, %end
231  br i1 %cmp, label %header, label %exit
232
233exit:
234  ret i32 %i.inc
235}
236
237; Check that we preserve static reachibility of a dead exit block while deleting
238; a branch.
239define i32 @dead_exit_test_branch_loop(i32 %end) {
240; CHECK-LABEL: @dead_exit_test_branch_loop(
241; CHECK-NEXT:  preheader:
242; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
243; CHECK-NEXT:    i32 1, label [[DEAD:%.*]]
244; CHECK-NEXT:    ]
245; CHECK:       preheader-split:
246; CHECK-NEXT:    br label [[HEADER:%.*]]
247; CHECK:       header:
248; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
249; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
250; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
251; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]]
252; CHECK:       dead:
253; CHECK-NEXT:    br label [[DUMMY:%.*]]
254; CHECK:       dummy:
255; CHECK-NEXT:    br label [[EXIT:%.*]]
256; CHECK:       exit.loopexit:
257; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
258; CHECK-NEXT:    br label [[EXIT]]
259; CHECK:       exit:
260; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ undef, [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ]
261; CHECK-NEXT:    ret i32 [[I_1]]
262;
263preheader:
264  br label %header
265
266header:
267  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
268  br i1 true, label %backedge, label %dead
269
270dead:
271  br label %dummy
272
273dummy:
274  br label %exit
275
276backedge:
277  %i.inc = add i32 %i, 1
278  %cmp = icmp slt i32 %i.inc, %end
279  br i1 %cmp, label %header, label %exit
280
281exit:
282  %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
283  ret i32 %i.1
284}
285
286; Check that we preserve static reachibility of a dead exit block while deleting
287; a switch.
288define i32 @dead_exit_test_switch_loop(i32 %end) {
289; CHECK-LABEL: @dead_exit_test_switch_loop(
290; CHECK-NEXT:  preheader:
291; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
292; CHECK-NEXT:    i32 1, label [[DEAD:%.*]]
293; CHECK-NEXT:    i32 2, label [[DEAD]]
294; CHECK-NEXT:    i32 3, label [[DEAD]]
295; CHECK-NEXT:    ]
296; CHECK:       preheader-split:
297; CHECK-NEXT:    br label [[HEADER:%.*]]
298; CHECK:       header:
299; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
300; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
301; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
302; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT_LOOPEXIT:%.*]]
303; CHECK:       dead:
304; CHECK-NEXT:    br label [[DUMMY:%.*]]
305; CHECK:       dummy:
306; CHECK-NEXT:    br label [[EXIT:%.*]]
307; CHECK:       exit.loopexit:
308; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
309; CHECK-NEXT:    br label [[EXIT]]
310; CHECK:       exit:
311; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ undef, [[DUMMY]] ], [ [[I_INC_LCSSA]], [[EXIT_LOOPEXIT]] ]
312; CHECK-NEXT:    ret i32 [[I_1]]
313;
314preheader:
315  br label %header
316
317header:
318  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
319  switch i32 1, label %dead [i32 0, label %dead
320  i32 1, label %backedge
321  i32 2, label %dead]
322
323dead:
324  br label %dummy
325
326dummy:
327  br label %exit
328
329backedge:
330  %i.inc = add i32 %i, 1
331  %cmp = icmp slt i32 %i.inc, %end
332  br i1 %cmp, label %header, label %exit
333
334exit:
335  %i.1 = phi i32 [%i.inc, %backedge], [%i, %dummy]
336  ret i32 %i.1
337}
338
339; Check that we can completely eliminate the current loop, branch case.
340define i32 @dead_loop_test_branch_loop(i32 %end) {
341; CHECK-LABEL: @dead_loop_test_branch_loop(
342; CHECK-NEXT:  preheader:
343; CHECK-NEXT:    br label [[HEADER:%.*]]
344; CHECK:       header:
345; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
346; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
347; CHECK:       dead:
348; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
349; CHECK-NEXT:    br label [[BACKEDGE]]
350; CHECK:       backedge:
351; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
352; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
353; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
354; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[EXIT:%.*]]
355; CHECK:       exit:
356; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
357; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
358;
359preheader:
360  br label %header
361
362header:
363  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
364  br i1 true, label %backedge, label %dead
365
366dead:
367  %i.2 = add i32 %i, 1
368  br label %dummy
369
370dummy:
371  br label %backedge
372
373backedge:
374  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
375  %i.inc = add i32 %i.1, 1
376  %cmp = icmp slt i32 %i.inc, %end
377  br i1 false, label %header, label %exit
378
379exit:
380  ret i32 %i.inc
381}
382
383; Check that we can completely eliminate the current loop, switch case.
384define i32 @dead_loop_test_switch_loop(i32 %end) {
385; CHECK-LABEL: @dead_loop_test_switch_loop(
386; CHECK-NEXT:  preheader:
387; CHECK-NEXT:    br label [[HEADER:%.*]]
388; CHECK:       header:
389; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
390; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
391; CHECK-NEXT:    i32 0, label [[DEAD]]
392; CHECK-NEXT:    i32 1, label [[BACKEDGE]]
393; CHECK-NEXT:    i32 2, label [[DEAD]]
394; CHECK-NEXT:    ]
395; CHECK:       dead:
396; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
397; CHECK-NEXT:    br label [[BACKEDGE]]
398; CHECK:       backedge:
399; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
400; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
401; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
402; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[EXIT:%.*]]
403; CHECK:       exit:
404; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
405; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
406;
407preheader:
408  br label %header
409header:
410  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
411  switch i32 1, label %dead [i32 0, label %dead
412  i32 1, label %backedge
413  i32 2, label %dead]
414dead:
415  %i.2 = add i32 %i, 1
416  br label %dummy
417
418dummy:
419  br label %backedge
420
421backedge:
422  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
423  %i.inc = add i32 %i.1, 1
424  %cmp = icmp slt i32 %i.inc, %end
425  br i1 false, label %header, label %exit
426
427exit:
428  ret i32 %i.inc
429}
430
431; Check that we can delete a dead inner loop entirely.
432define i32 @dead_sub_loop_test_branch_loop(i32 %end) {
433; CHECK-LABEL: @dead_sub_loop_test_branch_loop(
434; CHECK-NEXT:  preheader:
435; CHECK-NEXT:    br label [[HEADER:%.*]]
436; CHECK:       header:
437; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[EXIT_A:%.*]] ]
438; CHECK-NEXT:    br label [[LIVE_LOOP:%.*]]
439; CHECK:       live_loop:
440; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ]
441; CHECK-NEXT:    [[A_INC]] = add i32 [[A]], 1
442; CHECK-NEXT:    [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]]
443; CHECK-NEXT:    br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A]]
444; CHECK:       exit.a:
445; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
446; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
447; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
448; CHECK:       exit:
449; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[EXIT_A]] ]
450; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
451;
452preheader:
453  br label %header
454
455header:
456  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
457  br i1 true, label %live_preheader, label %dead_preheader
458
459live_preheader:
460  br label %live_loop
461
462live_loop:
463  %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop]
464  %a.inc = add i32 %a, 1
465  %cmp.a = icmp slt i32 %a.inc, %end
466  br i1 %cmp.a, label %live_loop, label %exit.a
467
468exit.a:
469  br label %backedge
470
471dead_preheader:
472  br label %dead_loop
473
474dead_loop:
475  %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop]
476  %b.inc = add i32 %b, 1
477  %cmp.b = icmp slt i32 %b.inc, %end
478  br i1 %cmp.b, label %dead_loop, label %exit.b
479
480exit.b:
481  br label %backedge
482
483backedge:
484  %i.inc = add i32 %i, 1
485  %cmp = icmp slt i32 %i.inc, %end
486  br i1 %cmp, label %header, label %exit
487
488exit:
489  ret i32 %i.inc
490}
491
492define i32 @dead_sub_loop_test_switch_loop(i32 %end) {
493; CHECK-LABEL: @dead_sub_loop_test_switch_loop(
494; CHECK-NEXT:  preheader:
495; CHECK-NEXT:    br label [[HEADER:%.*]]
496; CHECK:       header:
497; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[EXIT_A:%.*]] ]
498; CHECK-NEXT:    br label [[LIVE_LOOP:%.*]]
499; CHECK:       live_loop:
500; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[HEADER]] ], [ [[A_INC:%.*]], [[LIVE_LOOP]] ]
501; CHECK-NEXT:    [[A_INC]] = add i32 [[A]], 1
502; CHECK-NEXT:    [[CMP_A:%.*]] = icmp slt i32 [[A_INC]], [[END:%.*]]
503; CHECK-NEXT:    br i1 [[CMP_A]], label [[LIVE_LOOP]], label [[EXIT_A]]
504; CHECK:       exit.a:
505; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
506; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END]]
507; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
508; CHECK:       exit:
509; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[EXIT_A]] ]
510; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
511;
512preheader:
513  br label %header
514
515header:
516  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
517  switch i32 1, label %dead_preheader [i32 0, label %dead_preheader
518  i32 1, label %live_preheader
519  i32 2, label %dead_preheader]
520
521live_preheader:
522  br label %live_loop
523
524live_loop:
525  %a = phi i32 [0, %live_preheader], [%a.inc, %live_loop]
526  %a.inc = add i32 %a, 1
527  %cmp.a = icmp slt i32 %a.inc, %end
528  br i1 %cmp.a, label %live_loop, label %exit.a
529
530exit.a:
531  br label %backedge
532
533dead_preheader:
534  br label %dead_loop
535
536dead_loop:
537  %b = phi i32 [0, %dead_preheader], [%b.inc, %dead_loop]
538  %b.inc = add i32 %b, 1
539  %cmp.b = icmp slt i32 %b.inc, %end
540  br i1 %cmp.b, label %dead_loop, label %exit.b
541
542exit.b:
543  br label %backedge
544
545backedge:
546  %i.inc = add i32 %i, 1
547  %cmp = icmp slt i32 %i.inc, %end
548  br i1 %cmp, label %header, label %exit
549
550exit:
551  ret i32 %i.inc
552}
553
554; Check that we preserve static reachability of an exit block even if we prove
555; that the loop is infinite. Branch case.
556define i32 @inf_loop_test_branch_loop(i32 %end) {
557; CHECK-LABEL: @inf_loop_test_branch_loop(
558; CHECK-NEXT:  preheader:
559; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
560; CHECK-NEXT:    i32 1, label [[EXIT:%.*]]
561; CHECK-NEXT:    ]
562; CHECK:       preheader-split:
563; CHECK-NEXT:    br label [[HEADER:%.*]]
564; CHECK:       header:
565; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
566; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
567; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
568; CHECK-NEXT:    br label [[HEADER]]
569; CHECK:       exit:
570; CHECK-NEXT:    ret i32 undef
571;
572preheader:
573  br label %header
574
575header:
576  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
577  br i1 true, label %backedge, label %dead
578
579dead:
580  %i.2 = add i32 %i, 1
581  br label %dummy
582
583dummy:
584  br label %backedge
585
586backedge:
587  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
588  %i.inc = add i32 %i.1, 1
589  %cmp = icmp slt i32 %i.inc, %end
590  br i1 true, label %header, label %exit
591
592exit:
593  ret i32 %i.inc
594}
595
596define i32 @inf_loop_test_switch_loop(i32 %end) {
597; CHECK-LABEL: @inf_loop_test_switch_loop(
598; CHECK-NEXT:  preheader:
599; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
600; CHECK-NEXT:    i32 1, label [[EXIT:%.*]]
601; CHECK-NEXT:    ]
602; CHECK:       preheader-split:
603; CHECK-NEXT:    br label [[HEADER:%.*]]
604; CHECK:       header:
605; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
606; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
607; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
608; CHECK-NEXT:    br label [[HEADER]]
609; CHECK:       exit:
610; CHECK-NEXT:    ret i32 undef
611;
612preheader:
613  br label %header
614header:
615  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
616  switch i32 1, label %dead [i32 0, label %dead
617  i32 1, label %backedge
618  i32 2, label %dead]
619dead:
620  %i.2 = add i32 %i, 1
621  br label %dummy
622dummy:
623  br label %backedge
624backedge:
625  %i.1 = phi i32 [%i, %header], [%i.2, %dummy]
626  %i.inc = add i32 %i.1, 1
627  %cmp = icmp slt i32 %i.inc, %end
628  br i1 true, label %header, label %exit
629exit:
630  ret i32 %i.inc
631}
632
633; Check that when the block is not actually dead, we don't remove it.
634define i32 @live_block_test_branch_loop(i1 %c, i32 %end) {
635; CHECK-LABEL: @live_block_test_branch_loop(
636; CHECK-NEXT:  preheader:
637; CHECK-NEXT:    br label [[HEADER:%.*]]
638; CHECK:       header:
639; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
640; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
641; CHECK:       check:
642; CHECK-NEXT:    br label [[BACKEDGE]]
643; CHECK:       live:
644; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
645; CHECK-NEXT:    br label [[BACKEDGE]]
646; CHECK:       backedge:
647; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ]
648; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
649; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
650; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
651; CHECK:       exit:
652; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
653; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
654;
655preheader:
656  br label %header
657
658header:
659  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
660  br i1 %c, label %check, label %live
661
662check:
663  br i1 true, label %backedge, label %live
664
665live:
666  %i.2 = add i32 %i, 1
667  br label %backedge
668
669backedge:
670  %i.1 = phi i32 [%i, %check], [%i.2, %live]
671  %i.inc = add i32 %i.1, 1
672  %cmp = icmp slt i32 %i.inc, %end
673  br i1 %cmp, label %header, label %exit
674
675exit:
676  ret i32 %i.inc
677}
678
679; Check that when the block is not actually dead, we don't remove it. Version
680; with Phi node.
681define i32 @live_block_test_branch_loop_phis(i1 %c, i32 %end) {
682; CHECK-LABEL: @live_block_test_branch_loop_phis(
683; CHECK-NEXT:  preheader:
684; CHECK-NEXT:    br label [[HEADER:%.*]]
685; CHECK:       header:
686; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
687; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
688; CHECK:       check:
689; CHECK-NEXT:    br label [[BACKEDGE]]
690; CHECK:       live:
691; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
692; CHECK-NEXT:    br label [[BACKEDGE]]
693; CHECK:       backedge:
694; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ]
695; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
696; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
697; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
698; CHECK:       exit:
699; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
700; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
701;
702preheader:
703  br label %header
704
705header:
706  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
707  br i1 %c, label %check, label %live
708
709check:
710  br i1 true, label %backedge, label %live
711
712live:
713  %phi = phi i32 [ 1, %header ], [ -1, %check ]
714  %i.2 = add i32 %i, %phi
715  br label %backedge
716
717backedge:
718  %i.1 = phi i32 [%i, %check], [%i.2, %live]
719  %i.inc = add i32 %i.1, 1
720  %cmp = icmp slt i32 %i.inc, %end
721  br i1 %cmp, label %header, label %exit
722
723exit:
724  ret i32 %i.inc
725}
726
727define i32 @live_block_test_switch_loop(i1 %c, i32 %end) {
728; CHECK-LABEL: @live_block_test_switch_loop(
729; CHECK-NEXT:  preheader:
730; CHECK-NEXT:    br label [[HEADER:%.*]]
731; CHECK:       header:
732; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
733; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
734; CHECK:       check:
735; CHECK-NEXT:    br label [[BACKEDGE]]
736; CHECK:       live:
737; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
738; CHECK-NEXT:    br label [[BACKEDGE]]
739; CHECK:       backedge:
740; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ]
741; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
742; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
743; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
744; CHECK:       exit:
745; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
746; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
747;
748preheader:
749  br label %header
750
751header:
752  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
753  br i1 %c, label %check, label %live
754
755check:
756  switch i32 1, label %live [i32 0, label %live
757  i32 1, label %backedge
758  i32 2, label %live]
759
760live:
761  %i.2 = add i32 %i, 1
762  br label %backedge
763
764backedge:
765  %i.1 = phi i32 [%i, %check], [%i.2, %live]
766  %i.inc = add i32 %i.1, 1
767  %cmp = icmp slt i32 %i.inc, %end
768  br i1 %cmp, label %header, label %exit
769
770exit:
771  ret i32 %i.inc
772}
773
774define i32 @live_block_test_switch_loop_phis(i1 %c, i32 %end) {
775; CHECK-LABEL: @live_block_test_switch_loop_phis(
776; CHECK-NEXT:  preheader:
777; CHECK-NEXT:    br label [[HEADER:%.*]]
778; CHECK:       header:
779; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
780; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK:%.*]], label [[LIVE:%.*]]
781; CHECK:       check:
782; CHECK-NEXT:    br label [[BACKEDGE]]
783; CHECK:       live:
784; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
785; CHECK-NEXT:    br label [[BACKEDGE]]
786; CHECK:       backedge:
787; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[CHECK]] ], [ [[I_2]], [[LIVE]] ]
788; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
789; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
790; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[EXIT:%.*]]
791; CHECK:       exit:
792; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
793; CHECK-NEXT:    ret i32 [[I_INC_LCSSA]]
794;
795preheader:
796  br label %header
797
798header:
799  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
800  br i1 %c, label %check, label %live
801
802check:
803  switch i32 1, label %live [i32 0, label %live
804  i32 1, label %backedge
805  i32 2, label %live]
806
807live:
808  %phi = phi i32 [ 1, %header ], [ -1, %check ], [ -1, %check ], [ -1, %check ]
809  %i.2 = add i32 %i, %phi
810  br label %backedge
811
812backedge:
813  %i.1 = phi i32 [%i, %check], [%i.2, %live]
814  %i.inc = add i32 %i.1, 1
815  %cmp = icmp slt i32 %i.inc, %end
816  br i1 %cmp, label %header, label %exit
817
818exit:
819  ret i32 %i.inc
820}
821
822; Check that we can remove part of blocks of inner loop while the loop still
823; preserves, in presence of outer loop.
824define i32 @partial_sub_loop_test_branch_loop(i32 %end) {
825; CHECK-LABEL: @partial_sub_loop_test_branch_loop(
826; CHECK-NEXT:  entry:
827; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
828; CHECK:       outer_header:
829; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
830; CHECK-NEXT:    br label [[HEADER:%.*]]
831; CHECK:       header:
832; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[HEADER]] ]
833; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
834; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
835; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[OUTER_BACKEDGE]]
836; CHECK:       outer_backedge:
837; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
838; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
839; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END]]
840; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
841; CHECK:       exit:
842; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ]
843; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
844;
845entry:
846  br label %outer_header
847
848outer_header:
849  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
850  br label %preheader
851
852preheader:
853  br label %header
854
855header:
856  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
857  br i1 true, label %backedge, label %dead
858
859dead:
860  %i.2 = add i32 %i, 1
861  br label %backedge
862
863backedge:
864  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
865  %i.inc = add i32 %i.1, 1
866  %cmp = icmp slt i32 %i.inc, %end
867  br i1 %cmp, label %header, label %outer_backedge
868
869outer_backedge:
870  %j.inc = add i32 %j, 1
871  %cmp.j = icmp slt i32 %j.inc, %end
872  br i1 %cmp.j, label %outer_header, label %exit
873
874exit:
875  ret i32 %i.inc
876}
877
878define i32 @partial_sub_loop_test_switch_loop(i32 %end) {
879; CHECK-LABEL: @partial_sub_loop_test_switch_loop(
880; CHECK-NEXT:  entry:
881; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
882; CHECK:       outer_header:
883; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
884; CHECK-NEXT:    br label [[HEADER:%.*]]
885; CHECK:       header:
886; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[HEADER]] ]
887; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
888; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[I_INC]], [[END:%.*]]
889; CHECK-NEXT:    br i1 [[CMP]], label [[HEADER]], label [[OUTER_BACKEDGE]]
890; CHECK:       outer_backedge:
891; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[HEADER]] ]
892; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
893; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END]]
894; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
895; CHECK:       exit:
896; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ]
897; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
898;
899entry:
900  br label %outer_header
901
902outer_header:
903  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
904  br label %preheader
905
906preheader:
907  br label %header
908
909header:
910  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
911  switch i32 1, label %dead [i32 0, label %dead
912  i32 1, label %backedge
913  i32 2, label %dead]
914
915dead:
916  %i.2 = add i32 %i, 1
917  br label %backedge
918
919backedge:
920  %i.1 = phi i32 [%i, %header], [%i.2, %dead]
921  %i.inc = add i32 %i.1, 1
922  %cmp = icmp slt i32 %i.inc, %end
923  br i1 %cmp, label %header, label %outer_backedge
924
925outer_backedge:
926  %j.inc = add i32 %j, 1
927  %cmp.j = icmp slt i32 %j.inc, %end
928  br i1 %cmp.j, label %outer_header, label %exit
929
930exit:
931  ret i32 %i.inc
932}
933
934; Check that we can completely delete inner loop and preserve the outer loop.
935define i32 @full_sub_loop_test_branch_loop(i32 %end) {
936; CHECK-LABEL: @full_sub_loop_test_branch_loop(
937; CHECK-NEXT:  entry:
938; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
939; CHECK:       outer_header:
940; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
941; CHECK-NEXT:    br label [[HEADER:%.*]]
942; CHECK:       header:
943; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
944; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
945; CHECK-NEXT:    br i1 false, label [[BACKEDGE]], label [[DEAD:%.*]]
946; CHECK:       dead:
947; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
948; CHECK-NEXT:    br label [[BACKEDGE]]
949; CHECK:       backedge:
950; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
951; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
952; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[OUTER_BACKEDGE]]
953; CHECK:       outer_backedge:
954; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
955; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
956; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
957; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
958; CHECK:       exit:
959; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ]
960; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
961;
962entry:
963  br label %outer_header
964
965outer_header:
966  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
967  br label %preheader
968
969preheader:
970  br label %header
971
972header:
973  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
974  br label  %live_part
975
976live_part:
977  %mul = mul i32 %i, %i
978  br i1 false, label %backedge, label %dead
979
980dead:
981  %i.2 = add i32 %i, 1
982  br label %backedge
983
984backedge:
985  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
986  %i.inc = add i32 %i.1, 1
987  br i1 false, label %header, label %outer_backedge
988
989outer_backedge:
990  %j.inc = add i32 %j, 1
991  %cmp.j = icmp slt i32 %j.inc, %end
992  br i1 %cmp.j, label %outer_header, label %exit
993
994exit:
995  ret i32 %i.inc
996}
997
998define i32 @full_sub_loop_test_switch_loop(i32 %end) {
999; CHECK-LABEL: @full_sub_loop_test_switch_loop(
1000; CHECK-NEXT:  entry:
1001; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1002; CHECK:       outer_header:
1003; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1004; CHECK-NEXT:    br label [[HEADER:%.*]]
1005; CHECK:       header:
1006; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
1007; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1008; CHECK-NEXT:    switch i32 1, label [[DEAD:%.*]] [
1009; CHECK-NEXT:    i32 0, label [[BACKEDGE]]
1010; CHECK-NEXT:    ]
1011; CHECK:       dead:
1012; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
1013; CHECK-NEXT:    br label [[BACKEDGE]]
1014; CHECK:       backedge:
1015; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
1016; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
1017; CHECK-NEXT:    switch i32 1, label [[OUTER_BACKEDGE]] [
1018; CHECK-NEXT:    i32 0, label [[HEADER]]
1019; CHECK-NEXT:    ]
1020; CHECK:       outer_backedge:
1021; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
1022; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1023; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1024; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1025; CHECK:       exit:
1026; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ]
1027; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1028;
1029entry:
1030  br label %outer_header
1031
1032outer_header:
1033  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1034  br label %preheader
1035
1036preheader:
1037  br label %header
1038
1039header:
1040  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1041  br label  %live_part
1042
1043live_part:
1044  %mul = mul i32 %i, %i
1045  switch i32 1, label %dead [i32 0, label %backedge]
1046
1047dead:
1048  %i.2 = add i32 %i, 1
1049  br label %backedge
1050
1051backedge:
1052  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1053  %i.inc = add i32 %i.1, 1
1054  switch i32 1, label %outer_backedge [i32 0, label %header]
1055
1056outer_backedge:
1057  %j.inc = add i32 %j, 1
1058  %cmp.j = icmp slt i32 %j.inc, %end
1059  br i1 %cmp.j, label %outer_header, label %exit
1060
1061exit:
1062  ret i32 %i.inc
1063}
1064
1065; Inverted condition in live_part.
1066define i32 @full_sub_loop_test_branch_loop_inverse_1(i32 %end) {
1067; CHECK-LABEL: @full_sub_loop_test_branch_loop_inverse_1(
1068; CHECK-NEXT:  entry:
1069; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1070; CHECK:       outer_header:
1071; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1072; CHECK-NEXT:    br label [[HEADER:%.*]]
1073; CHECK:       header:
1074; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
1075; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1076; CHECK-NEXT:    br i1 true, label [[BACKEDGE]], label [[DEAD:%.*]]
1077; CHECK:       dead:
1078; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
1079; CHECK-NEXT:    br label [[BACKEDGE]]
1080; CHECK:       backedge:
1081; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
1082; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
1083; CHECK-NEXT:    br i1 false, label [[HEADER]], label [[OUTER_BACKEDGE]]
1084; CHECK:       outer_backedge:
1085; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
1086; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1087; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1088; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1089; CHECK:       exit:
1090; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ]
1091; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1092;
1093entry:
1094  br label %outer_header
1095
1096outer_header:
1097  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1098  br label %preheader
1099
1100preheader:
1101  br label %header
1102
1103header:
1104  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1105  br label  %live_part
1106
1107live_part:
1108  %mul = mul i32 %i, %i
1109  br i1 true, label %backedge, label %dead
1110
1111dead:
1112  %i.2 = add i32 %i, 1
1113  br label %backedge
1114
1115backedge:
1116  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1117  %i.inc = add i32 %i.1, 1
1118  br i1 false, label %header, label %outer_backedge
1119
1120outer_backedge:
1121  %j.inc = add i32 %j, 1
1122  %cmp.j = icmp slt i32 %j.inc, %end
1123  br i1 %cmp.j, label %outer_header, label %exit
1124
1125exit:
1126  ret i32 %i.inc
1127}
1128
1129define i32 @full_sub_loop_test_switch_loop_inverse_1(i32 %end) {
1130; CHECK-LABEL: @full_sub_loop_test_switch_loop_inverse_1(
1131; CHECK-NEXT:  entry:
1132; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1133; CHECK:       outer_header:
1134; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1135; CHECK-NEXT:    br label [[HEADER:%.*]]
1136; CHECK:       header:
1137; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[OUTER_HEADER]] ], [ [[I_INC:%.*]], [[BACKEDGE:%.*]] ]
1138; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1139; CHECK-NEXT:    switch i32 1, label [[BACKEDGE]] [
1140; CHECK-NEXT:    i32 0, label [[DEAD:%.*]]
1141; CHECK-NEXT:    ]
1142; CHECK:       dead:
1143; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
1144; CHECK-NEXT:    br label [[BACKEDGE]]
1145; CHECK:       backedge:
1146; CHECK-NEXT:    [[I_1:%.*]] = phi i32 [ [[I]], [[HEADER]] ], [ [[I_2]], [[DEAD]] ]
1147; CHECK-NEXT:    [[I_INC]] = add i32 [[I_1]], 1
1148; CHECK-NEXT:    switch i32 1, label [[OUTER_BACKEDGE]] [
1149; CHECK-NEXT:    i32 0, label [[HEADER]]
1150; CHECK-NEXT:    ]
1151; CHECK:       outer_backedge:
1152; CHECK-NEXT:    [[I_INC_LCSSA:%.*]] = phi i32 [ [[I_INC]], [[BACKEDGE]] ]
1153; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1154; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1155; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1156; CHECK:       exit:
1157; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ [[I_INC_LCSSA]], [[OUTER_BACKEDGE]] ]
1158; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1159;
1160entry:
1161  br label %outer_header
1162
1163outer_header:
1164  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1165  br label %preheader
1166
1167preheader:
1168  br label %header
1169
1170header:
1171  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1172  br label  %live_part
1173
1174live_part:
1175  %mul = mul i32 %i, %i
1176  switch i32 1, label %backedge [i32 0, label %dead]
1177
1178dead:
1179  %i.2 = add i32 %i, 1
1180  br label %backedge
1181
1182backedge:
1183  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1184  %i.inc = add i32 %i.1, 1
1185  switch i32 1, label %outer_backedge [i32 0, label %header]
1186
1187outer_backedge:
1188  %j.inc = add i32 %j, 1
1189  %cmp.j = icmp slt i32 %j.inc, %end
1190  br i1 %cmp.j, label %outer_header, label %exit
1191
1192exit:
1193  ret i32 %i.inc
1194}
1195
1196define i32 @full_sub_loop_test_branch_loop_inverse_2(i32 %end) {
1197; CHECK-LABEL: @full_sub_loop_test_branch_loop_inverse_2(
1198; CHECK-NEXT:  entry:
1199; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1200; CHECK:       outer_header:
1201; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1202; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
1203; CHECK-NEXT:    i32 1, label [[OUTER_BACKEDGE]]
1204; CHECK-NEXT:    ]
1205; CHECK:       preheader-split:
1206; CHECK-NEXT:    br label [[HEADER:%.*]]
1207; CHECK:       header:
1208; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
1209; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1210; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
1211; CHECK-NEXT:    [[I_INC]] = add i32 [[I_2]], 1
1212; CHECK-NEXT:    br label [[HEADER]]
1213; CHECK:       outer_backedge:
1214; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1215; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1216; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1217; CHECK:       exit:
1218; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ undef, [[OUTER_BACKEDGE]] ]
1219; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1220;
1221entry:
1222  br label %outer_header
1223
1224outer_header:
1225  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1226  br label %preheader
1227
1228preheader:
1229  br label %header
1230
1231header:
1232  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1233  br label  %live_part
1234
1235live_part:
1236  %mul = mul i32 %i, %i
1237  br i1 false, label %backedge, label %dead
1238
1239dead:
1240  %i.2 = add i32 %i, 1
1241  br label %backedge
1242
1243backedge:
1244  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1245  %i.inc = add i32 %i.1, 1
1246  br i1 true, label %header, label %outer_backedge
1247
1248outer_backedge:
1249  %j.inc = add i32 %j, 1
1250  %cmp.j = icmp slt i32 %j.inc, %end
1251  br i1 %cmp.j, label %outer_header, label %exit
1252
1253exit:
1254  ret i32 %i.inc
1255}
1256
1257define i32 @full_sub_loop_test_switch_loop_inverse_2(i32 %end) {
1258; CHECK-LABEL: @full_sub_loop_test_switch_loop_inverse_2(
1259; CHECK-NEXT:  entry:
1260; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1261; CHECK:       outer_header:
1262; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1263; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
1264; CHECK-NEXT:    i32 1, label [[OUTER_BACKEDGE]]
1265; CHECK-NEXT:    ]
1266; CHECK:       preheader-split:
1267; CHECK-NEXT:    br label [[HEADER:%.*]]
1268; CHECK:       header:
1269; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
1270; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1271; CHECK-NEXT:    [[I_2:%.*]] = add i32 [[I]], 1
1272; CHECK-NEXT:    [[I_INC]] = add i32 [[I_2]], 1
1273; CHECK-NEXT:    br label [[HEADER]]
1274; CHECK:       outer_backedge:
1275; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1276; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1277; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1278; CHECK:       exit:
1279; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ undef, [[OUTER_BACKEDGE]] ]
1280; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1281;
1282entry:
1283  br label %outer_header
1284
1285outer_header:
1286  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1287  br label %preheader
1288
1289preheader:
1290  br label %header
1291
1292header:
1293  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1294  br label  %live_part
1295
1296live_part:
1297  %mul = mul i32 %i, %i
1298  switch i32 1, label %dead [i32 0, label %backedge]
1299
1300dead:
1301  %i.2 = add i32 %i, 1
1302  br label %backedge
1303
1304backedge:
1305  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1306  %i.inc = add i32 %i.1, 1
1307  switch i32 1, label %header [i32 0, label %outer_backedge]
1308
1309outer_backedge:
1310  %j.inc = add i32 %j, 1
1311  %cmp.j = icmp slt i32 %j.inc, %end
1312  br i1 %cmp.j, label %outer_header, label %exit
1313
1314exit:
1315  ret i32 %i.inc
1316}
1317
1318
1319define i32 @full_sub_loop_test_branch_loop_inverse_3(i32 %end) {
1320; CHECK-LABEL: @full_sub_loop_test_branch_loop_inverse_3(
1321; CHECK-NEXT:  entry:
1322; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1323; CHECK:       outer_header:
1324; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1325; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
1326; CHECK-NEXT:    i32 1, label [[OUTER_BACKEDGE]]
1327; CHECK-NEXT:    ]
1328; CHECK:       preheader-split:
1329; CHECK-NEXT:    br label [[HEADER:%.*]]
1330; CHECK:       header:
1331; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
1332; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1333; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
1334; CHECK-NEXT:    br label [[HEADER]]
1335; CHECK:       outer_backedge:
1336; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1337; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1338; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1339; CHECK:       exit:
1340; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ undef, [[OUTER_BACKEDGE]] ]
1341; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1342;
1343entry:
1344  br label %outer_header
1345
1346outer_header:
1347  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1348  br label %preheader
1349
1350preheader:
1351  br label %header
1352
1353header:
1354  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1355  br label  %live_part
1356
1357live_part:
1358  %mul = mul i32 %i, %i
1359  br i1 true, label %backedge, label %dead
1360
1361dead:
1362  %i.2 = add i32 %i, 1
1363  br label %backedge
1364
1365backedge:
1366  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1367  %i.inc = add i32 %i.1, 1
1368  br i1 true, label %header, label %outer_backedge
1369
1370outer_backedge:
1371  %j.inc = add i32 %j, 1
1372  %cmp.j = icmp slt i32 %j.inc, %end
1373  br i1 %cmp.j, label %outer_header, label %exit
1374
1375exit:
1376  ret i32 %i.inc
1377}
1378
1379define i32 @full_sub_loop_test_switch_loop_inverse_3(i32 %end) {
1380; CHECK-LABEL: @full_sub_loop_test_switch_loop_inverse_3(
1381; CHECK-NEXT:  entry:
1382; CHECK-NEXT:    br label [[OUTER_HEADER:%.*]]
1383; CHECK:       outer_header:
1384; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[J_INC:%.*]], [[OUTER_BACKEDGE:%.*]] ]
1385; CHECK-NEXT:    switch i32 0, label [[PREHEADER_SPLIT:%.*]] [
1386; CHECK-NEXT:    i32 1, label [[OUTER_BACKEDGE]]
1387; CHECK-NEXT:    ]
1388; CHECK:       preheader-split:
1389; CHECK-NEXT:    br label [[HEADER:%.*]]
1390; CHECK:       header:
1391; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER_SPLIT]] ], [ [[I_INC:%.*]], [[HEADER]] ]
1392; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[I]], [[I]]
1393; CHECK-NEXT:    [[I_INC]] = add i32 [[I]], 1
1394; CHECK-NEXT:    br label [[HEADER]]
1395; CHECK:       outer_backedge:
1396; CHECK-NEXT:    [[J_INC]] = add i32 [[J]], 1
1397; CHECK-NEXT:    [[CMP_J:%.*]] = icmp slt i32 [[J_INC]], [[END:%.*]]
1398; CHECK-NEXT:    br i1 [[CMP_J]], label [[OUTER_HEADER]], label [[EXIT:%.*]]
1399; CHECK:       exit:
1400; CHECK-NEXT:    [[I_INC_LCSSA_LCSSA:%.*]] = phi i32 [ undef, [[OUTER_BACKEDGE]] ]
1401; CHECK-NEXT:    ret i32 [[I_INC_LCSSA_LCSSA]]
1402;
1403entry:
1404  br label %outer_header
1405
1406outer_header:
1407  %j = phi i32 [0, %entry], [%j.inc, %outer_backedge]
1408  br label %preheader
1409
1410preheader:
1411  br label %header
1412
1413header:
1414  %i = phi i32 [0, %preheader], [%i.inc, %backedge]
1415  br label  %live_part
1416
1417live_part:
1418  %mul = mul i32 %i, %i
1419  switch i32 1, label %backedge [i32 0, label %dead]
1420
1421dead:
1422  %i.2 = add i32 %i, 1
1423  br label %backedge
1424
1425backedge:
1426  %i.1 = phi i32 [%i, %live_part], [%i.2, %dead]
1427  %i.inc = add i32 %i.1, 1
1428  switch i32 1, label %header [i32 0, label %outer_backedge]
1429
1430outer_backedge:
1431  %j.inc = add i32 %j, 1
1432  %cmp.j = icmp slt i32 %j.inc, %end
1433  br i1 %cmp.j, label %outer_header, label %exit
1434
1435exit:
1436  ret i32 %i.inc
1437}
1438
1439define i32 @exit_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) {
1440; CHECK-LABEL: @exit_branch_from_inner_to_grandparent(
1441; CHECK-NEXT:  preheader:
1442; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1443; CHECK:       loop_1:
1444; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1445; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1446; CHECK:       loop_2:
1447; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1448; CHECK-NEXT:    switch i32 0, label [[LOOP_2_SPLIT:%.*]] [
1449; CHECK-NEXT:    i32 1, label [[LOOP_2_BACKEDGE]]
1450; CHECK-NEXT:    ]
1451; CHECK:       loop_2-split:
1452; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1453; CHECK:       loop_3:
1454; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2_SPLIT]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1455; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]]
1456; CHECK:       loop_3_backedge:
1457; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1458; CHECK-NEXT:    br label [[LOOP_3]]
1459; CHECK:       loop_2_backedge:
1460; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1461; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1462; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
1463; CHECK:       loop_1_backedge.loopexit:
1464; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1465; CHECK:       loop_1_backedge.loopexit1:
1466; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1467; CHECK:       loop_1_backedge:
1468; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1469; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1470; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1471; CHECK:       exit:
1472; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1473; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1474;
1475preheader:
1476  br label %loop_1
1477
1478loop_1:
1479  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1480  br label %loop_2
1481
1482loop_2:
1483  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1484  br label %loop_3
1485
1486loop_3:
1487  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1488  br i1 %cond1, label %loop_3_backedge, label %loop_1_backedge
1489
1490loop_3_backedge:
1491  %k.next = add i32 %k, 1
1492  br i1 true, label %loop_3, label %loop_2_backedge
1493
1494loop_2_backedge:
1495  %j.next = add i32 %j, 1
1496  %c_2 = icmp slt i32 %j.next, %N
1497  br i1 %c_2, label %loop_2, label %loop_1_backedge
1498
1499loop_1_backedge:
1500  %i.next = add i32 %i, 1
1501  %c_1 = icmp slt i32 %i.next, %N
1502  br i1 %c_1, label %loop_1, label %exit
1503
1504exit:
1505  ret i32 %i
1506}
1507
1508define i32 @exit_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) {
1509; CHECK-LABEL: @exit_switch_from_inner_to_grandparent(
1510; CHECK-NEXT:  preheader:
1511; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1512; CHECK:       loop_1:
1513; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1514; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1515; CHECK:       loop_2:
1516; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1517; CHECK-NEXT:    switch i32 0, label [[LOOP_2_SPLIT:%.*]] [
1518; CHECK-NEXT:    i32 1, label [[LOOP_2_BACKEDGE]]
1519; CHECK-NEXT:    ]
1520; CHECK:       loop_2-split:
1521; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1522; CHECK:       loop_3:
1523; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2_SPLIT]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1524; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]]
1525; CHECK:       loop_3_backedge:
1526; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1527; CHECK-NEXT:    br label [[LOOP_3]]
1528; CHECK:       loop_2_backedge:
1529; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1530; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1531; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
1532; CHECK:       loop_1_backedge.loopexit:
1533; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1534; CHECK:       loop_1_backedge.loopexit1:
1535; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1536; CHECK:       loop_1_backedge:
1537; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1538; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1539; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1540; CHECK:       exit:
1541; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1542; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1543;
1544preheader:
1545  br label %loop_1
1546
1547loop_1:
1548  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1549  br label %loop_2
1550
1551loop_2:
1552  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1553  br label %loop_3
1554
1555loop_3:
1556  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1557  br i1 %cond1, label %loop_3_backedge, label %loop_1_backedge
1558
1559loop_3_backedge:
1560  %k.next = add i32 %k, 1
1561  switch i32 1, label %loop_3 [i32 0, label %loop_2_backedge]
1562
1563loop_2_backedge:
1564  %j.next = add i32 %j, 1
1565  %c_2 = icmp slt i32 %j.next, %N
1566  br i1 %c_2, label %loop_2, label %loop_1_backedge
1567
1568loop_1_backedge:
1569  %i.next = add i32 %i, 1
1570  %c_1 = icmp slt i32 %i.next, %N
1571  br i1 %c_1, label %loop_1, label %exit
1572
1573exit:
1574  ret i32 %i
1575}
1576
1577define i32 @intermediate_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) {
1578; CHECK-LABEL: @intermediate_branch_from_inner_to_grandparent(
1579; CHECK-NEXT:  preheader:
1580; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1581; CHECK:       loop_1:
1582; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1583; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1584; CHECK:       loop_2:
1585; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1586; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1587; CHECK:       loop_3:
1588; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1589; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
1590; CHECK:       intermediate:
1591; CHECK-NEXT:    br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]]
1592; CHECK:       loop_3_backedge:
1593; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1594; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
1595; CHECK:       loop_2_backedge:
1596; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1597; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1598; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
1599; CHECK:       loop_1_backedge.loopexit:
1600; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1601; CHECK:       loop_1_backedge.loopexit1:
1602; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1603; CHECK:       loop_1_backedge:
1604; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1605; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1606; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1607; CHECK:       exit:
1608; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1609; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1610;
1611preheader:
1612  br label %loop_1
1613
1614loop_1:
1615  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1616  br label %loop_2
1617
1618loop_2:
1619  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1620  br label %loop_3
1621
1622loop_3:
1623  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1624  br i1 %cond1, label %loop_3_backedge, label %intermediate
1625
1626intermediate:
1627  br i1 false, label %loop_3_backedge, label %loop_1_backedge
1628
1629loop_3_backedge:
1630  %k.next = add i32 %k, 1
1631  br i1 %cond2, label %loop_3, label %loop_2_backedge
1632
1633loop_2_backedge:
1634  %j.next = add i32 %j, 1
1635  %c_2 = icmp slt i32 %j.next, %N
1636  br i1 %c_2, label %loop_2, label %loop_1_backedge
1637
1638loop_1_backedge:
1639  %i.next = add i32 %i, 1
1640  %c_1 = icmp slt i32 %i.next, %N
1641  br i1 %c_1, label %loop_1, label %exit
1642
1643exit:
1644  ret i32 %i
1645}
1646
1647define i32 @intermediate_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i32 %N) {
1648; CHECK-LABEL: @intermediate_switch_from_inner_to_grandparent(
1649; CHECK-NEXT:  preheader:
1650; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1651; CHECK:       loop_1:
1652; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1653; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1654; CHECK:       loop_2:
1655; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1656; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1657; CHECK:       loop_3:
1658; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1659; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
1660; CHECK:       intermediate:
1661; CHECK-NEXT:    switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [
1662; CHECK-NEXT:    i32 0, label [[LOOP_3_BACKEDGE]]
1663; CHECK-NEXT:    ]
1664; CHECK:       loop_3_backedge:
1665; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1666; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
1667; CHECK:       loop_2_backedge:
1668; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1669; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1670; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
1671; CHECK:       loop_1_backedge.loopexit:
1672; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1673; CHECK:       loop_1_backedge.loopexit1:
1674; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1675; CHECK:       loop_1_backedge:
1676; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1677; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1678; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1679; CHECK:       exit:
1680; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1681; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1682;
1683preheader:
1684  br label %loop_1
1685
1686loop_1:
1687  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1688  br label %loop_2
1689
1690loop_2:
1691  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1692  br label %loop_3
1693
1694loop_3:
1695  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1696  br i1 %cond1, label %loop_3_backedge, label %intermediate
1697
1698intermediate:
1699  switch i32 1, label %loop_1_backedge [i32 0, label %loop_3_backedge]
1700
1701loop_3_backedge:
1702  %k.next = add i32 %k, 1
1703  br i1 %cond2, label %loop_3, label %loop_2_backedge
1704
1705loop_2_backedge:
1706  %j.next = add i32 %j, 1
1707  %c_2 = icmp slt i32 %j.next, %N
1708  br i1 %c_2, label %loop_2, label %loop_1_backedge
1709
1710loop_1_backedge:
1711  %i.next = add i32 %i, 1
1712  %c_1 = icmp slt i32 %i.next, %N
1713  br i1 %c_1, label %loop_1, label %exit
1714
1715exit:
1716  ret i32 %i
1717}
1718
1719define i32 @intermediate_branch_from_inner_to_parent(i1 %cond1, i1 %cond2, i32 %N) {
1720; CHECK-LABEL: @intermediate_branch_from_inner_to_parent(
1721; CHECK-NEXT:  preheader:
1722; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1723; CHECK:       loop_1:
1724; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1725; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1726; CHECK:       loop_2:
1727; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1728; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1729; CHECK:       loop_3:
1730; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1731; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
1732; CHECK:       intermediate:
1733; CHECK-NEXT:    br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_2_BACKEDGE]]
1734; CHECK:       loop_3_backedge:
1735; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1736; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
1737; CHECK:       loop_2_backedge:
1738; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1739; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1740; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]]
1741; CHECK:       loop_1_backedge:
1742; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1743; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1744; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1745; CHECK:       exit:
1746; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1747; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1748;
1749preheader:
1750  br label %loop_1
1751
1752loop_1:
1753  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1754  br label %loop_2
1755
1756loop_2:
1757  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1758  br label %loop_3
1759
1760loop_3:
1761  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1762  br i1 %cond1, label %loop_3_backedge, label %intermediate
1763
1764intermediate:
1765  br i1 false, label %loop_3_backedge, label %loop_2_backedge
1766
1767loop_3_backedge:
1768  %k.next = add i32 %k, 1
1769  br i1 %cond2, label %loop_3, label %loop_2_backedge
1770
1771loop_2_backedge:
1772  %j.next = add i32 %j, 1
1773  %c_2 = icmp slt i32 %j.next, %N
1774  br i1 %c_2, label %loop_2, label %loop_1_backedge
1775
1776loop_1_backedge:
1777  %i.next = add i32 %i, 1
1778  %c_1 = icmp slt i32 %i.next, %N
1779  br i1 %c_1, label %loop_1, label %exit
1780
1781exit:
1782  ret i32 %i
1783}
1784
1785define i32 @intermediate_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i32 %N) {
1786; CHECK-LABEL: @intermediate_switch_from_inner_to_parent(
1787; CHECK-NEXT:  preheader:
1788; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1789; CHECK:       loop_1:
1790; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1791; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1792; CHECK:       loop_2:
1793; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1794; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1795; CHECK:       loop_3:
1796; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1797; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
1798; CHECK:       intermediate:
1799; CHECK-NEXT:    switch i32 1, label [[LOOP_2_BACKEDGE]] [
1800; CHECK-NEXT:    i32 0, label [[LOOP_3_BACKEDGE]]
1801; CHECK-NEXT:    ]
1802; CHECK:       loop_3_backedge:
1803; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1804; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
1805; CHECK:       loop_2_backedge:
1806; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1807; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1808; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]]
1809; CHECK:       loop_1_backedge:
1810; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1811; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1812; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1813; CHECK:       exit:
1814; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1815; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1816;
1817preheader:
1818  br label %loop_1
1819
1820loop_1:
1821  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1822  br label %loop_2
1823
1824loop_2:
1825  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1826  br label %loop_3
1827
1828loop_3:
1829  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1830  br i1 %cond1, label %loop_3_backedge, label %intermediate
1831
1832intermediate:
1833  switch i32 1, label %loop_2_backedge [i32 0, label %loop_3_backedge]
1834
1835loop_3_backedge:
1836  %k.next = add i32 %k, 1
1837  br i1 %cond2, label %loop_3, label %loop_2_backedge
1838
1839loop_2_backedge:
1840  %j.next = add i32 %j, 1
1841  %c_2 = icmp slt i32 %j.next, %N
1842  br i1 %c_2, label %loop_2, label %loop_1_backedge
1843
1844loop_1_backedge:
1845  %i.next = add i32 %i, 1
1846  %c_1 = icmp slt i32 %i.next, %N
1847  br i1 %c_1, label %loop_1, label %exit
1848
1849exit:
1850  ret i32 %i
1851}
1852
1853define i32 @intermediate_subloop_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
1854; CHECK-LABEL: @intermediate_subloop_branch_from_inner_to_grandparent(
1855; CHECK-NEXT:  preheader:
1856; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1857; CHECK:       loop_1:
1858; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1859; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1860; CHECK:       loop_2:
1861; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1862; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1863; CHECK:       loop_3:
1864; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1865; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
1866; CHECK:       intermediate:
1867; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
1868; CHECK:       intermediate_loop:
1869; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]]
1870; CHECK:       intermediate_exit:
1871; CHECK-NEXT:    br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]]
1872; CHECK:       loop_3_backedge:
1873; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1874; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
1875; CHECK:       loop_2_backedge:
1876; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1877; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1878; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
1879; CHECK:       loop_1_backedge.loopexit:
1880; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1881; CHECK:       loop_1_backedge.loopexit1:
1882; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1883; CHECK:       loop_1_backedge:
1884; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1885; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1886; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1887; CHECK:       exit:
1888; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1889; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1890;
1891preheader:
1892  br label %loop_1
1893
1894loop_1:
1895  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1896  br label %loop_2
1897
1898loop_2:
1899  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1900  br label %loop_3
1901
1902loop_3:
1903  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1904  br i1 %cond1, label %loop_3_backedge, label %intermediate
1905
1906intermediate:
1907  br label %intermediate_loop
1908
1909intermediate_loop:
1910  br i1 %cond3, label %intermediate_loop, label %intermediate_exit
1911
1912intermediate_exit:
1913  br i1 false, label %loop_3_backedge, label %loop_1_backedge
1914
1915loop_3_backedge:
1916  %k.next = add i32 %k, 1
1917  br i1 %cond2, label %loop_3, label %loop_2_backedge
1918
1919loop_2_backedge:
1920  %j.next = add i32 %j, 1
1921  %c_2 = icmp slt i32 %j.next, %N
1922  br i1 %c_2, label %loop_2, label %loop_1_backedge
1923
1924loop_1_backedge:
1925  %i.next = add i32 %i, 1
1926  %c_1 = icmp slt i32 %i.next, %N
1927  br i1 %c_1, label %loop_1, label %exit
1928
1929exit:
1930  ret i32 %i
1931}
1932
1933define i32 @intermediate_subloop_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
1934; CHECK-LABEL: @intermediate_subloop_switch_from_inner_to_grandparent(
1935; CHECK-NEXT:  preheader:
1936; CHECK-NEXT:    br label [[LOOP_1:%.*]]
1937; CHECK:       loop_1:
1938; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
1939; CHECK-NEXT:    br label [[LOOP_2:%.*]]
1940; CHECK:       loop_2:
1941; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
1942; CHECK-NEXT:    br label [[LOOP_3:%.*]]
1943; CHECK:       loop_3:
1944; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
1945; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
1946; CHECK:       intermediate:
1947; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
1948; CHECK:       intermediate_loop:
1949; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]]
1950; CHECK:       intermediate_exit:
1951; CHECK-NEXT:    switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [
1952; CHECK-NEXT:    i32 0, label [[LOOP_3_BACKEDGE]]
1953; CHECK-NEXT:    ]
1954; CHECK:       loop_3_backedge:
1955; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
1956; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
1957; CHECK:       loop_2_backedge:
1958; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
1959; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
1960; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
1961; CHECK:       loop_1_backedge.loopexit:
1962; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1963; CHECK:       loop_1_backedge.loopexit1:
1964; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
1965; CHECK:       loop_1_backedge:
1966; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
1967; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
1968; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
1969; CHECK:       exit:
1970; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
1971; CHECK-NEXT:    ret i32 [[I_LCSSA]]
1972;
1973preheader:
1974  br label %loop_1
1975
1976loop_1:
1977  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
1978  br label %loop_2
1979
1980loop_2:
1981  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
1982  br label %loop_3
1983
1984loop_3:
1985  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
1986  br i1 %cond1, label %loop_3_backedge, label %intermediate
1987
1988intermediate:
1989  br label %intermediate_loop
1990
1991intermediate_loop:
1992  br i1 %cond3, label %intermediate_loop, label %intermediate_exit
1993
1994intermediate_exit:
1995  switch i32 1, label %loop_1_backedge [i32 0, label %loop_3_backedge]
1996
1997loop_3_backedge:
1998  %k.next = add i32 %k, 1
1999  br i1 %cond2, label %loop_3, label %loop_2_backedge
2000
2001loop_2_backedge:
2002  %j.next = add i32 %j, 1
2003  %c_2 = icmp slt i32 %j.next, %N
2004  br i1 %c_2, label %loop_2, label %loop_1_backedge
2005
2006loop_1_backedge:
2007  %i.next = add i32 %i, 1
2008  %c_1 = icmp slt i32 %i.next, %N
2009  br i1 %c_1, label %loop_1, label %exit
2010
2011exit:
2012  ret i32 %i
2013}
2014
2015define i32 @intermediate_subloop_branch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
2016; CHECK-LABEL: @intermediate_subloop_branch_from_inner_to_parent(
2017; CHECK-NEXT:  preheader:
2018; CHECK-NEXT:    br label [[LOOP_1:%.*]]
2019; CHECK:       loop_1:
2020; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
2021; CHECK-NEXT:    br label [[LOOP_2:%.*]]
2022; CHECK:       loop_2:
2023; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
2024; CHECK-NEXT:    br label [[LOOP_3:%.*]]
2025; CHECK:       loop_3:
2026; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
2027; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
2028; CHECK:       intermediate:
2029; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
2030; CHECK:       intermediate_loop:
2031; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]]
2032; CHECK:       intermediate_exit:
2033; CHECK-NEXT:    br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_2_BACKEDGE]]
2034; CHECK:       loop_3_backedge:
2035; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
2036; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
2037; CHECK:       loop_2_backedge:
2038; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
2039; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
2040; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]]
2041; CHECK:       loop_1_backedge:
2042; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
2043; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
2044; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
2045; CHECK:       exit:
2046; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
2047; CHECK-NEXT:    ret i32 [[I_LCSSA]]
2048;
2049preheader:
2050  br label %loop_1
2051
2052loop_1:
2053  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
2054  br label %loop_2
2055
2056loop_2:
2057  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
2058  br label %loop_3
2059
2060loop_3:
2061  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
2062  br i1 %cond1, label %loop_3_backedge, label %intermediate
2063
2064intermediate:
2065  br label %intermediate_loop
2066
2067intermediate_loop:
2068  br i1 %cond3, label %intermediate_loop, label %intermediate_exit
2069
2070intermediate_exit:
2071  br i1 false, label %loop_3_backedge, label %loop_2_backedge
2072
2073loop_3_backedge:
2074  %k.next = add i32 %k, 1
2075  br i1 %cond2, label %loop_3, label %loop_2_backedge
2076
2077loop_2_backedge:
2078  %j.next = add i32 %j, 1
2079  %c_2 = icmp slt i32 %j.next, %N
2080  br i1 %c_2, label %loop_2, label %loop_1_backedge
2081
2082loop_1_backedge:
2083  %i.next = add i32 %i, 1
2084  %c_1 = icmp slt i32 %i.next, %N
2085  br i1 %c_1, label %loop_1, label %exit
2086
2087exit:
2088  ret i32 %i
2089}
2090
2091define i32 @intermediate_subloop_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
2092; CHECK-LABEL: @intermediate_subloop_switch_from_inner_to_parent(
2093; CHECK-NEXT:  preheader:
2094; CHECK-NEXT:    br label [[LOOP_1:%.*]]
2095; CHECK:       loop_1:
2096; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
2097; CHECK-NEXT:    br label [[LOOP_2:%.*]]
2098; CHECK:       loop_2:
2099; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
2100; CHECK-NEXT:    br label [[LOOP_3:%.*]]
2101; CHECK:       loop_3:
2102; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
2103; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
2104; CHECK:       intermediate:
2105; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
2106; CHECK:       intermediate_loop:
2107; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP]], label [[INTERMEDIATE_EXIT:%.*]]
2108; CHECK:       intermediate_exit:
2109; CHECK-NEXT:    switch i32 1, label [[LOOP_2_BACKEDGE]] [
2110; CHECK-NEXT:    i32 0, label [[LOOP_3_BACKEDGE]]
2111; CHECK-NEXT:    ]
2112; CHECK:       loop_3_backedge:
2113; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
2114; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
2115; CHECK:       loop_2_backedge:
2116; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
2117; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
2118; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]]
2119; CHECK:       loop_1_backedge:
2120; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
2121; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
2122; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
2123; CHECK:       exit:
2124; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
2125; CHECK-NEXT:    ret i32 [[I_LCSSA]]
2126;
2127preheader:
2128  br label %loop_1
2129
2130loop_1:
2131  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
2132  br label %loop_2
2133
2134loop_2:
2135  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
2136  br label %loop_3
2137
2138loop_3:
2139  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
2140  br i1 %cond1, label %loop_3_backedge, label %intermediate
2141
2142intermediate:
2143  br label %intermediate_loop
2144
2145intermediate_loop:
2146  br i1 %cond3, label %intermediate_loop, label %intermediate_exit
2147
2148intermediate_exit:
2149  switch i32 1, label %loop_2_backedge [i32 0, label %loop_3_backedge]
2150
2151loop_3_backedge:
2152  %k.next = add i32 %k, 1
2153  br i1 %cond2, label %loop_3, label %loop_2_backedge
2154
2155loop_2_backedge:
2156  %j.next = add i32 %j, 1
2157  %c_2 = icmp slt i32 %j.next, %N
2158  br i1 %c_2, label %loop_2, label %loop_1_backedge
2159
2160loop_1_backedge:
2161  %i.next = add i32 %i, 1
2162  %c_1 = icmp slt i32 %i.next, %N
2163  br i1 %c_1, label %loop_1, label %exit
2164
2165exit:
2166  ret i32 %i
2167}
2168
2169define i32 @intermediate_complex_subloop_branch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
2170; CHECK-LABEL: @intermediate_complex_subloop_branch_from_inner_to_parent(
2171; CHECK-NEXT:  preheader:
2172; CHECK-NEXT:    br label [[LOOP_1:%.*]]
2173; CHECK:       loop_1:
2174; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
2175; CHECK-NEXT:    br label [[LOOP_2:%.*]]
2176; CHECK:       loop_2:
2177; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
2178; CHECK-NEXT:    br label [[LOOP_3:%.*]]
2179; CHECK:       loop_3:
2180; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
2181; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
2182; CHECK:       intermediate:
2183; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
2184; CHECK:       intermediate_loop:
2185; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]]
2186; CHECK:       intermediate_loop.backedge:
2187; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP]]
2188; CHECK:       intermediate_block:
2189; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]]
2190; CHECK:       intermediate_exit:
2191; CHECK-NEXT:    br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_2_BACKEDGE]]
2192; CHECK:       loop_3_backedge:
2193; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
2194; CHECK-NEXT:    br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
2195; CHECK:       loop_2_backedge:
2196; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
2197; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
2198; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]]
2199; CHECK:       loop_1_backedge:
2200; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
2201; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
2202; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
2203; CHECK:       exit:
2204; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
2205; CHECK-NEXT:    ret i32 [[I_LCSSA]]
2206;
2207preheader:
2208  br label %loop_1
2209
2210loop_1:
2211  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
2212  br label %loop_2
2213
2214loop_2:
2215  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
2216  br label %loop_3
2217
2218loop_3:
2219  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
2220  br i1 %cond1, label %loop_3_backedge, label %intermediate
2221
2222intermediate:
2223  br label %intermediate_loop
2224
2225intermediate_loop:
2226  br i1 %cond3, label %intermediate_loop, label %intermediate_block
2227
2228intermediate_block:
2229  br i1 %cond2, label %intermediate_loop, label %intermediate_exit
2230
2231intermediate_exit:
2232  br i1 false, label %loop_3_backedge, label %loop_2_backedge
2233
2234loop_3_backedge:
2235  %k.next = add i32 %k, 1
2236  br i1 %cond2, label %loop_3, label %loop_2_backedge
2237
2238loop_2_backedge:
2239  %j.next = add i32 %j, 1
2240  %c_2 = icmp slt i32 %j.next, %N
2241  br i1 %c_2, label %loop_2, label %loop_1_backedge
2242
2243loop_1_backedge:
2244  %i.next = add i32 %i, 1
2245  %c_1 = icmp slt i32 %i.next, %N
2246  br i1 %c_1, label %loop_1, label %exit
2247
2248exit:
2249  ret i32 %i
2250}
2251
2252define i32 @intermediate_complex_subloop_switch_from_inner_to_parent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
2253; CHECK-LABEL: @intermediate_complex_subloop_switch_from_inner_to_parent(
2254; CHECK-NEXT:  preheader:
2255; CHECK-NEXT:    br label [[LOOP_1:%.*]]
2256; CHECK:       loop_1:
2257; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
2258; CHECK-NEXT:    br label [[LOOP_2:%.*]]
2259; CHECK:       loop_2:
2260; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
2261; CHECK-NEXT:    br label [[LOOP_3:%.*]]
2262; CHECK:       loop_3:
2263; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
2264; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
2265; CHECK:       intermediate:
2266; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
2267; CHECK:       intermediate_loop:
2268; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]]
2269; CHECK:       intermediate_loop.backedge:
2270; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP]]
2271; CHECK:       intermediate_block:
2272; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]]
2273; CHECK:       intermediate_exit:
2274; CHECK-NEXT:    switch i32 1, label [[LOOP_2_BACKEDGE]] [
2275; CHECK-NEXT:    i32 0, label [[LOOP_3_BACKEDGE]]
2276; CHECK-NEXT:    ]
2277; CHECK:       loop_3_backedge:
2278; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
2279; CHECK-NEXT:    br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
2280; CHECK:       loop_2_backedge:
2281; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
2282; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
2283; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE]]
2284; CHECK:       loop_1_backedge:
2285; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
2286; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
2287; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
2288; CHECK:       exit:
2289; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
2290; CHECK-NEXT:    ret i32 [[I_LCSSA]]
2291;
2292preheader:
2293  br label %loop_1
2294
2295loop_1:
2296  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
2297  br label %loop_2
2298
2299loop_2:
2300  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
2301  br label %loop_3
2302
2303loop_3:
2304  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
2305  br i1 %cond1, label %loop_3_backedge, label %intermediate
2306
2307intermediate:
2308  br label %intermediate_loop
2309
2310intermediate_loop:
2311  br i1 %cond3, label %intermediate_loop, label %intermediate_block
2312
2313intermediate_block:
2314  br i1 %cond2, label %intermediate_loop, label %intermediate_exit
2315
2316intermediate_exit:
2317  switch i32 1, label %loop_2_backedge [i32 0, label %loop_3_backedge]
2318
2319loop_3_backedge:
2320  %k.next = add i32 %k, 1
2321  br i1 %cond2, label %loop_3, label %loop_2_backedge
2322
2323loop_2_backedge:
2324  %j.next = add i32 %j, 1
2325  %c_2 = icmp slt i32 %j.next, %N
2326  br i1 %c_2, label %loop_2, label %loop_1_backedge
2327
2328loop_1_backedge:
2329  %i.next = add i32 %i, 1
2330  %c_1 = icmp slt i32 %i.next, %N
2331  br i1 %c_1, label %loop_1, label %exit
2332
2333exit:
2334  ret i32 %i
2335}
2336
2337
2338define i32 @intermediate_complex_subloop_branch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
2339; CHECK-LABEL: @intermediate_complex_subloop_branch_from_inner_to_grandparent(
2340; CHECK-NEXT:  preheader:
2341; CHECK-NEXT:    br label [[LOOP_1:%.*]]
2342; CHECK:       loop_1:
2343; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
2344; CHECK-NEXT:    br label [[LOOP_2:%.*]]
2345; CHECK:       loop_2:
2346; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
2347; CHECK-NEXT:    br label [[LOOP_3:%.*]]
2348; CHECK:       loop_3:
2349; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
2350; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
2351; CHECK:       intermediate:
2352; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
2353; CHECK:       intermediate_loop:
2354; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]]
2355; CHECK:       intermediate_loop.backedge:
2356; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP]]
2357; CHECK:       intermediate_block:
2358; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]]
2359; CHECK:       intermediate_exit:
2360; CHECK-NEXT:    br i1 false, label [[LOOP_3_BACKEDGE]], label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]]
2361; CHECK:       loop_3_backedge:
2362; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
2363; CHECK-NEXT:    br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
2364; CHECK:       loop_2_backedge:
2365; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
2366; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
2367; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
2368; CHECK:       loop_1_backedge.loopexit:
2369; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
2370; CHECK:       loop_1_backedge.loopexit1:
2371; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
2372; CHECK:       loop_1_backedge:
2373; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
2374; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
2375; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
2376; CHECK:       exit:
2377; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
2378; CHECK-NEXT:    ret i32 [[I_LCSSA]]
2379;
2380preheader:
2381  br label %loop_1
2382
2383loop_1:
2384  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
2385  br label %loop_2
2386
2387loop_2:
2388  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
2389  br label %loop_3
2390
2391loop_3:
2392  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
2393  br i1 %cond1, label %loop_3_backedge, label %intermediate
2394
2395intermediate:
2396  br label %intermediate_loop
2397
2398intermediate_loop:
2399  br i1 %cond3, label %intermediate_loop, label %intermediate_block
2400
2401intermediate_block:
2402  br i1 %cond2, label %intermediate_loop, label %intermediate_exit
2403
2404intermediate_exit:
2405  br i1 false, label %loop_3_backedge, label %loop_1_backedge
2406
2407loop_3_backedge:
2408  %k.next = add i32 %k, 1
2409  br i1 %cond2, label %loop_3, label %loop_2_backedge
2410
2411loop_2_backedge:
2412  %j.next = add i32 %j, 1
2413  %c_2 = icmp slt i32 %j.next, %N
2414  br i1 %c_2, label %loop_2, label %loop_1_backedge
2415
2416loop_1_backedge:
2417  %i.next = add i32 %i, 1
2418  %c_1 = icmp slt i32 %i.next, %N
2419  br i1 %c_1, label %loop_1, label %exit
2420
2421exit:
2422  ret i32 %i
2423}
2424
2425define i32 @intermediate_complex_subloop_switch_from_inner_to_grandparent(i1 %cond1, i1 %cond2, i1 %cond3, i32 %N) {
2426; CHECK-LABEL: @intermediate_complex_subloop_switch_from_inner_to_grandparent(
2427; CHECK-NEXT:  preheader:
2428; CHECK-NEXT:    br label [[LOOP_1:%.*]]
2429; CHECK:       loop_1:
2430; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_1_BACKEDGE:%.*]] ]
2431; CHECK-NEXT:    br label [[LOOP_2:%.*]]
2432; CHECK:       loop_2:
2433; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP_1]] ], [ [[J_NEXT:%.*]], [[LOOP_2_BACKEDGE:%.*]] ]
2434; CHECK-NEXT:    br label [[LOOP_3:%.*]]
2435; CHECK:       loop_3:
2436; CHECK-NEXT:    [[K:%.*]] = phi i32 [ 0, [[LOOP_2]] ], [ [[K_NEXT:%.*]], [[LOOP_3_BACKEDGE:%.*]] ]
2437; CHECK-NEXT:    br i1 [[COND1:%.*]], label [[LOOP_3_BACKEDGE]], label [[INTERMEDIATE:%.*]]
2438; CHECK:       intermediate:
2439; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP:%.*]]
2440; CHECK:       intermediate_loop:
2441; CHECK-NEXT:    br i1 [[COND3:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE:%.*]], label [[INTERMEDIATE_BLOCK:%.*]]
2442; CHECK:       intermediate_loop.backedge:
2443; CHECK-NEXT:    br label [[INTERMEDIATE_LOOP]]
2444; CHECK:       intermediate_block:
2445; CHECK-NEXT:    br i1 [[COND2:%.*]], label [[INTERMEDIATE_LOOP_BACKEDGE]], label [[INTERMEDIATE_EXIT:%.*]]
2446; CHECK:       intermediate_exit:
2447; CHECK-NEXT:    switch i32 1, label [[LOOP_1_BACKEDGE_LOOPEXIT:%.*]] [
2448; CHECK-NEXT:    i32 0, label [[LOOP_3_BACKEDGE]]
2449; CHECK-NEXT:    ]
2450; CHECK:       loop_3_backedge:
2451; CHECK-NEXT:    [[K_NEXT]] = add i32 [[K]], 1
2452; CHECK-NEXT:    br i1 [[COND2]], label [[LOOP_3]], label [[LOOP_2_BACKEDGE]]
2453; CHECK:       loop_2_backedge:
2454; CHECK-NEXT:    [[J_NEXT]] = add i32 [[J]], 1
2455; CHECK-NEXT:    [[C_2:%.*]] = icmp slt i32 [[J_NEXT]], [[N:%.*]]
2456; CHECK-NEXT:    br i1 [[C_2]], label [[LOOP_2]], label [[LOOP_1_BACKEDGE_LOOPEXIT1:%.*]]
2457; CHECK:       loop_1_backedge.loopexit:
2458; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
2459; CHECK:       loop_1_backedge.loopexit1:
2460; CHECK-NEXT:    br label [[LOOP_1_BACKEDGE]]
2461; CHECK:       loop_1_backedge:
2462; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
2463; CHECK-NEXT:    [[C_1:%.*]] = icmp slt i32 [[I_NEXT]], [[N]]
2464; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_1]], label [[EXIT:%.*]]
2465; CHECK:       exit:
2466; CHECK-NEXT:    [[I_LCSSA:%.*]] = phi i32 [ [[I]], [[LOOP_1_BACKEDGE]] ]
2467; CHECK-NEXT:    ret i32 [[I_LCSSA]]
2468;
2469preheader:
2470  br label %loop_1
2471
2472loop_1:
2473  %i = phi i32 [ 0, %preheader ], [ %i.next, %loop_1_backedge ]
2474  br label %loop_2
2475
2476loop_2:
2477  %j = phi i32 [ 0, %loop_1 ], [ %j.next, %loop_2_backedge ]
2478  br label %loop_3
2479
2480loop_3:
2481  %k = phi i32 [ 0, %loop_2 ], [ %k.next, %loop_3_backedge ]
2482  br i1 %cond1, label %loop_3_backedge, label %intermediate
2483
2484intermediate:
2485  br label %intermediate_loop
2486
2487intermediate_loop:
2488  br i1 %cond3, label %intermediate_loop, label %intermediate_block
2489
2490intermediate_block:
2491  br i1 %cond2, label %intermediate_loop, label %intermediate_exit
2492
2493intermediate_exit:
2494  switch i32 1, label %loop_1_backedge [i32 0, label %loop_3_backedge]
2495
2496loop_3_backedge:
2497  %k.next = add i32 %k, 1
2498  br i1 %cond2, label %loop_3, label %loop_2_backedge
2499
2500loop_2_backedge:
2501  %j.next = add i32 %j, 1
2502  %c_2 = icmp slt i32 %j.next, %N
2503  br i1 %c_2, label %loop_2, label %loop_1_backedge
2504
2505loop_1_backedge:
2506  %i.next = add i32 %i, 1
2507  %c_1 = icmp slt i32 %i.next, %N
2508  br i1 %c_1, label %loop_1, label %exit
2509
2510exit:
2511  ret i32 %i
2512}
2513
2514define i32 @complex_dead_subloop_branch(i1 %cond1, i1 %cond2, i1 %cond3) {
2515entry:
2516  br label %loop
2517
2518loop:
2519  br i1 true, label %latch, label %subloop
2520
2521subloop:
2522  br i1 %cond1, label %x, label %y
2523
2524x:
2525  br label %subloop_latch
2526
2527y:
2528  br label %subloop_latch
2529
2530subloop_latch:
2531  %dead_phi = phi i32 [ 1, %x ], [ 2, %y ]
2532  br i1 %cond2, label %latch, label %subloop
2533
2534latch:
2535  %result = phi i32 [ 0, %loop ], [ %dead_phi, %subloop_latch ]
2536  br i1 %cond3, label %loop, label %exit
2537
2538exit:
2539  ret i32 %result
2540}
2541
2542define i32 @complex_dead_subloop_switch(i1 %cond1, i1 %cond2, i1 %cond3) {
2543entry:
2544  br label %loop
2545
2546loop:
2547  switch i32 1, label %latch [ i32 0, label %subloop ]
2548
2549subloop:
2550  br i1 %cond1, label %x, label %y
2551
2552x:
2553  br label %subloop_latch
2554
2555y:
2556  br label %subloop_latch
2557
2558subloop_latch:
2559  %dead_phi = phi i32 [ 1, %x ], [ 2, %y ]
2560  br i1 %cond2, label %latch, label %subloop
2561
2562latch:
2563  %result = phi i32 [ 0, %loop ], [ %dead_phi, %subloop_latch ]
2564  br i1 %cond3, label %loop, label %exit
2565
2566exit:
2567  ret i32 %result
2568}
2569