xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/switch-on-cmp.ll (revision 4d85285ff68d11fcb8c6b296799a11074e7ff7d7)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3
4define void @ucmp_gt1(i32 %a, i32 %b) {
5; CHECK-LABEL: define void @ucmp_gt1(
6; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
7; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]]
8; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
9; CHECK:       [[BB1]]:
10; CHECK-NEXT:    call void @foo()
11; CHECK-NEXT:    br label %[[BB2]]
12; CHECK:       [[BB2]]:
13; CHECK-NEXT:    ret void
14;
15  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
16  switch i8 %res, label %bb1 [
17  i8 -1, label %bb2
18  i8 0, label %bb2
19  ]
20
21bb1:
22  call void @foo()
23  br label %bb2
24
25bb2:
26  ret void
27}
28
29define void @ucmp_gt2(i32 %a, i32 %b) {
30; CHECK-LABEL: define void @ucmp_gt2(
31; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
32; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]]
33; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
34; CHECK:       [[BB1]]:
35; CHECK-NEXT:    call void @foo()
36; CHECK-NEXT:    br label %[[BB2]]
37; CHECK:       [[BB2]]:
38; CHECK-NEXT:    ret void
39;
40  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
41  switch i8 %res, label %bb1 [
42  i8 0, label %bb2
43  i8 -1, label %bb2
44  ]
45
46bb1:
47  call void @foo()
48  br label %bb2
49
50bb2:
51  ret void
52}
53
54define void @ucmp_lt1(i32 %a, i32 %b) {
55; CHECK-LABEL: define void @ucmp_lt1(
56; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
57; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A]], [[B]]
58; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB1:.*]]
59; CHECK:       [[BB1]]:
60; CHECK-NEXT:    call void @foo()
61; CHECK-NEXT:    br label %[[BB2]]
62; CHECK:       [[BB2]]:
63; CHECK-NEXT:    ret void
64;
65  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
66  switch i8 %res, label %bb2 [
67  i8 1, label %bb1
68  i8 0, label %bb1
69  ]
70
71bb1:
72  call void @foo()
73  br label %bb2
74
75bb2:
76  ret void
77}
78
79define void @ucmp_lt2(i32 %a, i32 %b) {
80; CHECK-LABEL: define void @ucmp_lt2(
81; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
82; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A]], [[B]]
83; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB2:.*]], label %[[BB1:.*]]
84; CHECK:       [[BB1]]:
85; CHECK-NEXT:    call void @foo()
86; CHECK-NEXT:    br label %[[BB2]]
87; CHECK:       [[BB2]]:
88; CHECK-NEXT:    ret void
89;
90  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
91  switch i8 %res, label %bb2 [
92  i8 0, label %bb1
93  i8 1, label %bb1
94  ]
95
96bb1:
97  call void @foo()
98  br label %bb2
99
100bb2:
101  ret void
102}
103
104define void @ucmp_eq1(i32 %a, i32 %b) {
105; CHECK-LABEL: define void @ucmp_eq1(
106; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
107; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A]], [[B]]
108; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
109; CHECK:       [[BB1]]:
110; CHECK-NEXT:    call void @foo()
111; CHECK-NEXT:    br label %[[BB2]]
112; CHECK:       [[BB2]]:
113; CHECK-NEXT:    ret void
114;
115  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
116  switch i8 %res, label %bb1 [
117  i8 -1, label %bb2
118  i8 1, label %bb2
119  ]
120
121bb1:
122  call void @foo()
123  br label %bb2
124
125bb2:
126  ret void
127}
128
129define void @ucmp_eq2(i32 %a, i32 %b) {
130; CHECK-LABEL: define void @ucmp_eq2(
131; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
132; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A]], [[B]]
133; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
134; CHECK:       [[BB1]]:
135; CHECK-NEXT:    call void @foo()
136; CHECK-NEXT:    br label %[[BB2]]
137; CHECK:       [[BB2]]:
138; CHECK-NEXT:    ret void
139;
140  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
141  switch i8 %res, label %bb1 [
142  i8 1, label %bb2
143  i8 -1, label %bb2
144  ]
145
146bb1:
147  call void @foo()
148  br label %bb2
149
150bb2:
151  ret void
152}
153
154define void @scmp_gt1(i32 %a, i32 %b) {
155; CHECK-LABEL: define void @scmp_gt1(
156; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
157; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A]], [[B]]
158; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
159; CHECK:       [[BB1]]:
160; CHECK-NEXT:    call void @foo()
161; CHECK-NEXT:    br label %[[BB2]]
162; CHECK:       [[BB2]]:
163; CHECK-NEXT:    ret void
164;
165  %res = call i8 @llvm.scmp.i8.i32(i32 %a, i32 %b)
166  switch i8 %res, label %bb1 [
167  i8 -1, label %bb2
168  i8 0, label %bb2
169  ]
170
171bb1:
172  call void @foo()
173  br label %bb2
174
175bb2:
176  ret void
177}
178
179define void @scmp_gt2(i32 %a, i32 %b) {
180; CHECK-LABEL: define void @scmp_gt2(
181; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
182; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[A]], [[B]]
183; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
184; CHECK:       [[BB1]]:
185; CHECK-NEXT:    call void @foo()
186; CHECK-NEXT:    br label %[[BB2]]
187; CHECK:       [[BB2]]:
188; CHECK-NEXT:    ret void
189;
190  %res = call i8 @llvm.scmp.i8.i32(i32 %a, i32 %b)
191  switch i8 %res, label %bb1 [
192  i8 0, label %bb2
193  i8 -1, label %bb2
194  ]
195
196bb1:
197  call void @foo()
198  br label %bb2
199
200bb2:
201  ret void
202}
203
204define void @ucmp_gt_multiuse(i32 %a, i32 %b) {
205; CHECK-LABEL: define void @ucmp_gt_multiuse(
206; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
207; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
208; CHECK-NEXT:    call void @use(i8 [[RES]])
209; CHECK-NEXT:    switch i8 [[RES]], label %[[BB1:.*]] [
210; CHECK-NEXT:      i8 -1, label %[[BB2:.*]]
211; CHECK-NEXT:      i8 0, label %[[BB2]]
212; CHECK-NEXT:    ]
213; CHECK:       [[BB1]]:
214; CHECK-NEXT:    call void @foo()
215; CHECK-NEXT:    br label %[[BB2]]
216; CHECK:       [[BB2]]:
217; CHECK-NEXT:    ret void
218;
219  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
220  call void @use(i8 %res)
221  switch i8 %res, label %bb1 [
222  i8 -1, label %bb2
223  i8 0, label %bb2
224  ]
225
226bb1:
227  call void @foo()
228  br label %bb2
229
230bb2:
231  ret void
232}
233
234define i32 @ucmp_gt_phi(i32 %a, i32 %b) {
235; CHECK-LABEL: define i32 @ucmp_gt_phi(
236; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
237; CHECK-NEXT:  [[ENTRY:.*]]:
238; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[A]], [[B]]
239; CHECK-NEXT:    br i1 [[TMP0]], label %[[BB1:.*]], label %[[BB2:.*]]
240; CHECK:       [[BB1]]:
241; CHECK-NEXT:    call void @foo()
242; CHECK-NEXT:    br label %[[BB2]]
243; CHECK:       [[BB2]]:
244; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, %[[BB1]] ], [ 1, %[[ENTRY]] ]
245; CHECK-NEXT:    ret i32 [[PHI]]
246;
247entry:
248  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
249  switch i8 %res, label %bb1 [
250  i8 -1, label %bb2
251  i8 0, label %bb2
252  ]
253
254bb1:
255  call void @foo()
256  br label %bb2
257
258bb2:
259  %phi = phi i32 [ 0, %bb1 ], [ 1, %entry ], [ 1, %entry ]
260  ret i32 %phi
261}
262
263define void @ucmp_gt_extra_case(i32 %a, i32 %b) {
264; CHECK-LABEL: define void @ucmp_gt_extra_case(
265; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
266; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
267; CHECK-NEXT:    switch i8 [[RES]], label %[[BB1:.*]] [
268; CHECK-NEXT:      i8 -1, label %[[BB2:.*]]
269; CHECK-NEXT:      i8 0, label %[[BB2]]
270; CHECK-NEXT:      i8 1, label %[[BB2]]
271; CHECK-NEXT:    ]
272; CHECK:       [[BB1]]:
273; CHECK-NEXT:    call void @foo()
274; CHECK-NEXT:    br label %[[BB2]]
275; CHECK:       [[BB2]]:
276; CHECK-NEXT:    ret void
277;
278  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
279  switch i8 %res, label %bb1 [
280  i8 -1, label %bb2
281  i8 0, label %bb2
282  i8 1, label %bb2
283  ]
284
285bb1:
286  call void @foo()
287  br label %bb2
288
289bb2:
290  ret void
291}
292
293define void @ucmp_gt_wrong_case(i32 %a, i32 %b) {
294; CHECK-LABEL: define void @ucmp_gt_wrong_case(
295; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
296; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
297; CHECK-NEXT:    switch i8 [[RES]], label %[[BB1:.*]] [
298; CHECK-NEXT:      i8 -2, label %[[BB2:.*]]
299; CHECK-NEXT:      i8 0, label %[[BB2]]
300; CHECK-NEXT:    ]
301; CHECK:       [[BB1]]:
302; CHECK-NEXT:    call void @foo()
303; CHECK-NEXT:    br label %[[BB2]]
304; CHECK:       [[BB2]]:
305; CHECK-NEXT:    ret void
306;
307  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
308  switch i8 %res, label %bb1 [
309  i8 -2, label %bb2
310  i8 0, label %bb2
311  ]
312
313bb1:
314  call void @foo()
315  br label %bb2
316
317bb2:
318  ret void
319}
320
321define void @ucmp_gt_not_same_succ(i32 %a, i32 %b) {
322; CHECK-LABEL: define void @ucmp_gt_not_same_succ(
323; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
324; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
325; CHECK-NEXT:    switch i8 [[RES]], label %[[BB1:.*]] [
326; CHECK-NEXT:      i8 -1, label %[[BB2:.*]]
327; CHECK-NEXT:      i8 0, label %[[BB3:.*]]
328; CHECK-NEXT:    ]
329; CHECK:       [[BB1]]:
330; CHECK-NEXT:    call void @foo()
331; CHECK-NEXT:    br label %[[BB2]]
332; CHECK:       [[BB3]]:
333; CHECK-NEXT:    call void @foo()
334; CHECK-NEXT:    br label %[[BB2]]
335; CHECK:       [[BB2]]:
336; CHECK-NEXT:    ret void
337;
338  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
339  switch i8 %res, label %bb1 [
340  i8 -1, label %bb2
341  i8 0, label %bb3
342  ]
343
344bb1:
345  call void @foo()
346  br label %bb2
347
348bb3:
349  call void @foo()
350  br label %bb2
351
352bb2:
353  ret void
354}
355
356define void @ucmp_gt_unpredictable(i32 %a, i32 %b) {
357; CHECK-LABEL: define void @ucmp_gt_unpredictable(
358; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
359; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]]
360; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]], !unpredictable [[META0:![0-9]+]]
361; CHECK:       [[BB1]]:
362; CHECK-NEXT:    call void @foo()
363; CHECK-NEXT:    br label %[[BB2]]
364; CHECK:       [[BB2]]:
365; CHECK-NEXT:    ret void
366;
367  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
368  switch i8 %res, label %bb1 [
369  i8 -1, label %bb2
370  i8 0, label %bb2
371  ], !unpredictable !{}
372
373bb1:
374  call void @foo()
375  br label %bb2
376
377bb2:
378  ret void
379}
380
381define void @ucmp_gt_weights(i32 %a, i32 %b) {
382; CHECK-LABEL: define void @ucmp_gt_weights(
383; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
384; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]]
385; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]], !prof [[PROF1:![0-9]+]]
386; CHECK:       [[BB1]]:
387; CHECK-NEXT:    call void @foo()
388; CHECK-NEXT:    br label %[[BB2]]
389; CHECK:       [[BB2]]:
390; CHECK-NEXT:    ret void
391;
392  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
393  switch i8 %res, label %bb1 [
394  i8 -1, label %bb2
395  i8 0, label %bb2
396  ], !prof !{!"branch_weights", i32 5, i32 10, i32 20}
397
398bb1:
399  call void @foo()
400  br label %bb2
401
402bb2:
403  ret void
404}
405
406define void @ucmp_gt_unreachable(i32 %a, i32 %b) {
407; CHECK-LABEL: define void @ucmp_gt_unreachable(
408; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
409; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]]
410; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
411; CHECK:       [[BB1]]:
412; CHECK-NEXT:    call void @foo()
413; CHECK-NEXT:    br label %[[BB2]]
414; CHECK:       [[BB2]]:
415; CHECK-NEXT:    ret void
416;
417  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
418  switch i8 %res, label %unreachable [
419  i8 -1, label %bb2
420  i8 0, label %bb2
421  i8 1, label %bb1
422  ]
423
424bb1:
425  call void @foo()
426  br label %bb2
427
428bb2:
429  ret void
430
431unreachable:
432  unreachable
433}
434
435define void @ucmp_lt_unreachable(i32 %a, i32 %b) {
436; CHECK-LABEL: define void @ucmp_lt_unreachable(
437; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
438; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[A]], [[B]]
439; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
440; CHECK:       [[BB1]]:
441; CHECK-NEXT:    call void @foo()
442; CHECK-NEXT:    br label %[[BB2]]
443; CHECK:       [[BB2]]:
444; CHECK-NEXT:    ret void
445;
446  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
447  switch i8 %res, label %unreachable [
448  i8 -1, label %bb1
449  i8 0, label %bb2
450  i8 1, label %bb2
451  ]
452
453bb1:
454  call void @foo()
455  br label %bb2
456
457bb2:
458  ret void
459
460unreachable:
461  unreachable
462}
463
464define void @ucmp_eq_unreachable(i32 %a, i32 %b) {
465; CHECK-LABEL: define void @ucmp_eq_unreachable(
466; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
467; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A]], [[B]]
468; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
469; CHECK:       [[BB1]]:
470; CHECK-NEXT:    call void @foo()
471; CHECK-NEXT:    br label %[[BB2]]
472; CHECK:       [[BB2]]:
473; CHECK-NEXT:    ret void
474;
475  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
476  switch i8 %res, label %unreachable [
477  i8 -1, label %bb2
478  i8 0, label %bb1
479  i8 1, label %bb2
480  ]
481
482bb1:
483  call void @foo()
484  br label %bb2
485
486bb2:
487  ret void
488
489unreachable:
490  unreachable
491}
492
493define void @ucmp_gt_unreachable_multi_edge(i8 %x, i32 %a, i32 %b) {
494; CHECK-LABEL: define void @ucmp_gt_unreachable_multi_edge(
495; CHECK-SAME: i8 [[X:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
496; CHECK-NEXT:  [[ENTRY:.*:]]
497; CHECK-NEXT:    switch i8 [[X]], label %[[UNREACHABLE:.*]] [
498; CHECK-NEXT:      i8 0, label %[[SW:.*]]
499; CHECK-NEXT:      i8 1, label %[[BB1:.*]]
500; CHECK-NEXT:    ]
501; CHECK:       [[SW]]:
502; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[A]], [[B]]
503; CHECK-NEXT:    br i1 [[TMP0]], label %[[BB1]], label %[[BB2:.*]]
504; CHECK:       [[BB1]]:
505; CHECK-NEXT:    call void @foo()
506; CHECK-NEXT:    br label %[[BB2]]
507; CHECK:       [[BB2]]:
508; CHECK-NEXT:    ret void
509; CHECK:       [[UNREACHABLE]]:
510; CHECK-NEXT:    unreachable
511;
512entry:
513  switch i8 %x, label %unreachable [
514  i8 0, label %sw
515  i8 1, label %bb1
516  ]
517
518sw:
519  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
520  switch i8 %res, label %unreachable [
521  i8 -1, label %bb2
522  i8 0, label %bb2
523  i8 1, label %bb1
524  ]
525
526bb1:
527  call void @foo()
528  br label %bb2
529
530bb2:
531  ret void
532
533unreachable:
534  %phi = phi i32 [ 0, %entry ], [ 1, %sw ]
535  unreachable
536}
537
538define void @ucmp_gt_unreachable_wrong_case(i32 %a, i32 %b) {
539; CHECK-LABEL: define void @ucmp_gt_unreachable_wrong_case(
540; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
541; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
542; CHECK-NEXT:    switch i8 [[RES]], label %[[UNREACHABLE:.*]] [
543; CHECK-NEXT:      i8 -2, label %[[BB2:.*]]
544; CHECK-NEXT:      i8 0, label %[[BB2]]
545; CHECK-NEXT:      i8 1, label %[[BB1:.*]]
546; CHECK-NEXT:    ]
547; CHECK:       [[BB1]]:
548; CHECK-NEXT:    call void @foo()
549; CHECK-NEXT:    br label %[[BB2]]
550; CHECK:       [[BB2]]:
551; CHECK-NEXT:    ret void
552; CHECK:       [[UNREACHABLE]]:
553; CHECK-NEXT:    unreachable
554;
555  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
556  switch i8 %res, label %unreachable [
557  i8 -2, label %bb2
558  i8 0, label %bb2
559  i8 1, label %bb1
560  ]
561
562bb1:
563  call void @foo()
564  br label %bb2
565
566bb2:
567  ret void
568
569unreachable:
570  unreachable
571}
572
573define void @ucmp_gt_unreachable_no_two_equal_cases(i32 %a, i32 %b) {
574; CHECK-LABEL: define void @ucmp_gt_unreachable_no_two_equal_cases(
575; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
576; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
577; CHECK-NEXT:    switch i8 [[RES]], label %[[UNREACHABLE:.*]] [
578; CHECK-NEXT:      i8 -1, label %[[BB3:.*]]
579; CHECK-NEXT:      i8 0, label %[[BB2:.*]]
580; CHECK-NEXT:      i8 1, label %[[BB1:.*]]
581; CHECK-NEXT:    ]
582; CHECK:       [[BB1]]:
583; CHECK-NEXT:    call void @foo()
584; CHECK-NEXT:    br label %[[BB2]]
585; CHECK:       [[BB3]]:
586; CHECK-NEXT:    call void @foo()
587; CHECK-NEXT:    br label %[[BB2]]
588; CHECK:       [[BB2]]:
589; CHECK-NEXT:    ret void
590; CHECK:       [[UNREACHABLE]]:
591; CHECK-NEXT:    unreachable
592;
593  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
594  switch i8 %res, label %unreachable [
595  i8 -1, label %bb3
596  i8 0, label %bb2
597  i8 1, label %bb1
598  ]
599
600bb1:
601  call void @foo()
602  br label %bb2
603
604bb3:
605  call void @foo()
606  br label %bb2
607
608bb2:
609  ret void
610
611unreachable:
612  unreachable
613}
614
615define void @ucmp_gt_unreachable_three_equal_cases(i32 %a, i32 %b) {
616; CHECK-LABEL: define void @ucmp_gt_unreachable_three_equal_cases(
617; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
618; CHECK-NEXT:  [[BB1:.*:]]
619; CHECK-NEXT:    call void @foo()
620; CHECK-NEXT:    ret void
621;
622  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
623  switch i8 %res, label %unreachable [
624  i8 -1, label %bb1
625  i8 0, label %bb1
626  i8 1, label %bb1
627  ]
628
629bb1:
630  call void @foo()
631  ret void
632
633unreachable:
634  unreachable
635}
636
637define void @ucmp_gt_unreachable_default_not_unreachable(i32 %a, i32 %b) {
638; CHECK-LABEL: define void @ucmp_gt_unreachable_default_not_unreachable(
639; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
640; CHECK-NEXT:    [[RES:%.*]] = call i8 @llvm.ucmp.i8.i32(i32 [[A]], i32 [[B]])
641; CHECK-NEXT:    switch i8 [[RES]], label %[[NOT_UNREACHABLE:.*]] [
642; CHECK-NEXT:      i8 -1, label %[[BB2:.*]]
643; CHECK-NEXT:      i8 0, label %[[BB2]]
644; CHECK-NEXT:      i8 1, label %[[BB1:.*]]
645; CHECK-NEXT:    ]
646; CHECK:       [[BB1]]:
647; CHECK-NEXT:    call void @foo()
648; CHECK-NEXT:    br label %[[BB2]]
649; CHECK:       [[BB2]]:
650; CHECK-NEXT:    ret void
651; CHECK:       [[NOT_UNREACHABLE]]:
652; CHECK-NEXT:    call void @foo()
653; CHECK-NEXT:    br label %[[BB2]]
654;
655  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
656  switch i8 %res, label %not.unreachable [
657  i8 -1, label %bb2
658  i8 0, label %bb2
659  i8 1, label %bb1
660  ]
661
662bb1:
663  call void @foo()
664  br label %bb2
665
666bb2:
667  ret void
668
669not.unreachable:
670  call void @foo()
671  br label %bb2
672}
673
674define void @ucmp_gt_unreachable_weights(i32 %a, i32 %b) {
675; CHECK-LABEL: define void @ucmp_gt_unreachable_weights(
676; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
677; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[A]], [[B]]
678; CHECK-NEXT:    br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]], !prof [[PROF1]]
679; CHECK:       [[BB1]]:
680; CHECK-NEXT:    call void @foo()
681; CHECK-NEXT:    br label %[[BB2]]
682; CHECK:       [[BB2]]:
683; CHECK-NEXT:    ret void
684;
685  %res = call i8 @llvm.ucmp.i8.i32(i32 %a, i32 %b)
686  switch i8 %res, label %unreachable [
687  i8 -1, label %bb2
688  i8 0, label %bb2
689  i8 1, label %bb1
690  ], !prof !{!"branch_weights", i32 0, i32 10, i32 20, i32 5}
691
692bb1:
693  call void @foo()
694  br label %bb2
695
696bb2:
697  ret void
698
699unreachable:
700  unreachable
701}
702
703declare void @use(i8)
704declare void @foo()
705;.
706; CHECK: [[META0]] = !{}
707; CHECK: [[PROF1]] = !{!"branch_weights", i32 5, i32 30}
708;.
709