[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / SimpleLoopUnswitch / ARM / nontrivial-unswitch-cost.ll
blob8482adec807ce08fb809bb59b02d7b188e8e9ce6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -mtriple=thumbv8m.main -simple-loop-unswitch -enable-nontrivial-unswitch -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(i1* %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, i1* [[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, i1* %ptr
49   br i1 %v, label %loop_begin, label %loop_exit
51 loop_exit:
52   ret void
55 define void @test_unswitch(i1* %ptr, i1 %cond) {
56 ; CHECK-LABEL: @test_unswitch(
57 ; CHECK-NEXT:  entry:
58 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
59 ; CHECK:       entry.split.us:
60 ; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
61 ; CHECK:       loop_begin.us:
62 ; CHECK-NEXT:    call void @x()
63 ; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
64 ; CHECK:       loop_a.us:
65 ; CHECK-NEXT:    call void @a()
66 ; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
67 ; CHECK:       loop_latch.us:
68 ; CHECK-NEXT:    [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
69 ; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
70 ; CHECK:       loop_exit.split.us:
71 ; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
72 ; CHECK:       entry.split:
73 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
74 ; CHECK:       loop_begin:
75 ; CHECK-NEXT:    call void @x()
76 ; CHECK-NEXT:    br label [[LOOP_B:%.*]]
77 ; CHECK:       loop_b:
78 ; CHECK-NEXT:    call void @b()
79 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
80 ; CHECK:       loop_latch:
81 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR]], align 1
82 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
83 ; CHECK:       loop_exit.split:
84 ; CHECK-NEXT:    br label [[LOOP_EXIT]]
85 ; CHECK:       loop_exit:
86 ; CHECK-NEXT:    ret void
88 entry:
89   br label %loop_begin
91 loop_begin:
92   call void @x()
93   br i1 %cond, label %loop_a, label %loop_b
95 loop_a:
96   call void @a()
97   br label %loop_latch
99 loop_b:
100   call void @b()
101   br label %loop_latch
103 loop_latch:
104   %v = load i1, i1* %ptr
105   br i1 %v, label %loop_begin, label %loop_exit
107 loop_exit:
108   ret void
111 define void @test_unswitch_minsize(i1* %ptr, i1 %cond) #0 {
112 ; CHECK-LABEL: @test_unswitch_minsize(
113 ; CHECK-NEXT:  entry:
114 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
115 ; CHECK:       loop_begin:
116 ; CHECK-NEXT:    call void @x()
117 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
118 ; CHECK:       loop_a:
119 ; CHECK-NEXT:    call void @a()
120 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
121 ; CHECK:       loop_b:
122 ; CHECK-NEXT:    call void @b()
123 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
124 ; CHECK:       loop_latch:
125 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR:%.*]], align 1
126 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
127 ; CHECK:       loop_exit:
128 ; CHECK-NEXT:    ret void
130 entry:
131   br label %loop_begin
133 loop_begin:
134   call void @x()
135   br i1 %cond, label %loop_a, label %loop_b
137 loop_a:
138   call void @a()
139   br label %loop_latch
141 loop_b:
142   call void @b()
143   br label %loop_latch
145 loop_latch:
146   %v = load i1, i1* %ptr
147   br i1 %v, label %loop_begin, label %loop_exit
149 loop_exit:
150   ret void
153 define void @test_unswitch_non_dup_code(i1* %ptr, i1 %cond) {
154 ; CHECK-LABEL: @test_unswitch_non_dup_code(
155 ; CHECK-NEXT:  entry:
156 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
157 ; CHECK:       entry.split.us:
158 ; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
159 ; CHECK:       loop_begin.us:
160 ; CHECK-NEXT:    call void @x()
161 ; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
162 ; CHECK:       loop_a.us:
163 ; CHECK-NEXT:    call void @a()
164 ; CHECK-NEXT:    call void @a()
165 ; CHECK-NEXT:    call void @a()
166 ; CHECK-NEXT:    call void @a()
167 ; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
168 ; CHECK:       loop_latch.us:
169 ; CHECK-NEXT:    [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
170 ; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
171 ; CHECK:       loop_exit.split.us:
172 ; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
173 ; CHECK:       entry.split:
174 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
175 ; CHECK:       loop_begin:
176 ; CHECK-NEXT:    call void @x()
177 ; CHECK-NEXT:    br label [[LOOP_B:%.*]]
178 ; CHECK:       loop_b:
179 ; CHECK-NEXT:    call void @b()
180 ; CHECK-NEXT:    call void @b()
181 ; CHECK-NEXT:    call void @b()
182 ; CHECK-NEXT:    call void @b()
183 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
184 ; CHECK:       loop_latch:
185 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR]], align 1
186 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
187 ; CHECK:       loop_exit.split:
188 ; CHECK-NEXT:    br label [[LOOP_EXIT]]
189 ; CHECK:       loop_exit:
190 ; CHECK-NEXT:    ret void
192 entry:
193   br label %loop_begin
195 loop_begin:
196   call void @x()
197   br i1 %cond, label %loop_a, label %loop_b
199 loop_a:
200   call void @a()
201   call void @a()
202   call void @a()
203   call void @a()
204   br label %loop_latch
206 loop_b:
207   call void @b()
208   call void @b()
209   call void @b()
210   call void @b()
211   br label %loop_latch
213 loop_latch:
214   %v = load i1, i1* %ptr
215   br i1 %v, label %loop_begin, label %loop_exit
217 loop_exit:
218   ret void
221 define void @test_unswitch_non_dup_code_minsize(i1* %ptr, i1 %cond) #0 {
222 ; CHECK-LABEL: @test_unswitch_non_dup_code_minsize(
223 ; CHECK-NEXT:  entry:
224 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
225 ; CHECK:       loop_begin:
226 ; CHECK-NEXT:    call void @x()
227 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
228 ; CHECK:       loop_a:
229 ; CHECK-NEXT:    call void @a()
230 ; CHECK-NEXT:    call void @a()
231 ; CHECK-NEXT:    call void @a()
232 ; CHECK-NEXT:    call void @a()
233 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
234 ; CHECK:       loop_b:
235 ; CHECK-NEXT:    call void @b()
236 ; CHECK-NEXT:    call void @b()
237 ; CHECK-NEXT:    call void @b()
238 ; CHECK-NEXT:    call void @b()
239 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
240 ; CHECK:       loop_latch:
241 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR:%.*]], align 1
242 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
243 ; CHECK:       loop_exit:
244 ; CHECK-NEXT:    ret void
246 entry:
247   br label %loop_begin
249 loop_begin:
250   call void @x()
251   br i1 %cond, label %loop_a, label %loop_b
253 loop_a:
254   call void @a()
255   call void @a()
256   call void @a()
257   call void @a()
258   br label %loop_latch
260 loop_b:
261   call void @b()
262   call void @b()
263   call void @b()
264   call void @b()
265   br label %loop_latch
267 loop_latch:
268   %v = load i1, i1* %ptr
269   br i1 %v, label %loop_begin, label %loop_exit
271 loop_exit:
272   ret void
275 define void @test_unswitch_non_dup_code_in_cfg(i1* %ptr, i1 %cond) {
276 ; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg(
277 ; CHECK-NEXT:  entry:
278 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
279 ; CHECK:       entry.split.us:
280 ; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
281 ; CHECK:       loop_begin.us:
282 ; CHECK-NEXT:    call void @x()
283 ; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
284 ; CHECK:       loop_a.us:
285 ; CHECK-NEXT:    [[V1_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
286 ; CHECK-NEXT:    br i1 [[V1_US]], label [[LOOP_A_A_US:%.*]], label [[LOOP_A_B_US:%.*]]
287 ; CHECK:       loop_a_b.us:
288 ; CHECK-NEXT:    call void @a()
289 ; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
290 ; CHECK:       loop_a_a.us:
291 ; CHECK-NEXT:    call void @a()
292 ; CHECK-NEXT:    br label [[LOOP_LATCH_US]]
293 ; CHECK:       loop_latch.us:
294 ; CHECK-NEXT:    [[V3_US:%.*]] = load i1, i1* [[PTR]], align 1
295 ; CHECK-NEXT:    br i1 [[V3_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
296 ; CHECK:       loop_exit.split.us:
297 ; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
298 ; CHECK:       entry.split:
299 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
300 ; CHECK:       loop_begin:
301 ; CHECK-NEXT:    call void @x()
302 ; CHECK-NEXT:    br label [[LOOP_B:%.*]]
303 ; CHECK:       loop_b:
304 ; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
305 ; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]]
306 ; CHECK:       loop_b_a:
307 ; CHECK-NEXT:    call void @b()
308 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
309 ; CHECK:       loop_b_b:
310 ; CHECK-NEXT:    call void @b()
311 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
312 ; CHECK:       loop_latch:
313 ; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
314 ; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
315 ; CHECK:       loop_exit.split:
316 ; CHECK-NEXT:    br label [[LOOP_EXIT]]
317 ; CHECK:       loop_exit:
318 ; CHECK-NEXT:    ret void
320 entry:
321   br label %loop_begin
323 loop_begin:
324   call void @x()
325   br i1 %cond, label %loop_a, label %loop_b
327 loop_a:
328   %v1 = load i1, i1* %ptr
329   br i1 %v1, label %loop_a_a, label %loop_a_b
331 loop_a_a:
332   call void @a()
333   br label %loop_latch
335 loop_a_b:
336   call void @a()
337   br label %loop_latch
339 loop_b:
340   %v2 = load i1, i1* %ptr
341   br i1 %v2, label %loop_b_a, label %loop_b_b
343 loop_b_a:
344   call void @b()
345   br label %loop_latch
347 loop_b_b:
348   call void @b()
349   br label %loop_latch
351 loop_latch:
352   %v3 = load i1, i1* %ptr
353   br i1 %v3, label %loop_begin, label %loop_exit
355 loop_exit:
356   ret void
359 define void @test_unswitch_non_dup_code_in_cfg_minsize(i1* %ptr, i1 %cond) #0 {
360 ; CHECK-LABEL: @test_unswitch_non_dup_code_in_cfg_minsize(
361 ; CHECK-NEXT:  entry:
362 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
363 ; CHECK:       loop_begin:
364 ; CHECK-NEXT:    call void @x()
365 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
366 ; CHECK:       loop_a:
367 ; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1
368 ; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]]
369 ; CHECK:       loop_a_a:
370 ; CHECK-NEXT:    call void @a()
371 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
372 ; CHECK:       loop_a_b:
373 ; CHECK-NEXT:    call void @a()
374 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
375 ; CHECK:       loop_b:
376 ; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
377 ; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]]
378 ; CHECK:       loop_b_a:
379 ; CHECK-NEXT:    call void @b()
380 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
381 ; CHECK:       loop_b_b:
382 ; CHECK-NEXT:    call void @b()
383 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
384 ; CHECK:       loop_latch:
385 ; CHECK-NEXT:    [[V3:%.*]] = load i1, i1* [[PTR]], align 1
386 ; CHECK-NEXT:    br i1 [[V3]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
387 ; CHECK:       loop_exit:
388 ; CHECK-NEXT:    ret void
390 entry:
391   br label %loop_begin
393 loop_begin:
394   call void @x()
395   br i1 %cond, label %loop_a, label %loop_b
397 loop_a:
398   %v1 = load i1, i1* %ptr
399   br i1 %v1, label %loop_a_a, label %loop_a_b
401 loop_a_a:
402   call void @a()
403   br label %loop_latch
405 loop_a_b:
406   call void @a()
407   br label %loop_latch
409 loop_b:
410   %v2 = load i1, i1* %ptr
411   br i1 %v2, label %loop_b_a, label %loop_b_b
413 loop_b_a:
414   call void @b()
415   br label %loop_latch
417 loop_b_b:
418   call void @b()
419   br label %loop_latch
421 loop_latch:
422   %v3 = load i1, i1* %ptr
423   br i1 %v3, label %loop_begin, label %loop_exit
425 loop_exit:
426   ret void
429 define void @test_no_unswitch_non_dup_code(i1* %ptr, i1 %cond) {
430 ; CHECK-LABEL: @test_no_unswitch_non_dup_code(
431 ; CHECK-NEXT:  entry:
432 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
433 ; CHECK:       loop_begin:
434 ; CHECK-NEXT:    call void @x()
435 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B:%.*]]
436 ; CHECK:       loop_a:
437 ; CHECK-NEXT:    [[V1:%.*]] = load i1, i1* [[PTR:%.*]], align 1
438 ; CHECK-NEXT:    br i1 [[V1]], label [[LOOP_A_A:%.*]], label [[LOOP_A_B:%.*]]
439 ; CHECK:       loop_a_a:
440 ; CHECK-NEXT:    call void @a()
441 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
442 ; CHECK:       loop_a_b:
443 ; CHECK-NEXT:    call void @a()
444 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
445 ; CHECK:       loop_b:
446 ; CHECK-NEXT:    [[V2:%.*]] = load i1, i1* [[PTR]], align 1
447 ; CHECK-NEXT:    br i1 [[V2]], label [[LOOP_B_A:%.*]], label [[LOOP_B_B:%.*]]
448 ; CHECK:       loop_b_a:
449 ; CHECK-NEXT:    call void @b()
450 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
451 ; CHECK:       loop_b_b:
452 ; CHECK-NEXT:    call void @b()
453 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
454 ; CHECK:       loop_latch:
455 ; CHECK-NEXT:    call void @x()
456 ; CHECK-NEXT:    call void @x()
457 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR]], align 1
458 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
459 ; CHECK:       loop_exit:
460 ; CHECK-NEXT:    ret void
462 entry:
463   br label %loop_begin
465 loop_begin:
466   call void @x()
467   br i1 %cond, label %loop_a, label %loop_b
469 loop_a:
470   %v1 = load i1, i1* %ptr
471   br i1 %v1, label %loop_a_a, label %loop_a_b
473 loop_a_a:
474   call void @a()
475   br label %loop_latch
477 loop_a_b:
478   call void @a()
479   br label %loop_latch
481 loop_b:
482   %v2 = load i1, i1* %ptr
483   br i1 %v2, label %loop_b_a, label %loop_b_b
485 loop_b_a:
486   call void @b()
487   br label %loop_latch
489 loop_b_b:
490   call void @b()
491   br label %loop_latch
493 loop_latch:
494   call void @x()
495   call void @x()
496   %v = load i1, i1* %ptr
497   br i1 %v, label %loop_begin, label %loop_exit
499 loop_exit:
500   ret void
503 define void @test_unswitch_large_exit(i1* %ptr, i1 %cond) {
504 ; CHECK-LABEL: @test_unswitch_large_exit(
505 ; CHECK-NEXT:  entry:
506 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
507 ; CHECK:       entry.split.us:
508 ; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
509 ; CHECK:       loop_begin.us:
510 ; CHECK-NEXT:    call void @x()
511 ; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
512 ; CHECK:       loop_a.us:
513 ; CHECK-NEXT:    call void @a()
514 ; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
515 ; CHECK:       loop_latch.us:
516 ; CHECK-NEXT:    [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
517 ; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
518 ; CHECK:       loop_exit.split.us:
519 ; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
520 ; CHECK:       entry.split:
521 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
522 ; CHECK:       loop_begin:
523 ; CHECK-NEXT:    call void @x()
524 ; CHECK-NEXT:    br label [[LOOP_B:%.*]]
525 ; CHECK:       loop_b:
526 ; CHECK-NEXT:    call void @b()
527 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
528 ; CHECK:       loop_latch:
529 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR]], align 1
530 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT_SPLIT:%.*]]
531 ; CHECK:       loop_exit.split:
532 ; CHECK-NEXT:    br label [[LOOP_EXIT]]
533 ; CHECK:       loop_exit:
534 ; CHECK-NEXT:    call void @x()
535 ; CHECK-NEXT:    call void @x()
536 ; CHECK-NEXT:    call void @x()
537 ; CHECK-NEXT:    call void @x()
538 ; CHECK-NEXT:    ret void
540 entry:
541   br label %loop_begin
543 loop_begin:
544   call void @x()
545   br i1 %cond, label %loop_a, label %loop_b
547 loop_a:
548   call void @a()
549   br label %loop_latch
551 loop_b:
552   call void @b()
553   br label %loop_latch
555 loop_latch:
556   %v = load i1, i1* %ptr
557   br i1 %v, label %loop_begin, label %loop_exit
559 loop_exit:
560   call void @x()
561   call void @x()
562   call void @x()
563   call void @x()
564   ret void
567 define void @test_unswitch_dedicated_exiting(i1* %ptr, i1 %cond) {
568 ; CHECK-LABEL: @test_unswitch_dedicated_exiting(
569 ; CHECK-NEXT:  entry:
570 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]]
571 ; CHECK:       entry.split.us:
572 ; CHECK-NEXT:    br label [[LOOP_BEGIN_US:%.*]]
573 ; CHECK:       loop_begin.us:
574 ; CHECK-NEXT:    call void @x()
575 ; CHECK-NEXT:    br label [[LOOP_A_US:%.*]]
576 ; CHECK:       loop_a.us:
577 ; CHECK-NEXT:    call void @a()
578 ; CHECK-NEXT:    br label [[LOOP_LATCH_US:%.*]]
579 ; CHECK:       loop_latch.us:
580 ; CHECK-NEXT:    [[V_US:%.*]] = load i1, i1* [[PTR:%.*]], align 1
581 ; CHECK-NEXT:    br i1 [[V_US]], label [[LOOP_BEGIN_US]], label [[LOOP_EXIT_SPLIT_US:%.*]]
582 ; CHECK:       loop_exit.split.us:
583 ; CHECK-NEXT:    br label [[LOOP_EXIT:%.*]]
584 ; CHECK:       entry.split:
585 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
586 ; CHECK:       loop_begin:
587 ; CHECK-NEXT:    call void @x()
588 ; CHECK-NEXT:    br label [[LOOP_B_EXIT:%.*]]
589 ; CHECK:       loop_b_exit:
590 ; CHECK-NEXT:    call void @b()
591 ; CHECK-NEXT:    call void @b()
592 ; CHECK-NEXT:    call void @b()
593 ; CHECK-NEXT:    call void @b()
594 ; CHECK-NEXT:    ret void
595 ; CHECK:       loop_exit:
596 ; CHECK-NEXT:    ret void
598 entry:
599   br label %loop_begin
601 loop_begin:
602   call void @x()
603   br i1 %cond, label %loop_a, label %loop_b_exit
605 loop_a:
606   call void @a()
607   br label %loop_latch
609 loop_b_exit:
610   call void @b()
611   call void @b()
612   call void @b()
613   call void @b()
614   ret void
616 loop_latch:
617   %v = load i1, i1* %ptr
618   br i1 %v, label %loop_begin, label %loop_exit
620 loop_exit:
621   ret void
624 define void @test_unswitch_dedicated_exiting_minsize(i1* %ptr, i1 %cond) #0 {
625 ; CHECK-LABEL: @test_unswitch_dedicated_exiting_minsize(
626 ; CHECK-NEXT:  entry:
627 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
628 ; CHECK:       loop_begin:
629 ; CHECK-NEXT:    call void @x()
630 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[LOOP_A:%.*]], label [[LOOP_B_EXIT:%.*]]
631 ; CHECK:       loop_a:
632 ; CHECK-NEXT:    call void @a()
633 ; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
634 ; CHECK:       loop_b_exit:
635 ; CHECK-NEXT:    call void @b()
636 ; CHECK-NEXT:    call void @b()
637 ; CHECK-NEXT:    call void @b()
638 ; CHECK-NEXT:    call void @b()
639 ; CHECK-NEXT:    ret void
640 ; CHECK:       loop_latch:
641 ; CHECK-NEXT:    [[V:%.*]] = load i1, i1* [[PTR:%.*]], align 1
642 ; CHECK-NEXT:    br i1 [[V]], label [[LOOP_BEGIN]], label [[LOOP_EXIT:%.*]]
643 ; CHECK:       loop_exit:
644 ; CHECK-NEXT:    ret void
646 entry:
647   br label %loop_begin
649 loop_begin:
650   call void @x()
651   br i1 %cond, label %loop_a, label %loop_b_exit
653 loop_a:
654   call void @a()
655   br label %loop_latch
657 loop_b_exit:
658   call void @b()
659   call void @b()
660   call void @b()
661   call void @b()
662   ret void
664 loop_latch:
665   %v = load i1, i1* %ptr
666   br i1 %v, label %loop_begin, label %loop_exit
668 loop_exit:
669   ret void
672 attributes #0 = { minsize optsize }