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