xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/merge-phis-in-switch.ll (revision 07b9d231ff9baa6473b0dd588a3ce5330d3e4871)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
3
4; Test a bunch of cases where the combination of phis in switch should be merged into one phi
5
6declare void @use(i8)
7
8define i8 @phis_of_switch_minimal(i8 noundef %arg) {
9; CHECK-LABEL: define i8 @phis_of_switch_minimal(
10; CHECK-SAME: i8 noundef [[ARG:%.*]]) {
11; CHECK-NEXT:  start:
12; CHECK-NEXT:    switch i8 [[ARG]], label [[UNREACHABLE:%.*]] [
13; CHECK-NEXT:      i8 0, label [[CASE01:%.*]]
14; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
15; CHECK-NEXT:      i8 2, label [[END:%.*]]
16; CHECK-NEXT:    ]
17; CHECK:       unreachable:
18; CHECK-NEXT:    unreachable
19; CHECK:       case1:
20; CHECK-NEXT:    br label [[END]]
21; CHECK:       case01:
22; CHECK-NEXT:    br label [[END]]
23; CHECK:       end:
24; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ 3, [[START:%.*]] ], [ 2, [[CASE1]] ], [ 1, [[CASE01]] ]
25; CHECK-NEXT:    ret i8 [[PHI2]]
26;
27start:
28  switch i8 %arg, label %unreachable [
29  i8 0, label %case01
30  i8 1, label %case1
31  i8 2, label %end
32  ]
33unreachable:
34  unreachable
35case1:
36  br label %case01
37
38case01:
39  %phi1 = phi i8 [ 2, %case1 ], [1, %start]
40  br label %end
41
42end:
43  %phi2 = phi i8 [ %phi1, %case01 ], [ 3, %start ]
44  ret i8 %phi2
45}
46
47define i8 @phis_of_switch(i8 noundef %arg) {
48; CHECK-LABEL: define i8 @phis_of_switch(
49; CHECK-SAME: i8 noundef [[ARG:%.*]]) {
50; CHECK-NEXT:  start:
51; CHECK-NEXT:    switch i8 [[ARG]], label [[UNREACHABLE:%.*]] [
52; CHECK-NEXT:      i8 0, label [[CASE012:%.*]]
53; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
54; CHECK-NEXT:      i8 2, label [[CASE2:%.*]]
55; CHECK-NEXT:      i8 3, label [[END:%.*]]
56; CHECK-NEXT:    ]
57; CHECK:       unreachable:
58; CHECK-NEXT:    unreachable
59; CHECK:       case1:
60; CHECK-NEXT:    br label [[END]]
61; CHECK:       case2:
62; CHECK-NEXT:    br label [[END]]
63; CHECK:       case012:
64; CHECK-NEXT:    br label [[END]]
65; CHECK:       end:
66; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ 4, [[START:%.*]] ], [ 3, [[CASE2]] ], [ 2, [[CASE1]] ], [ 1, [[CASE012]] ]
67; CHECK-NEXT:    ret i8 [[PHI2]]
68;
69start:
70  switch i8 %arg, label %unreachable [
71  i8 0, label %case012
72  i8 1, label %case1
73  i8 2, label %case2
74  i8 3, label %end
75  ]
76unreachable:
77  unreachable
78case1:
79  br label %case012
80
81case2:
82  br label %case012
83
84case012:
85  %phi1 = phi i8 [ 3, %case2 ], [ 2, %case1 ], [1, %start]
86  br label %end
87
88end:
89  %phi2 = phi i8 [ %phi1, %case012 ], [ 4, %start ]
90  ret i8 %phi2
91}
92
93define i8 @multiple_phis_of_switch(i8 noundef %arg) {
94; CHECK-LABEL: define i8 @multiple_phis_of_switch(
95; CHECK-SAME: i8 noundef [[ARG:%.*]]) {
96; CHECK-NEXT:  start:
97; CHECK-NEXT:    switch i8 [[ARG]], label [[UNREACHABLE:%.*]] [
98; CHECK-NEXT:      i8 0, label [[CASE012:%.*]]
99; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
100; CHECK-NEXT:      i8 2, label [[CASE2:%.*]]
101; CHECK-NEXT:      i8 3, label [[END:%.*]]
102; CHECK-NEXT:    ]
103; CHECK:       unreachable:
104; CHECK-NEXT:    unreachable
105; CHECK:       case1:
106; CHECK-NEXT:    br label [[END]]
107; CHECK:       case2:
108; CHECK-NEXT:    br label [[END]]
109; CHECK:       case012:
110; CHECK-NEXT:    br label [[END]]
111; CHECK:       end:
112; CHECK-NEXT:    [[PHI2_1:%.*]] = phi i8 [ 4, [[START:%.*]] ], [ 3, [[CASE2]] ], [ 2, [[CASE1]] ], [ 1, [[CASE012]] ]
113; CHECK-NEXT:    [[PHI2_2:%.*]] = phi i8 [ 5, [[START]] ], [ 3, [[CASE2]] ], [ 2, [[CASE1]] ], [ 1, [[CASE012]] ]
114; CHECK-NEXT:    [[PHI2_3:%.*]] = phi i8 [ 3, [[START]] ], [ 6, [[CASE2]] ], [ 5, [[CASE1]] ], [ 4, [[CASE012]] ]
115; CHECK-NEXT:    call void @use(i8 [[PHI2_1]])
116; CHECK-NEXT:    call void @use(i8 [[PHI2_2]])
117; CHECK-NEXT:    call void @use(i8 [[PHI2_3]])
118; CHECK-NEXT:    ret i8 [[PHI2_1]]
119;
120start:
121  switch i8 %arg, label %unreachable [
122  i8 0, label %case012
123  i8 1, label %case1
124  i8 2, label %case2
125  i8 3, label %end
126  ]
127unreachable:
128  unreachable
129case1:
130  br label %case012
131
132case2:
133  br label %case012
134
135case012:
136  %phi1_1 = phi i8 [ 3, %case2 ], [ 2, %case1 ], [1, %start]
137  %phi1_2 = phi i8 [ 6, %case2 ], [ 5, %case1 ], [4, %start]
138  br label %end
139
140end:
141  %phi2_1 = phi i8 [ %phi1_1, %case012 ], [ 4, %start ]
142  %phi2_2 = phi i8 [ %phi1_1, %case012 ], [ 5, %start ]
143  %phi2_3 = phi i8 [ %phi1_2, %case012 ], [ 3, %start ]
144  call void @use(i8 %phi2_1)
145  call void @use(i8 %phi2_2)
146  call void @use(i8 %phi2_3)
147  ret i8 %phi2_1
148}
149
150define i8 @phis_of_switch_multiple_stage0(i8 noundef %arg) {
151; CHECK-LABEL: define i8 @phis_of_switch_multiple_stage0(
152; CHECK-SAME: i8 noundef [[ARG:%.*]]) {
153; CHECK-NEXT:  start:
154; CHECK-NEXT:    switch i8 [[ARG]], label [[UNREACHABLE:%.*]] [
155; CHECK-NEXT:      i8 0, label [[CASE0:%.*]]
156; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
157; CHECK-NEXT:      i8 2, label [[CASE2:%.*]]
158; CHECK-NEXT:      i8 3, label [[CASE0123:%.*]]
159; CHECK-NEXT:      i8 4, label [[CASE01234:%.*]]
160; CHECK-NEXT:      i8 5, label [[END:%.*]]
161; CHECK-NEXT:    ]
162; CHECK:       unreachable:
163; CHECK-NEXT:    unreachable
164; CHECK:       case0:
165; CHECK-NEXT:    br label [[END]]
166; CHECK:       case1:
167; CHECK-NEXT:    br label [[END]]
168; CHECK:       case2:
169; CHECK-NEXT:    br label [[END]]
170; CHECK:       case0123:
171; CHECK-NEXT:    br label [[END]]
172; CHECK:       case01234:
173; CHECK-NEXT:    br label [[END]]
174; CHECK:       end:
175; CHECK-NEXT:    [[PHI3:%.*]] = phi i8 [ 6, [[START:%.*]] ], [ 3, [[CASE2]] ], [ 2, [[CASE1]] ], [ 1, [[CASE0]] ], [ 4, [[CASE0123]] ], [ 5, [[CASE01234]] ]
176; CHECK-NEXT:    ret i8 [[PHI3]]
177;
178start:
179  switch i8 %arg, label %unreachable [
180  i8 0, label %case0
181  i8 1, label %case1
182  i8 2, label %case2
183  i8 3, label %case0123
184  i8 4, label %case01234
185  i8 5, label %end
186  ]
187unreachable:
188  unreachable
189
190case0:
191  br label %case0123
192
193case1:
194  br label %case0123
195
196case2:
197  br label %case0123
198
199case0123:
200  %phi1 = phi i8 [4, %start], [ 3, %case2 ], [ 2, %case1 ], [ 1, %case0 ]
201  br label %case01234
202
203case01234:
204  %phi2 = phi i8 [ %phi1, %case0123 ], [ 5, %start ]
205  br label %end
206
207end:
208  %phi3 = phi i8 [ %phi2, %case01234 ], [6, %start]
209  ret i8 %phi3
210}
211
212define i8 @phis_of_switch_multiple_stage1(i8 noundef %arg) {
213; CHECK-LABEL: define i8 @phis_of_switch_multiple_stage1(
214; CHECK-SAME: i8 noundef [[ARG:%.*]]) {
215; CHECK-NEXT:  start:
216; CHECK-NEXT:    switch i8 [[ARG]], label [[UNREACHABLE:%.*]] [
217; CHECK-NEXT:      i8 0, label [[CASE0:%.*]]
218; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
219; CHECK-NEXT:      i8 2, label [[CASE012:%.*]]
220; CHECK-NEXT:      i8 3, label [[CASE3:%.*]]
221; CHECK-NEXT:      i8 4, label [[CASE4:%.*]]
222; CHECK-NEXT:      i8 5, label [[CASE345:%.*]]
223; CHECK-NEXT:      i8 6, label [[CASE0123456:%.*]]
224; CHECK-NEXT:    ]
225; CHECK:       unreachable:
226; CHECK-NEXT:    unreachable
227; CHECK:       case0:
228; CHECK-NEXT:    br label [[CASE0123456]]
229; CHECK:       case1:
230; CHECK-NEXT:    br label [[CASE0123456]]
231; CHECK:       case012:
232; CHECK-NEXT:    br label [[CASE0123456]]
233; CHECK:       case3:
234; CHECK-NEXT:    br label [[CASE0123456]]
235; CHECK:       case4:
236; CHECK-NEXT:    br label [[CASE0123456]]
237; CHECK:       case345:
238; CHECK-NEXT:    br label [[CASE0123456]]
239; CHECK:       case0123456:
240; CHECK-NEXT:    [[PHI1234567:%.*]] = phi i8 [ 7, [[START:%.*]] ], [ 2, [[CASE1]] ], [ 1, [[CASE0]] ], [ 3, [[CASE012]] ], [ 5, [[CASE4]] ], [ 4, [[CASE3]] ], [ 6, [[CASE345]] ]
241; CHECK-NEXT:    ret i8 [[PHI1234567]]
242;
243start:
244  switch i8 %arg, label %unreachable [
245  i8 0, label %case0
246  i8 1, label %case1
247  i8 2, label %case012
248  i8 3, label %case3
249  i8 4, label %case4
250  i8 5, label %case345
251  i8 6, label %case0123456
252  ]
253unreachable:
254  unreachable
255case0:
256  br label %case012
257
258case1:
259  br label %case012
260
261case012:
262  %phi123 = phi i8 [3, %start], [ 2, %case1 ], [ 1, %case0 ]
263  br label %case0123456
264
265case3:
266  br label %case345
267
268case4:
269  br label %case345
270
271case345:
272  %phi456 = phi i8 [6, %start], [ 5, %case4 ], [ 4, %case3 ]
273  br label %case0123456
274
275case0123456:
276  %phi1234567 = phi i8 [7, %start], [ %phi456, %case345 ], [ %phi123, %case012 ]
277  ret i8 %phi1234567
278
279}
280
281define i8 @phis_of_switch_extra_use_fail(i8 noundef %arg) {
282; CHECK-LABEL: define i8 @phis_of_switch_extra_use_fail(
283; CHECK-SAME: i8 noundef [[ARG:%.*]]) {
284; CHECK-NEXT:  start:
285; CHECK-NEXT:    switch i8 [[ARG]], label [[UNREACHABLE:%.*]] [
286; CHECK-NEXT:      i8 0, label [[CASE012:%.*]]
287; CHECK-NEXT:      i8 1, label [[CASE1:%.*]]
288; CHECK-NEXT:      i8 2, label [[CASE2:%.*]]
289; CHECK-NEXT:      i8 3, label [[END:%.*]]
290; CHECK-NEXT:    ]
291; CHECK:       unreachable:
292; CHECK-NEXT:    unreachable
293; CHECK:       case1:
294; CHECK-NEXT:    br label [[CASE012]]
295; CHECK:       case2:
296; CHECK-NEXT:    br label [[CASE012]]
297; CHECK:       case012:
298; CHECK-NEXT:    [[PHI1:%.*]] = phi i8 [ 3, [[CASE2]] ], [ 2, [[CASE1]] ], [ 1, [[START:%.*]] ]
299; CHECK-NEXT:    call void @use(i8 [[PHI1]])
300; CHECK-NEXT:    br label [[END]]
301; CHECK:       end:
302; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ [[PHI1]], [[CASE012]] ], [ 4, [[START]] ]
303; CHECK-NEXT:    ret i8 [[PHI2]]
304;
305start:
306  switch i8 %arg, label %unreachable [
307  i8 0, label %case012
308  i8 1, label %case1
309  i8 2, label %case2 i8 3, label %end
310  ]
311unreachable:
312  unreachable
313case1:
314  br label %case012
315
316case2:
317  br label %case012
318
319case012:
320  %phi1 = phi i8 [ 3, %case2 ], [ 2, %case1 ], [1, %start]
321  call void @use(i8 %phi1)
322  br label %end
323
324end:
325  %phi2 = phi i8 [ %phi1, %case012 ], [ 4, %start ]
326  ret i8 %phi2
327}
328