1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt %s -mtriple=x86_64-- -codegenprepare -S | FileCheck %s
3@g = global i32 0
4@effect = global i32 0
5
6define void @switch_phi_const(i32 %x) {
7; CHECK-LABEL: @switch_phi_const(
8; CHECK-NEXT:  bb0:
9; CHECK-NEXT:    switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [
10; CHECK-NEXT:    i32 13, label [[CASE_13:%.*]]
11; CHECK-NEXT:    i32 42, label [[CASE_42:%.*]]
12; CHECK-NEXT:    i32 50, label [[CASE_50_51:%.*]]
13; CHECK-NEXT:    i32 51, label [[CASE_50_51]]
14; CHECK-NEXT:    i32 55, label [[CASE_55:%.*]]
15; CHECK-NEXT:    i32 7, label [[CASE_7:%.*]]
16; CHECK-NEXT:    ]
17; CHECK:       case_13:
18; CHECK-NEXT:    [[X0:%.*]] = phi i32 [ [[X]], [[BB0:%.*]] ], [ [[X_LOOPBACK:%.*]], [[CASE_7]] ]
19; CHECK-NEXT:    store i32 13, i32* @effect, align 4
20; CHECK-NEXT:    br label [[CASE_42]]
21; CHECK:       case_42:
22; CHECK-NEXT:    [[X1:%.*]] = phi i32 [ [[X]], [[BB0]] ], [ [[X0]], [[CASE_13]] ]
23; CHECK-NEXT:    store i32 [[X1]], i32* @effect, align 4
24; CHECK-NEXT:    br label [[CASE_50_51]]
25; CHECK:       case_50_51:
26; CHECK-NEXT:    [[X2:%.*]] = phi i32 [ 50, [[BB0]] ], [ 50, [[BB0]] ], [ [[X1]], [[CASE_42]] ]
27; CHECK-NEXT:    [[X2_2:%.*]] = phi i32 [ 51, [[BB0]] ], [ 51, [[BB0]] ], [ [[X1]], [[CASE_42]] ]
28; CHECK-NEXT:    store i32 [[X2]], i32* @effect, align 4
29; CHECK-NEXT:    store i32 [[X2_2]], i32* @effect, align 4
30; CHECK-NEXT:    br label [[CASE_55]]
31; CHECK:       case_55:
32; CHECK-NEXT:    [[X3:%.*]] = phi i32 [ 42, [[BB0]] ], [ 55, [[CASE_50_51]] ]
33; CHECK-NEXT:    store i32 [[X3]], i32* @effect, align 4
34; CHECK-NEXT:    br label [[DEFAULT]]
35; CHECK:       case_7:
36; CHECK-NEXT:    [[X_LOOPBACK]] = load i32, i32* @g, align 4
37; CHECK-NEXT:    store i32 7, i32* @effect, align 4
38; CHECK-NEXT:    br label [[CASE_13]]
39; CHECK:       default:
40; CHECK-NEXT:    ret void
41;
42bb0:
43  switch i32 %x, label %default [
44  i32 13, label %case_13
45  i32 42, label %case_42
46  i32 50, label %case_50_51
47  i32 51, label %case_50_51
48  i32 55, label %case_55
49  i32 7, label %case_7
50  ]
51
52case_13:
53  ; We should replace 13 with %x
54  %x0 = phi i32 [ 13, %bb0 ], [ %x_loopback, %case_7 ]
55  store i32 13, i32* @effect, align 4
56  br label %case_42
57
58case_42:
59  ; We should replace 42 with %x
60  %x1 = phi i32 [ 42, %bb0 ], [ %x0, %case_13 ]
61  store i32 %x1, i32* @effect, align 4
62  br label %case_50_51
63
64case_50_51:
65  ; Must not replace the PHI argument: Case values 50 and 51 jump here.
66  %x2 = phi i32 [ 50, %bb0 ], [ 50, %bb0 ], [ %x1, %case_42 ]
67  %x2.2 = phi i32 [ 51, %bb0 ], [ 51, %bb0 ], [ %x1, %case_42 ]
68  store i32 %x2, i32* @effect, align 4
69  store i32 %x2.2, i32* @effect, align 4
70  br label %case_55
71
72case_55:
73  ; We must not replace any of the PHI arguments:
74  ; - 42 is the wrong constant
75  ; - %case_42 is not the switch predecessor block.
76  %x3 = phi i32 [ 42, %bb0 ], [ 55, %case_50_51 ]
77  store i32 %x3, i32* @effect, align 4
78  br label %default
79
80case_7:
81  %x_loopback = load i32, i32* @g, align 4
82  store i32 7, i32* @effect, align 4
83  br label %case_13
84
85default:
86  ret void
87}
88
89define void @switch_phi_const_multiple_phis(i32 %x) {
90; CHECK-LABEL: @switch_phi_const_multiple_phis(
91; CHECK-NEXT:  bb0:
92; CHECK-NEXT:    br i1 undef, label [[BB1:%.*]], label [[CASE_13:%.*]]
93; CHECK:       bb1:
94; CHECK-NEXT:    [[COND:%.*]] = icmp eq i32 [[X:%.*]], 13
95; CHECK-NEXT:    br i1 [[COND]], label [[CASE_13]], label [[DEFAULT:%.*]]
96; CHECK:       case_13:
97; CHECK-NEXT:    [[X0:%.*]] = phi i32 [ [[X]], [[BB1]] ], [ 1, [[BB0:%.*]] ]
98; CHECK-NEXT:    [[N0:%.*]] = phi i32 [ 14, [[BB1]] ], [ 1, [[BB0]] ]
99; CHECK-NEXT:    [[X1:%.*]] = phi i32 [ 27, [[BB0]] ], [ [[X]], [[BB1]] ]
100; CHECK-NEXT:    store volatile i32 [[X0]], i32* @effect, align 4
101; CHECK-NEXT:    store volatile i32 [[N0]], i32* @effect, align 4
102; CHECK-NEXT:    store volatile i32 [[X1]], i32* @effect, align 4
103; CHECK-NEXT:    ret void
104; CHECK:       default:
105; CHECK-NEXT:    ret void
106;
107bb0:
108  br i1 undef, label %bb1, label %case_13
109
110bb1:
111  switch i32 %x, label %default [
112  i32 13, label %case_13
113  ]
114
115case_13:
116  ; Check that replacement works for multiple PHIs.
117  ; Should perform replacement for %x0, %x1 but not %n0
118  %x0 = phi i32 [13, %bb1], [1, %bb0]
119  %n0 = phi i32 [14, %bb1], [1, %bb0]
120  %x1 = phi i32 [27, %bb0], [13, %bb1]
121  store volatile i32 %x0, i32* @effect, align 4
122  store volatile i32 %n0, i32* @effect, align 4
123  store volatile i32 %x1, i32* @effect, align 4
124  ret void
125
126default:
127  ret void
128}
129
130define void @switch_phi_const_degenerate() {
131; CHECK-LABEL: @switch_phi_const_degenerate(
132; CHECK-NEXT:  bb0:
133; CHECK-NEXT:    br i1 undef, label [[CASE_42:%.*]], label [[BB1:%.*]]
134; CHECK:       bb1:
135; CHECK-NEXT:    br label [[CASE_42]]
136; CHECK:       case_42:
137; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[BB0:%.*]] ], [ 42, [[BB1]] ]
138; CHECK-NEXT:    store volatile i32 [[X]], i32* @effect, align 4
139; CHECK-NEXT:    ret void
140;
141bb0:
142  br i1 undef, label %case_42, label %bb1
143
144bb1:
145  switch i32 42, label %unreachable [
146  i32 42, label %case_42
147  ]
148
149case_42:
150  ; We should not end up in an endless loop 42 with the switch condition 42.
151  %x = phi i32 [0, %bb0], [42, %bb1]
152  store volatile i32 %x, i32* @effect, align 4
153  ret void
154
155unreachable:
156  unreachable
157}
158