xref: /llvm-project/llvm/test/Transforms/CorrelatedValuePropagation/add.ll (revision 3127b659fad358b135721bd937fead49e5c73de5)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
3
4define void @test0(i32 %a) {
5; CHECK-LABEL: define void @test0(
6; CHECK-SAME: i32 [[A:%.*]]) {
7; CHECK-NEXT:  entry:
8; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 100
9; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
10; CHECK:       bb:
11; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
12; CHECK-NEXT:    br label [[EXIT]]
13; CHECK:       exit:
14; CHECK-NEXT:    ret void
15;
16entry:
17  %cmp = icmp slt i32 %a, 100
18  br i1 %cmp, label %bb, label %exit
19
20bb:
21  %add = add i32 %a, 1
22  br label %exit
23
24exit:
25  ret void
26}
27
28define void @test1(i32 %a) {
29; CHECK-LABEL: define void @test1(
30; CHECK-SAME: i32 [[A:%.*]]) {
31; CHECK-NEXT:  entry:
32; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], 100
33; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
34; CHECK:       bb:
35; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], 1
36; CHECK-NEXT:    br label [[EXIT]]
37; CHECK:       exit:
38; CHECK-NEXT:    ret void
39;
40entry:
41  %cmp = icmp ult i32 %a, 100
42  br i1 %cmp, label %bb, label %exit
43
44bb:
45  %add = add i32 %a, 1
46  br label %exit
47
48exit:
49  ret void
50}
51
52define void @test2(i32 %a) {
53; CHECK-LABEL: define void @test2(
54; CHECK-SAME: i32 [[A:%.*]]) {
55; CHECK-NEXT:  entry:
56; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[A]], -1
57; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
58; CHECK:       bb:
59; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A]], 1
60; CHECK-NEXT:    br label [[EXIT]]
61; CHECK:       exit:
62; CHECK-NEXT:    ret void
63;
64entry:
65  %cmp = icmp ult i32 %a, -1
66  br i1 %cmp, label %bb, label %exit
67
68bb:
69  %add = add i32 %a, 1
70  br label %exit
71
72exit:
73  ret void
74}
75
76define void @test3(i32 %a) {
77; CHECK-LABEL: define void @test3(
78; CHECK-SAME: i32 [[A:%.*]]) {
79; CHECK-NEXT:  entry:
80; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[A]], -1
81; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
82; CHECK:       bb:
83; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], 1
84; CHECK-NEXT:    br label [[EXIT]]
85; CHECK:       exit:
86; CHECK-NEXT:    ret void
87;
88entry:
89  %cmp = icmp ule i32 %a, -1
90  br i1 %cmp, label %bb, label %exit
91
92bb:
93  %add = add i32 %a, 1
94  br label %exit
95
96exit:
97  ret void
98}
99
100define void @test4(i32 %a) {
101; CHECK-LABEL: define void @test4(
102; CHECK-SAME: i32 [[A:%.*]]) {
103; CHECK-NEXT:  entry:
104; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A]], 2147483647
105; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
106; CHECK:       bb:
107; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
108; CHECK-NEXT:    br label [[EXIT]]
109; CHECK:       exit:
110; CHECK-NEXT:    ret void
111;
112entry:
113  %cmp = icmp slt i32 %a, 2147483647
114  br i1 %cmp, label %bb, label %exit
115
116bb:
117  %add = add i32 %a, 1
118  br label %exit
119
120exit:
121  ret void
122}
123
124define void @test5(i32 %a) {
125; CHECK-LABEL: define void @test5(
126; CHECK-SAME: i32 [[A:%.*]]) {
127; CHECK-NEXT:  entry:
128; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[A]], 2147483647
129; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
130; CHECK:       bb:
131; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], 1
132; CHECK-NEXT:    br label [[EXIT]]
133; CHECK:       exit:
134; CHECK-NEXT:    ret void
135;
136entry:
137  %cmp = icmp sle i32 %a, 2147483647
138  br i1 %cmp, label %bb, label %exit
139
140bb:
141  %add = add i32 %a, 1
142  br label %exit
143
144exit:
145  ret void
146}
147
148; Check for a corner case where an integer value is represented with a constant
149; LVILatticeValue instead of constantrange. Check that we don't fail with an
150; assertion in this case.
151@b = global i32 0, align 4
152define void @test6(i32 %a) {
153; CHECK-LABEL: define void @test6(
154; CHECK-SAME: i32 [[A:%.*]]) {
155; CHECK-NEXT:  bb:
156; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], ptrtoint (ptr @b to i32)
157; CHECK-NEXT:    ret void
158;
159bb:
160  %add = add i32 %a, ptrtoint (ptr @b to i32)
161  ret void
162}
163
164; Check that we can gather information for conditions is the form of
165;   and ( i s< 100, Unknown )
166define void @test7(i32 %a, i1 %flag) {
167; CHECK-LABEL: define void @test7(
168; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) {
169; CHECK-NEXT:  entry:
170; CHECK-NEXT:    [[CMP_1:%.*]] = icmp slt i32 [[A]], 100
171; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG]]
172; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
173; CHECK:       bb:
174; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
175; CHECK-NEXT:    br label [[EXIT]]
176; CHECK:       exit:
177; CHECK-NEXT:    ret void
178;
179entry:
180  %cmp.1 = icmp slt i32 %a, 100
181  %cmp = and i1 %cmp.1, %flag
182  br i1 %cmp, label %bb, label %exit
183
184bb:
185  %add = add i32 %a, 1
186  br label %exit
187
188exit:
189  ret void
190}
191
192; Check that we can gather information for conditions is the form of
193;   and ( i s< 100, i s> 0 )
194define void @test8(i32 %a) {
195; CHECK-LABEL: define void @test8(
196; CHECK-SAME: i32 [[A:%.*]]) {
197; CHECK-NEXT:  entry:
198; CHECK-NEXT:    [[CMP_1:%.*]] = icmp slt i32 [[A]], 100
199; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0
200; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]]
201; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
202; CHECK:       bb:
203; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], 1
204; CHECK-NEXT:    br label [[EXIT]]
205; CHECK:       exit:
206; CHECK-NEXT:    ret void
207;
208entry:
209  %cmp.1 = icmp slt i32 %a, 100
210  %cmp.2 = icmp sgt i32 %a, 0
211  %cmp = and i1 %cmp.1, %cmp.2
212  br i1 %cmp, label %bb, label %exit
213
214bb:
215  %add = add i32 %a, 1
216  br label %exit
217
218exit:
219  ret void
220}
221
222; Check that for conditions is the form of cond1 && cond2 we don't mistakenly
223; assume that !cond1 && !cond2 holds down to false path.
224define void @test8_neg(i32 %a) {
225; CHECK-LABEL: define void @test8_neg(
226; CHECK-SAME: i32 [[A:%.*]]) {
227; CHECK-NEXT:  entry:
228; CHECK-NEXT:    [[CMP_1:%.*]] = icmp sge i32 [[A]], 100
229; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sle i32 [[A]], 0
230; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_2]]
231; CHECK-NEXT:    br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
232; CHECK:       bb:
233; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], 1
234; CHECK-NEXT:    br label [[EXIT]]
235; CHECK:       exit:
236; CHECK-NEXT:    ret void
237;
238entry:
239  %cmp.1 = icmp sge i32 %a, 100
240  %cmp.2 = icmp sle i32 %a, 0
241  %cmp = and i1 %cmp.1, %cmp.2
242  br i1 %cmp, label %exit, label %bb
243
244bb:
245  %add = add i32 %a, 1
246  br label %exit
247
248exit:
249  ret void
250}
251
252; Check that we can gather information for conditions is the form of
253;   and ( i s< 100, and (i s> 0, Unknown )
254define void @test9(i32 %a, i1 %flag) {
255; CHECK-LABEL: define void @test9(
256; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) {
257; CHECK-NEXT:  entry:
258; CHECK-NEXT:    [[CMP_1:%.*]] = icmp slt i32 [[A]], 100
259; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0
260; CHECK-NEXT:    [[CMP_3:%.*]] = and i1 [[CMP_2]], [[FLAG]]
261; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[CMP_1]], [[CMP_3]]
262; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
263; CHECK:       bb:
264; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], 1
265; CHECK-NEXT:    br label [[EXIT]]
266; CHECK:       exit:
267; CHECK-NEXT:    ret void
268;
269entry:
270  %cmp.1 = icmp slt i32 %a, 100
271  %cmp.2 = icmp sgt i32 %a, 0
272  %cmp.3 = and i1 %cmp.2, %flag
273  %cmp = and i1 %cmp.1, %cmp.3
274  br i1 %cmp, label %bb, label %exit
275
276bb:
277  %add = add i32 %a, 1
278  br label %exit
279
280exit:
281  ret void
282}
283
284; Check that we can gather information for conditions is the form of
285;   and ( i s< Unknown, ... )
286define void @test10(i32 %a, i32 %b, i1 %flag) {
287; CHECK-LABEL: define void @test10(
288; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i1 [[FLAG:%.*]]) {
289; CHECK-NEXT:  entry:
290; CHECK-NEXT:    [[CMP_1:%.*]] = icmp slt i32 [[A]], [[B]]
291; CHECK-NEXT:    [[CMP:%.*]] = and i1 [[CMP_1]], [[FLAG]]
292; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
293; CHECK:       bb:
294; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
295; CHECK-NEXT:    br label [[EXIT]]
296; CHECK:       exit:
297; CHECK-NEXT:    ret void
298;
299entry:
300  %cmp.1 = icmp slt i32 %a, %b
301  %cmp = and i1 %cmp.1, %flag
302  br i1 %cmp, label %bb, label %exit
303
304bb:
305  %add = add i32 %a, 1
306  br label %exit
307
308exit:
309  ret void
310}
311
312@limit = external global i32
313define i32 @test11(ptr %p, i32 %i) {
314; CHECK-LABEL: define range(i32 0, 2147483645) i32 @test11(
315; CHECK-SAME: ptr [[P:%.*]], i32 [[I:%.*]]) {
316; CHECK-NEXT:    [[LIMIT:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]
317; CHECK-NEXT:    [[WITHIN_1:%.*]] = icmp ugt i32 [[LIMIT]], [[I]]
318; CHECK-NEXT:    [[I_PLUS_7:%.*]] = add i32 [[I]], 7
319; CHECK-NEXT:    [[WITHIN_2:%.*]] = icmp ugt i32 [[LIMIT]], [[I_PLUS_7]]
320; CHECK-NEXT:    [[WITHIN:%.*]] = and i1 [[WITHIN_1]], [[WITHIN_2]]
321; CHECK-NEXT:    br i1 [[WITHIN]], label [[THEN:%.*]], label [[ELSE:%.*]]
322; CHECK:       then:
323; CHECK-NEXT:    [[I_PLUS_6:%.*]] = add nuw nsw i32 [[I]], 6
324; CHECK-NEXT:    ret i32 [[I_PLUS_6]]
325; CHECK:       else:
326; CHECK-NEXT:    ret i32 0
327;
328  %limit = load i32, ptr %p, !range !{i32 0, i32 2147483647}
329  %within.1 = icmp ugt i32 %limit, %i
330  %i.plus.7 = add i32 %i, 7
331  %within.2 = icmp ugt i32 %limit, %i.plus.7
332  %within = and i1 %within.1, %within.2
333  br i1 %within, label %then, label %else
334
335then:
336  %i.plus.6 = add i32 %i, 6
337  ret i32 %i.plus.6
338
339else:
340  ret i32 0
341}
342
343; Check that we can gather information for conditions is the form of
344;   or ( i s>= 100, Unknown )
345define void @test12(i32 %a, i1 %flag) {
346; CHECK-LABEL: define void @test12(
347; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) {
348; CHECK-NEXT:  entry:
349; CHECK-NEXT:    [[CMP_1:%.*]] = icmp sge i32 [[A]], 100
350; CHECK-NEXT:    [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG]]
351; CHECK-NEXT:    br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
352; CHECK:       bb:
353; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
354; CHECK-NEXT:    br label [[EXIT]]
355; CHECK:       exit:
356; CHECK-NEXT:    ret void
357;
358entry:
359  %cmp.1 = icmp sge i32 %a, 100
360  %cmp = or i1 %cmp.1, %flag
361  br i1 %cmp, label %exit, label %bb
362
363bb:
364  %add = add i32 %a, 1
365  br label %exit
366
367exit:
368  ret void
369}
370
371; Check that we can gather information for conditions is the form of
372;   or ( i s>= 100, i s<= 0 )
373define void @test13(i32 %a) {
374; CHECK-LABEL: define void @test13(
375; CHECK-SAME: i32 [[A:%.*]]) {
376; CHECK-NEXT:  entry:
377; CHECK-NEXT:    [[CMP_1:%.*]] = icmp sge i32 [[A]], 100
378; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sle i32 [[A]], 0
379; CHECK-NEXT:    [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]]
380; CHECK-NEXT:    br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
381; CHECK:       bb:
382; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], 1
383; CHECK-NEXT:    br label [[EXIT]]
384; CHECK:       exit:
385; CHECK-NEXT:    ret void
386;
387entry:
388  %cmp.1 = icmp sge i32 %a, 100
389  %cmp.2 = icmp sle i32 %a, 0
390  %cmp = or i1 %cmp.1, %cmp.2
391  br i1 %cmp, label %exit, label %bb
392
393bb:
394  %add = add i32 %a, 1
395  br label %exit
396
397exit:
398  ret void
399}
400
401; Check that for conditions is the form of cond1 || cond2 we don't mistakenly
402; assume that cond1 || cond2 holds down to true path.
403define void @test13_neg(i32 %a) {
404; CHECK-LABEL: define void @test13_neg(
405; CHECK-SAME: i32 [[A:%.*]]) {
406; CHECK-NEXT:  entry:
407; CHECK-NEXT:    [[CMP_1:%.*]] = icmp slt i32 [[A]], 100
408; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sgt i32 [[A]], 0
409; CHECK-NEXT:    [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_2]]
410; CHECK-NEXT:    br i1 [[CMP]], label [[BB:%.*]], label [[EXIT:%.*]]
411; CHECK:       bb:
412; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A]], 1
413; CHECK-NEXT:    br label [[EXIT]]
414; CHECK:       exit:
415; CHECK-NEXT:    ret void
416;
417entry:
418  %cmp.1 = icmp slt i32 %a, 100
419  %cmp.2 = icmp sgt i32 %a, 0
420  %cmp = or i1 %cmp.1, %cmp.2
421  br i1 %cmp, label %bb, label %exit
422
423bb:
424  %add = add i32 %a, 1
425  br label %exit
426
427exit:
428  ret void
429}
430
431; Check that we can gather information for conditions is the form of
432;   or ( i s>=100, or (i s<= 0, Unknown )
433define void @test14(i32 %a, i1 %flag) {
434; CHECK-LABEL: define void @test14(
435; CHECK-SAME: i32 [[A:%.*]], i1 [[FLAG:%.*]]) {
436; CHECK-NEXT:  entry:
437; CHECK-NEXT:    [[CMP_1:%.*]] = icmp sge i32 [[A]], 100
438; CHECK-NEXT:    [[CMP_2:%.*]] = icmp sle i32 [[A]], 0
439; CHECK-NEXT:    [[CMP_3:%.*]] = or i1 [[CMP_2]], [[FLAG]]
440; CHECK-NEXT:    [[CMP:%.*]] = or i1 [[CMP_1]], [[CMP_3]]
441; CHECK-NEXT:    br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
442; CHECK:       bb:
443; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[A]], 1
444; CHECK-NEXT:    br label [[EXIT]]
445; CHECK:       exit:
446; CHECK-NEXT:    ret void
447;
448entry:
449  %cmp.1 = icmp sge i32 %a, 100
450  %cmp.2 = icmp sle i32 %a, 0
451  %cmp.3 = or i1 %cmp.2, %flag
452  %cmp = or i1 %cmp.1, %cmp.3
453  br i1 %cmp, label %exit, label %bb
454
455bb:
456  %add = add i32 %a, 1
457  br label %exit
458
459exit:
460  ret void
461}
462
463; Check that we can gather information for conditions is the form of
464;   or ( i s>= Unknown, ... )
465define void @test15(i32 %a, i32 %b, i1 %flag) {
466; CHECK-LABEL: define void @test15(
467; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i1 [[FLAG:%.*]]) {
468; CHECK-NEXT:  entry:
469; CHECK-NEXT:    [[CMP_1:%.*]] = icmp sge i32 [[A]], [[B]]
470; CHECK-NEXT:    [[CMP:%.*]] = or i1 [[CMP_1]], [[FLAG]]
471; CHECK-NEXT:    br i1 [[CMP]], label [[EXIT:%.*]], label [[BB:%.*]]
472; CHECK:       bb:
473; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[A]], 1
474; CHECK-NEXT:    br label [[EXIT]]
475; CHECK:       exit:
476; CHECK-NEXT:    ret void
477;
478entry:
479  %cmp.1 = icmp sge i32 %a, %b
480  %cmp = or i1 %cmp.1, %flag
481  br i1 %cmp, label %exit, label %bb
482
483bb:
484  %add = add i32 %a, 1
485  br label %exit
486
487exit:
488  ret void
489}
490
491; single basic block loop
492; because the loop exit condition is SLT, we can supplement the iv add
493; (iv.next def) with an nsw.
494define i32 @test16(ptr %n, ptr %a) {
495; CHECK-LABEL: define i32 @test16(
496; CHECK-SAME: ptr [[N:%.*]], ptr [[A:%.*]]) {
497; CHECK-NEXT:  preheader:
498; CHECK-NEXT:    br label [[LOOP:%.*]]
499; CHECK:       loop:
500; CHECK-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[PREHEADER:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
501; CHECK-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[PREHEADER]] ], [ [[ACC_CURR:%.*]], [[LOOP]] ]
502; CHECK-NEXT:    [[X:%.*]] = load atomic i32, ptr [[A]] unordered, align 8
503; CHECK-NEXT:    fence acquire
504; CHECK-NEXT:    [[ACC_CURR]] = add i32 [[ACC]], [[X]]
505; CHECK-NEXT:    [[IV_NEXT]] = add nsw i32 [[IV]], 1
506; CHECK-NEXT:    [[NVAL:%.*]] = load atomic i32, ptr [[N]] unordered, align 8
507; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[IV_NEXT]], [[NVAL]]
508; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[EXIT:%.*]]
509; CHECK:       exit:
510; CHECK-NEXT:    ret i32 [[ACC_CURR]]
511;
512preheader:
513  br label %loop
514
515loop:
516  %iv = phi i32 [ 0, %preheader ], [ %iv.next, %loop ]
517  %acc = phi i32 [ 0, %preheader ], [ %acc.curr, %loop ]
518  %x = load atomic i32, ptr %a unordered, align 8
519  fence acquire
520  %acc.curr = add i32 %acc, %x
521  %iv.next = add i32 %iv, 1
522  %nval = load atomic i32, ptr %n unordered, align 8
523  %cmp = icmp slt i32 %iv.next, %nval
524  br i1 %cmp, label %loop, label %exit
525
526exit:
527  ret i32 %acc.curr
528}
529
530define i32 @test_undef_range(i32 %x) {
531; CHECK-LABEL: define i32 @test_undef_range(
532; CHECK-SAME: i32 [[X:%.*]]) {
533; CHECK-NEXT:  entry:
534; CHECK-NEXT:    switch i32 [[X]], label [[JOIN:%.*]] [
535; CHECK-NEXT:      i32 1, label [[CASE1:%.*]]
536; CHECK-NEXT:      i32 2, label [[CASE2:%.*]]
537; CHECK-NEXT:    ]
538; CHECK:       case1:
539; CHECK-NEXT:    br label [[JOIN]]
540; CHECK:       case2:
541; CHECK-NEXT:    br label [[JOIN]]
542; CHECK:       join:
543; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 1, [[CASE1]] ], [ 2, [[CASE2]] ], [ undef, [[ENTRY:%.*]] ]
544; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[PHI]], 1
545; CHECK-NEXT:    ret i32 [[ADD]]
546;
547entry:
548  switch i32 %x, label %join [
549  i32 1, label %case1
550  i32 2, label %case2
551  ]
552
553case1:
554  br label %join
555
556case2:
557  br label %join
558
559join:
560  %phi = phi i32 [ 1, %case1 ], [ 2, %case2 ], [ undef, %entry ]
561  %add = add i32 %phi, 1
562  ret i32 %add
563}
564
565;.
566; CHECK: [[RNG0]] = !{i32 0, i32 2147483647}
567;.
568