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