[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / SimpleLoopUnswitch / ARM / nontrivial-unswitch-cost.ll
blobadf118ba7ea14dc32a49c6b9d032e913ed37850a
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
4 declare void @a()
5 declare void @b()
6 declare void @x()
8 define 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
30 entry:
31   br label %loop_begin
32 loop_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
39 loop_a:
40   call void @a()
41   br label %loop_latch
43 loop_b:
44   call void @b()
45   br label %loop_latch
47 loop_latch:
48   %v = load i1, ptr %ptr
49   br i1 %v, label %loop_begin, label %loop_exit
51 loop_exit:
52   ret void
55 define 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
89 entry:
90   br label %loop_begin
92 loop_begin:
93   call void @x()
94   br i1 %cond, label %loop_a, label %loop_b
96 loop_a:
97   call void @a()
98   br label %loop_latch
100 loop_b:
101   call void @b()
102   br label %loop_latch
104 loop_latch:
105   %v = load i1, ptr %ptr
106   br i1 %v, label %loop_begin, label %loop_exit
108 loop_exit:
109   ret void
112 define 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
131 entry:
132   br label %loop_begin
134 loop_begin:
135   call void @x()
136   br i1 %cond, label %loop_a, label %loop_b
138 loop_a:
139   call void @a()
140   br label %loop_latch
142 loop_b:
143   call void @b()
144   br label %loop_latch
146 loop_latch:
147   %v = load i1, ptr %ptr
148   br i1 %v, label %loop_begin, label %loop_exit
150 loop_exit:
151   ret void
154 define 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
194 entry:
195   br label %loop_begin
197 loop_begin:
198   call void @x()
199   br i1 %cond, label %loop_a, label %loop_b
201 loop_a:
202   call void @a()
203   call void @a()
204   call void @a()
205   call void @a()
206   br label %loop_latch
208 loop_b:
209   call void @b()
210   call void @b()
211   call void @b()
212   call void @b()
213   br label %loop_latch
215 loop_latch:
216   %v = load i1, ptr %ptr
217   br i1 %v, label %loop_begin, label %loop_exit
219 loop_exit:
220   ret void
223 define 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
248 entry:
249   br label %loop_begin
251 loop_begin:
252   call void @x()
253   br i1 %cond, label %loop_a, label %loop_b
255 loop_a:
256   call void @a()
257   call void @a()
258   call void @a()
259   call void @a()
260   br label %loop_latch
262 loop_b:
263   call void @b()
264   call void @b()
265   call void @b()
266   call void @b()
267   br label %loop_latch
269 loop_latch:
270   %v = load i1, ptr %ptr
271   br i1 %v, label %loop_begin, label %loop_exit
273 loop_exit:
274   ret void
277 define 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
323 entry:
324   br label %loop_begin
326 loop_begin:
327   call void @x()
328   br i1 %cond, label %loop_a, label %loop_b
330 loop_a:
331   %v1 = load i1, ptr %ptr
332   br i1 %v1, label %loop_a_a, label %loop_a_b
334 loop_a_a:
335   call void @a()
336   br label %loop_latch
338 loop_a_b:
339   call void @a()
340   br label %loop_latch
342 loop_b:
343   %v2 = load i1, ptr %ptr
344   br i1 %v2, label %loop_b_a, label %loop_b_b
346 loop_b_a:
347   call void @b()
348   br label %loop_latch
350 loop_b_b:
351   call void @b()
352   br label %loop_latch
354 loop_latch:
355   %v3 = load i1, ptr %ptr
356   br i1 %v3, label %loop_begin, label %loop_exit
358 loop_exit:
359   ret void
362 define 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
393 entry:
394   br label %loop_begin
396 loop_begin:
397   call void @x()
398   br i1 %cond, label %loop_a, label %loop_b
400 loop_a:
401   %v1 = load i1, ptr %ptr
402   br i1 %v1, label %loop_a_a, label %loop_a_b
404 loop_a_a:
405   call void @a()
406   br label %loop_latch
408 loop_a_b:
409   call void @a()
410   br label %loop_latch
412 loop_b:
413   %v2 = load i1, ptr %ptr
414   br i1 %v2, label %loop_b_a, label %loop_b_b
416 loop_b_a:
417   call void @b()
418   br label %loop_latch
420 loop_b_b:
421   call void @b()
422   br label %loop_latch
424 loop_latch:
425   %v3 = load i1, ptr %ptr
426   br i1 %v3, label %loop_begin, label %loop_exit
428 loop_exit:
429   ret void
432 define 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
465 entry:
466   br label %loop_begin
468 loop_begin:
469   call void @x()
470   br i1 %cond, label %loop_a, label %loop_b
472 loop_a:
473   %v1 = load i1, ptr %ptr
474   br i1 %v1, label %loop_a_a, label %loop_a_b
476 loop_a_a:
477   call void @a()
478   br label %loop_latch
480 loop_a_b:
481   call void @a()
482   br label %loop_latch
484 loop_b:
485   %v2 = load i1, ptr %ptr
486   br i1 %v2, label %loop_b_a, label %loop_b_b
488 loop_b_a:
489   call void @b()
490   br label %loop_latch
492 loop_b_b:
493   call void @b()
494   br label %loop_latch
496 loop_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
502 loop_exit:
503   ret void
506 define 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
544 entry:
545   br label %loop_begin
547 loop_begin:
548   call void @x()
549   br i1 %cond, label %loop_a, label %loop_b
551 loop_a:
552   call void @a()
553   br label %loop_latch
555 loop_b:
556   call void @b()
557   br label %loop_latch
559 loop_latch:
560   %v = load i1, ptr %ptr
561   br i1 %v, label %loop_begin, label %loop_exit
563 loop_exit:
564   call void @x()
565   call void @x()
566   call void @x()
567   call void @x()
568   ret void
571 define 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
603 entry:
604   br label %loop_begin
606 loop_begin:
607   call void @x()
608   br i1 %cond, label %loop_a, label %loop_b_exit
610 loop_a:
611   call void @a()
612   br label %loop_latch
614 loop_b_exit:
615   call void @b()
616   call void @b()
617   call void @b()
618   call void @b()
619   ret void
621 loop_latch:
622   %v = load i1, ptr %ptr
623   br i1 %v, label %loop_begin, label %loop_exit
625 loop_exit:
626   ret void
629 define 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
651 entry:
652   br label %loop_begin
654 loop_begin:
655   call void @x()
656   br i1 %cond, label %loop_a, label %loop_b_exit
658 loop_a:
659   call void @a()
660   br label %loop_latch
662 loop_b_exit:
663   call void @b()
664   call void @b()
665   call void @b()
666   call void @b()
667   ret void
669 loop_latch:
670   %v = load i1, ptr %ptr
671   br i1 %v, label %loop_begin, label %loop_exit
673 loop_exit:
674   ret void
677 attributes #0 = { minsize optsize }