xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/ARM/nontrivial-unswitch-cost.ll (revision 2f79f5438cd6f4fa0fdc32458911c2d163f917c0)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -mtriple=thumbv8m.main -passes='simple-loop-unswitch<nontrivial>' -unswitch-threshold=5 -S -o - %s | FileCheck %s
3
4declare void @a()
5declare void @b()
6declare void @x()
7
8define void @test_no_unswitch(ptr %ptr, i1 %cond) {
9; CHECK-LABEL: @test_no_unswitch(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
12; CHECK:       loop_begin:
13; CHECK-NEXT:    call void @x()
14; CHECK-NEXT:    call void @x()
15; CHECK-NEXT:    call void @x()
16; CHECK-NEXT:    call void @x()
17; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
18; CHECK:       loop_a:
19; CHECK-NEXT:    call void @a()
20; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
21; CHECK:       loop_b:
22; CHECK-NEXT:    call void @b()
23; CHECK-NEXT:    br label [[LOOP_LATCH]]
24; CHECK:       loop_latch:
25; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1
26; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
27; CHECK:       loop_exit:
28; CHECK-NEXT:    ret void
29;
30entry:
31  br label %loop_begin
32loop_begin:
33  call void @x()
34  call void @x()
35  call void @x()
36  call void @x()
37  br i1 %cond, label %loop_a, label %loop_b
38
39loop_a:
40  call void @a()
41  br label %loop_latch
42
43loop_b:
44  call void @b()
45  br label %loop_latch
46
47loop_latch:
48  %v = load i1, ptr %ptr
49  br i1 %v, label %loop_begin, label %loop_exit
50
51loop_exit:
52  ret void
53}
54
55define void @test_unswitch(ptr %ptr, i1 %cond) {
56; CHECK-LABEL: @test_unswitch(
57; CHECK-NEXT:  entry:
58; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
59; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
60; CHECK:       entry.split.us:
61; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
62; CHECK:       loop_begin.us:
63; CHECK-NEXT:    call void @x()
64; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
65; CHECK:       loop_a.us:
66; CHECK-NEXT:    call void @a()
67; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
68; CHECK:       loop_latch.us:
69; CHECK-NEXT:    [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1
70; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
71; CHECK:       loop_exit.split.us:
72; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
73; CHECK:       entry.split:
74; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
75; CHECK:       loop_begin:
76; CHECK-NEXT:    call void @x()
77; CHECK-NEXT:    br label [[LOOP_B:%.*]]
78; CHECK:       loop_b:
79; CHECK-NEXT:    call void @b()
80; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
81; CHECK:       loop_latch:
82; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR]], align 1
83; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
84; CHECK:       loop_exit.split:
85; CHECK-NEXT:    br label [[LOOP_EXIT]]
86; CHECK:       loop_exit:
87; CHECK-NEXT:    ret void
88;
89entry:
90  br label %loop_begin
91
92loop_begin:
93  call void @x()
94  br i1 %cond, label %loop_a, label %loop_b
95
96loop_a:
97  call void @a()
98  br label %loop_latch
99
100loop_b:
101  call void @b()
102  br label %loop_latch
103
104loop_latch:
105  %v = load i1, ptr %ptr
106  br i1 %v, label %loop_begin, label %loop_exit
107
108loop_exit:
109  ret void
110}
111
112define void @test_unswitch_minsize(ptr %ptr, i1 %cond) #0 {
113; CHECK-LABEL: @test_unswitch_minsize(
114; CHECK-NEXT:  entry:
115; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
116; CHECK:       loop_begin:
117; CHECK-NEXT:    call void @x()
118; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
119; CHECK:       loop_a:
120; CHECK-NEXT:    call void @a()
121; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
122; CHECK:       loop_b:
123; CHECK-NEXT:    call void @b()
124; CHECK-NEXT:    br label [[LOOP_LATCH]]
125; CHECK:       loop_latch:
126; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1
127; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
128; CHECK:       loop_exit:
129; CHECK-NEXT:    ret void
130;
131entry:
132  br label %loop_begin
133
134loop_begin:
135  call void @x()
136  br i1 %cond, label %loop_a, label %loop_b
137
138loop_a:
139  call void @a()
140  br label %loop_latch
141
142loop_b:
143  call void @b()
144  br label %loop_latch
145
146loop_latch:
147  %v = load i1, ptr %ptr
148  br i1 %v, label %loop_begin, label %loop_exit
149
150loop_exit:
151  ret void
152}
153
154define void @test_unswitch_non_dup_code(ptr %ptr, i1 %cond) {
155; CHECK-LABEL: @test_unswitch_non_dup_code(
156; CHECK-NEXT:  entry:
157; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
158; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
159; CHECK:       entry.split.us:
160; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
161; CHECK:       loop_begin.us:
162; CHECK-NEXT:    call void @x()
163; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
164; CHECK:       loop_a.us:
165; CHECK-NEXT:    call void @a()
166; CHECK-NEXT:    call void @a()
167; CHECK-NEXT:    call void @a()
168; CHECK-NEXT:    call void @a()
169; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
170; CHECK:       loop_latch.us:
171; CHECK-NEXT:    [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1
172; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
173; CHECK:       loop_exit.split.us:
174; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
175; CHECK:       entry.split:
176; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
177; CHECK:       loop_begin:
178; CHECK-NEXT:    call void @x()
179; CHECK-NEXT:    br label [[LOOP_B:%.*]]
180; CHECK:       loop_b:
181; CHECK-NEXT:    call void @b()
182; CHECK-NEXT:    call void @b()
183; CHECK-NEXT:    call void @b()
184; CHECK-NEXT:    call void @b()
185; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
186; CHECK:       loop_latch:
187; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR]], align 1
188; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
189; CHECK:       loop_exit.split:
190; CHECK-NEXT:    br label [[LOOP_EXIT]]
191; CHECK:       loop_exit:
192; CHECK-NEXT:    ret void
193;
194entry:
195  br label %loop_begin
196
197loop_begin:
198  call void @x()
199  br i1 %cond, label %loop_a, label %loop_b
200
201loop_a:
202  call void @a()
203  call void @a()
204  call void @a()
205  call void @a()
206  br label %loop_latch
207
208loop_b:
209  call void @b()
210  call void @b()
211  call void @b()
212  call void @b()
213  br label %loop_latch
214
215loop_latch:
216  %v = load i1, ptr %ptr
217  br i1 %v, label %loop_begin, label %loop_exit
218
219loop_exit:
220  ret void
221}
222
223define void @test_unswitch_non_dup_code_minsize(ptr %ptr, i1 %cond) #0 {
224; CHECK-LABEL: @test_unswitch_non_dup_code_minsize(
225; CHECK-NEXT:  entry:
226; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
227; CHECK:       loop_begin:
228; CHECK-NEXT:    call void @x()
229; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
230; CHECK:       loop_a:
231; CHECK-NEXT:    call void @a()
232; CHECK-NEXT:    call void @a()
233; CHECK-NEXT:    call void @a()
234; CHECK-NEXT:    call void @a()
235; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
236; CHECK:       loop_b:
237; CHECK-NEXT:    call void @b()
238; CHECK-NEXT:    call void @b()
239; CHECK-NEXT:    call void @b()
240; CHECK-NEXT:    call void @b()
241; CHECK-NEXT:    br label [[LOOP_LATCH]]
242; CHECK:       loop_latch:
243; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1
244; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
245; CHECK:       loop_exit:
246; CHECK-NEXT:    ret void
247;
248entry:
249  br label %loop_begin
250
251loop_begin:
252  call void @x()
253  br i1 %cond, label %loop_a, label %loop_b
254
255loop_a:
256  call void @a()
257  call void @a()
258  call void @a()
259  call void @a()
260  br label %loop_latch
261
262loop_b:
263  call void @b()
264  call void @b()
265  call void @b()
266  call void @b()
267  br label %loop_latch
268
269loop_latch:
270  %v = load i1, ptr %ptr
271  br i1 %v, label %loop_begin, label %loop_exit
272
273loop_exit:
274  ret void
275}
276
277define void @test_unswitch_non_dup_code_in_cfg(ptr %ptr, i1 %cond) {
278; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg(
279; CHECK-NEXT:  entry:
280; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
281; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
282; CHECK:       entry.split.us:
283; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
284; CHECK:       loop_begin.us:
285; CHECK-NEXT:    call void @x()
286; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
287; CHECK:       loop_a.us:
288; CHECK-NEXT:    [[V1_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1
289; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_A_US:%.*]], label [[LOOP_A_B_US:%.*]]
290; CHECK:       loop_a_b.us:
291; CHECK-NEXT:    call void @a()
292; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
293; CHECK:       loop_a_a.us:
294; CHECK-NEXT:    call void @a()
295; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
296; CHECK:       loop_latch.us:
297; CHECK-NEXT:    [[V3_US:%.*]] = load i1, ptr [[PTR]], align 1
298; CHECK-NEXT:    br i1 [[V3_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
299; CHECK:       loop_exit.split.us:
300; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
301; CHECK:       entry.split:
302; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
303; CHECK:       loop_begin:
304; CHECK-NEXT:    call void @x()
305; CHECK-NEXT:    br label [[LOOP_B:%.*]]
306; CHECK:       loop_b:
307; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1
308; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]]
309; CHECK:       loop_b_a:
310; CHECK-NEXT:    call void @b()
311; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
312; CHECK:       loop_b_b:
313; CHECK-NEXT:    call void @b()
314; CHECK-NEXT:    br label [[LOOP_LATCH]]
315; CHECK:       loop_latch:
316; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1
317; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
318; CHECK:       loop_exit.split:
319; CHECK-NEXT:    br label [[LOOP_EXIT]]
320; CHECK:       loop_exit:
321; CHECK-NEXT:    ret void
322;
323entry:
324  br label %loop_begin
325
326loop_begin:
327  call void @x()
328  br i1 %cond, label %loop_a, label %loop_b
329
330loop_a:
331  %v1 = load i1, ptr %ptr
332  br i1 %v1, label %loop_a_a, label %loop_a_b
333
334loop_a_a:
335  call void @a()
336  br label %loop_latch
337
338loop_a_b:
339  call void @a()
340  br label %loop_latch
341
342loop_b:
343  %v2 = load i1, ptr %ptr
344  br i1 %v2, label %loop_b_a, label %loop_b_b
345
346loop_b_a:
347  call void @b()
348  br label %loop_latch
349
350loop_b_b:
351  call void @b()
352  br label %loop_latch
353
354loop_latch:
355  %v3 = load i1, ptr %ptr
356  br i1 %v3, label %loop_begin, label %loop_exit
357
358loop_exit:
359  ret void
360}
361
362define void @test_unswitch_non_dup_code_in_cfg_minsize(ptr %ptr, i1 %cond) #0 {
363; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg_minsize(
364; CHECK-NEXT:  entry:
365; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
366; CHECK:       loop_begin:
367; CHECK-NEXT:    call void @x()
368; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
369; CHECK:       loop_a:
370; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1
371; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]]
372; CHECK:       loop_a_a:
373; CHECK-NEXT:    call void @a()
374; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
375; CHECK:       loop_a_b:
376; CHECK-NEXT:    call void @a()
377; CHECK-NEXT:    br label [[LOOP_LATCH]]
378; CHECK:       loop_b:
379; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1
380; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]]
381; CHECK:       loop_b_a:
382; CHECK-NEXT:    call void @b()
383; CHECK-NEXT:    br label [[LOOP_LATCH]]
384; CHECK:       loop_b_b:
385; CHECK-NEXT:    call void @b()
386; CHECK-NEXT:    br label [[LOOP_LATCH]]
387; CHECK:       loop_latch:
388; CHECK-NEXT:    [[V3:%.*]] = load i1, ptr [[PTR]], align 1
389; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
390; CHECK:       loop_exit:
391; CHECK-NEXT:    ret void
392;
393entry:
394  br label %loop_begin
395
396loop_begin:
397  call void @x()
398  br i1 %cond, label %loop_a, label %loop_b
399
400loop_a:
401  %v1 = load i1, ptr %ptr
402  br i1 %v1, label %loop_a_a, label %loop_a_b
403
404loop_a_a:
405  call void @a()
406  br label %loop_latch
407
408loop_a_b:
409  call void @a()
410  br label %loop_latch
411
412loop_b:
413  %v2 = load i1, ptr %ptr
414  br i1 %v2, label %loop_b_a, label %loop_b_b
415
416loop_b_a:
417  call void @b()
418  br label %loop_latch
419
420loop_b_b:
421  call void @b()
422  br label %loop_latch
423
424loop_latch:
425  %v3 = load i1, ptr %ptr
426  br i1 %v3, label %loop_begin, label %loop_exit
427
428loop_exit:
429  ret void
430}
431
432define void @test_no_unswitch_non_dup_code(ptr %ptr, i1 %cond) {
433; CHECK-LABEL: @test_no_unswitch_non_dup_code(
434; CHECK-NEXT:  entry:
435; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
436; CHECK:       loop_begin:
437; CHECK-NEXT:    call void @x()
438; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
439; CHECK:       loop_a:
440; CHECK-NEXT:    [[V1:%.*]] = load i1, ptr [[PTR:%.*]], align 1
441; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]]
442; CHECK:       loop_a_a:
443; CHECK-NEXT:    call void @a()
444; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
445; CHECK:       loop_a_b:
446; CHECK-NEXT:    call void @a()
447; CHECK-NEXT:    br label [[LOOP_LATCH]]
448; CHECK:       loop_b:
449; CHECK-NEXT:    [[V2:%.*]] = load i1, ptr [[PTR]], align 1
450; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]]
451; CHECK:       loop_b_a:
452; CHECK-NEXT:    call void @b()
453; CHECK-NEXT:    br label [[LOOP_LATCH]]
454; CHECK:       loop_b_b:
455; CHECK-NEXT:    call void @b()
456; CHECK-NEXT:    br label [[LOOP_LATCH]]
457; CHECK:       loop_latch:
458; CHECK-NEXT:    call void @x()
459; CHECK-NEXT:    call void @x()
460; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR]], align 1
461; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
462; CHECK:       loop_exit:
463; CHECK-NEXT:    ret void
464;
465entry:
466  br label %loop_begin
467
468loop_begin:
469  call void @x()
470  br i1 %cond, label %loop_a, label %loop_b
471
472loop_a:
473  %v1 = load i1, ptr %ptr
474  br i1 %v1, label %loop_a_a, label %loop_a_b
475
476loop_a_a:
477  call void @a()
478  br label %loop_latch
479
480loop_a_b:
481  call void @a()
482  br label %loop_latch
483
484loop_b:
485  %v2 = load i1, ptr %ptr
486  br i1 %v2, label %loop_b_a, label %loop_b_b
487
488loop_b_a:
489  call void @b()
490  br label %loop_latch
491
492loop_b_b:
493  call void @b()
494  br label %loop_latch
495
496loop_latch:
497  call void @x()
498  call void @x()
499  %v = load i1, ptr %ptr
500  br i1 %v, label %loop_begin, label %loop_exit
501
502loop_exit:
503  ret void
504}
505
506define void @test_unswitch_large_exit(ptr %ptr, i1 %cond) {
507; CHECK-LABEL: @test_unswitch_large_exit(
508; CHECK-NEXT:  entry:
509; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
510; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
511; CHECK:       entry.split.us:
512; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
513; CHECK:       loop_begin.us:
514; CHECK-NEXT:    call void @x()
515; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
516; CHECK:       loop_a.us:
517; CHECK-NEXT:    call void @a()
518; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
519; CHECK:       loop_latch.us:
520; CHECK-NEXT:    [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1
521; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
522; CHECK:       loop_exit.split.us:
523; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
524; CHECK:       entry.split:
525; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
526; CHECK:       loop_begin:
527; CHECK-NEXT:    call void @x()
528; CHECK-NEXT:    br label [[LOOP_B:%.*]]
529; CHECK:       loop_b:
530; CHECK-NEXT:    call void @b()
531; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
532; CHECK:       loop_latch:
533; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR]], align 1
534; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
535; CHECK:       loop_exit.split:
536; CHECK-NEXT:    br label [[LOOP_EXIT]]
537; CHECK:       loop_exit:
538; CHECK-NEXT:    call void @x()
539; CHECK-NEXT:    call void @x()
540; CHECK-NEXT:    call void @x()
541; CHECK-NEXT:    call void @x()
542; CHECK-NEXT:    ret void
543;
544entry:
545  br label %loop_begin
546
547loop_begin:
548  call void @x()
549  br i1 %cond, label %loop_a, label %loop_b
550
551loop_a:
552  call void @a()
553  br label %loop_latch
554
555loop_b:
556  call void @b()
557  br label %loop_latch
558
559loop_latch:
560  %v = load i1, ptr %ptr
561  br i1 %v, label %loop_begin, label %loop_exit
562
563loop_exit:
564  call void @x()
565  call void @x()
566  call void @x()
567  call void @x()
568  ret void
569}
570
571define void @test_unswitch_dedicated_exiting(ptr %ptr, i1 %cond) {
572; CHECK-LABEL: @test_unswitch_dedicated_exiting(
573; CHECK-NEXT:  entry:
574; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 [[COND:%.*]]
575; CHECK-NEXT:    br i1 [[COND_FR]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
576; CHECK:       entry.split.us:
577; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
578; CHECK:       loop_begin.us:
579; CHECK-NEXT:    call void @x()
580; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
581; CHECK:       loop_a.us:
582; CHECK-NEXT:    call void @a()
583; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
584; CHECK:       loop_latch.us:
585; CHECK-NEXT:    [[V_US:%.*]] = load i1, ptr [[PTR:%.*]], align 1
586; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
587; CHECK:       loop_exit.split.us:
588; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
589; CHECK:       entry.split:
590; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
591; CHECK:       loop_begin:
592; CHECK-NEXT:    call void @x()
593; CHECK-NEXT:    br label [[LOOP_B_EXIT:%.*]]
594; CHECK:       loop_b_exit:
595; CHECK-NEXT:    call void @b()
596; CHECK-NEXT:    call void @b()
597; CHECK-NEXT:    call void @b()
598; CHECK-NEXT:    call void @b()
599; CHECK-NEXT:    ret void
600; CHECK:       loop_exit:
601; CHECK-NEXT:    ret void
602;
603entry:
604  br label %loop_begin
605
606loop_begin:
607  call void @x()
608  br i1 %cond, label %loop_a, label %loop_b_exit
609
610loop_a:
611  call void @a()
612  br label %loop_latch
613
614loop_b_exit:
615  call void @b()
616  call void @b()
617  call void @b()
618  call void @b()
619  ret void
620
621loop_latch:
622  %v = load i1, ptr %ptr
623  br i1 %v, label %loop_begin, label %loop_exit
624
625loop_exit:
626  ret void
627}
628
629define void @test_unswitch_dedicated_exiting_minsize(ptr %ptr, i1 %cond) #0 {
630; CHECK-LABEL: @test_unswitch_dedicated_exiting_minsize(
631; CHECK-NEXT:  entry:
632; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
633; CHECK:       loop_begin:
634; CHECK-NEXT:    call void @x()
635; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B_EXIT:%.*]]
636; CHECK:       loop_a:
637; CHECK-NEXT:    call void @a()
638; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
639; CHECK:       loop_b_exit:
640; CHECK-NEXT:    call void @b()
641; CHECK-NEXT:    call void @b()
642; CHECK-NEXT:    call void @b()
643; CHECK-NEXT:    call void @b()
644; CHECK-NEXT:    ret void
645; CHECK:       loop_latch:
646; CHECK-NEXT:    [[V:%.*]] = load i1, ptr [[PTR:%.*]], align 1
647; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
648; CHECK:       loop_exit:
649; CHECK-NEXT:    ret void
650;
651entry:
652  br label %loop_begin
653
654loop_begin:
655  call void @x()
656  br i1 %cond, label %loop_a, label %loop_b_exit
657
658loop_a:
659  call void @a()
660  br label %loop_latch
661
662loop_b_exit:
663  call void @b()
664  call void @b()
665  call void @b()
666  call void @b()
667  ret void
668
669loop_latch:
670  %v = load i1, ptr %ptr
671  br i1 %v, label %loop_begin, label %loop_exit
672
673loop_exit:
674  ret void
675}
676
677attributes #0 = { minsize optsize }
678