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
4 ; Test a bunch of cases where the combination of phis in switch should be merged into one phi
8 define i8 @phis_of_switch_minimal(i8 noundef %arg) {
9 ; CHECK-LABEL: define i8 @phis_of_switch_minimal
10 ; CHECK-SAME: (i8 noundef [[ARG:%.*]]) {
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:%.*]]
18 ; CHECK-NEXT: unreachable
20 ; CHECK-NEXT: br label [[END]]
22 ; CHECK-NEXT: br label [[END]]
24 ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ 3, [[START:%.*]] ], [ 2, [[CASE1]] ], [ 1, [[CASE01]] ]
25 ; CHECK-NEXT: ret i8 [[PHI2]]
28 switch i8 %arg, label %unreachable [
39 %phi1 = phi i8 [ 2, %case1 ], [1, %start]
43 %phi2 = phi i8 [ %phi1, %case01 ], [ 3, %start ]
47 define i8 @phis_of_switch(i8 noundef %arg) {
48 ; CHECK-LABEL: define i8 @phis_of_switch
49 ; CHECK-SAME: (i8 noundef [[ARG:%.*]]) {
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:%.*]]
58 ; CHECK-NEXT: unreachable
60 ; CHECK-NEXT: br label [[END]]
62 ; CHECK-NEXT: br label [[END]]
64 ; CHECK-NEXT: br label [[END]]
66 ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ 4, [[START:%.*]] ], [ 3, [[CASE2]] ], [ 2, [[CASE1]] ], [ 1, [[CASE012]] ]
67 ; CHECK-NEXT: ret i8 [[PHI2]]
70 switch i8 %arg, label %unreachable [
85 %phi1 = phi i8 [ 3, %case2 ], [ 2, %case1 ], [1, %start]
89 %phi2 = phi i8 [ %phi1, %case012 ], [ 4, %start ]
93 define i8 @multiple_phis_of_switch(i8 noundef %arg) {
94 ; CHECK-LABEL: define i8 @multiple_phis_of_switch
95 ; CHECK-SAME: (i8 noundef [[ARG:%.*]]) {
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:%.*]]
103 ; CHECK: unreachable:
104 ; CHECK-NEXT: unreachable
106 ; CHECK-NEXT: br label [[END]]
108 ; CHECK-NEXT: br label [[END]]
110 ; CHECK-NEXT: br label [[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]]
121 switch i8 %arg, label %unreachable [
136 %phi1_1 = phi i8 [ 3, %case2 ], [ 2, %case1 ], [1, %start]
137 %phi1_2 = phi i8 [ 6, %case2 ], [ 5, %case1 ], [4, %start]
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)
150 define 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:%.*]]) {
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:%.*]]
162 ; CHECK: unreachable:
163 ; CHECK-NEXT: unreachable
165 ; CHECK-NEXT: br label [[END]]
167 ; CHECK-NEXT: br label [[END]]
169 ; CHECK-NEXT: br label [[END]]
171 ; CHECK-NEXT: br label [[END]]
173 ; CHECK-NEXT: br label [[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]]
179 switch i8 %arg, label %unreachable [
183 i8 3, label %case0123
184 i8 4, label %case01234
200 %phi1 = phi i8 [4, %start], [ 3, %case2 ], [ 2, %case1 ], [ 1, %case0 ]
204 %phi2 = phi i8 [ %phi1, %case0123 ], [ 5, %start ]
208 %phi3 = phi i8 [ %phi2, %case01234 ], [6, %start]
212 define 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:%.*]]) {
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:%.*]]
225 ; CHECK: unreachable:
226 ; CHECK-NEXT: unreachable
228 ; CHECK-NEXT: br label [[CASE0123456]]
230 ; CHECK-NEXT: br label [[CASE0123456]]
232 ; CHECK-NEXT: br label [[CASE0123456]]
234 ; CHECK-NEXT: br label [[CASE0123456]]
236 ; CHECK-NEXT: br label [[CASE0123456]]
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]]
244 switch i8 %arg, label %unreachable [
251 i8 6, label %case0123456
262 %phi123 = phi i8 [3, %start], [ 2, %case1 ], [ 1, %case0 ]
263 br label %case0123456
272 %phi456 = phi i8 [6, %start], [ 5, %case4 ], [ 4, %case3 ]
273 br label %case0123456
276 %phi1234567 = phi i8 [7, %start], [ %phi456, %case345 ], [ %phi123, %case012 ]
281 define 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:%.*]]) {
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:%.*]]
291 ; CHECK: unreachable:
292 ; CHECK-NEXT: unreachable
294 ; CHECK-NEXT: br label [[CASE012]]
296 ; CHECK-NEXT: br label [[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]]
302 ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[PHI1]], [[CASE012]] ], [ 4, [[START]] ]
303 ; CHECK-NEXT: ret i8 [[PHI2]]
306 switch i8 %arg, label %unreachable [
309 i8 2, label %case2 i8 3, label %end
320 %phi1 = phi i8 [ 3, %case2 ], [ 2, %case1 ], [1, %start]
321 call void @use(i8 %phi1)
325 %phi2 = phi i8 [ %phi1, %case012 ], [ 4, %start ]