Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / switch-to-select-two-case.ll
blob1e2f18b3f339d43344489233da954486caa0ae81
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
4 ; int foo1_with_default(int a) {
5 ;   switch(a) {
6 ;     case 10:
7 ;       return 10;
8 ;     case 20:
9 ;       return 2;
10 ;   }
11 ;   return 4;
12 ; }
14 define i32 @foo1_with_default(i32 %a) {
15 ; CHECK-LABEL: @foo1_with_default(
16 ; CHECK-NEXT:  entry:
17 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[A:%.*]], 20
18 ; CHECK-NEXT:    [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 2, i32 4
19 ; CHECK-NEXT:    [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 [[A]], 10
20 ; CHECK-NEXT:    [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i32 10, i32 [[SWITCH_SELECT]]
21 ; CHECK-NEXT:    ret i32 [[SWITCH_SELECT2]]
23 entry:
24   switch i32 %a, label %sw.epilog [
25   i32 10, label %sw.bb
26   i32 20, label %sw.bb1
27   ]
29 sw.bb:
30   br label %return
32 sw.bb1:
33   br label %return
35 sw.epilog:
36   br label %return
38 return:
39   %retval.0 = phi i32 [ 4, %sw.epilog ], [ 2, %sw.bb1 ], [ 10, %sw.bb ]
40   ret i32 %retval.0
43 ; Same as above, but both cases have the same value.
44 define i32 @same_value(i32 %a) {
45 ; CHECK-LABEL: @same_value(
46 ; CHECK-NEXT:  entry:
47 ; CHECK-NEXT:    [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i32 [[A:%.*]], 10
48 ; CHECK-NEXT:    [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i32 [[A]], 20
49 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
50 ; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i32 10, i32 4
51 ; CHECK-NEXT:    ret i32 [[TMP0]]
53 entry:
54   switch i32 %a, label %sw.epilog [
55   i32 10, label %sw.bb
56   i32 20, label %sw.bb
57   ]
59 sw.bb:
60   br label %return
62 sw.epilog:
63   br label %return
65 return:
66   %retval.0 = phi i32 [ 4, %sw.epilog ], [ 10, %sw.bb ]
67   ret i32 %retval.0
70 define i1 @switch_to_select_same2_case_results_different_default(i8 %0) {
71 ; CHECK-LABEL: @switch_to_select_same2_case_results_different_default(
72 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i8 [[TMP0:%.*]], -5
73 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
74 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
75 ; CHECK-NEXT:    ret i1 [[TMP2]]
77   switch i8 %0, label %2 [
78   i8 4, label %3
79   i8 0, label %3
80   ]
83   br label %3
86   %4 = phi i1 [ false, %2 ], [ true, %1 ], [ true, %1 ]
87   ret i1 %4
90 define i1 @switch_to_select_same2_case_results_different_default_and_positive_offset_for_case(i8 %0) {
91 ; CHECK-LABEL: @switch_to_select_same2_case_results_different_default_and_positive_offset_for_case(
92 ; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 [[TMP0:%.*]], 43
93 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i8 [[TMP2]], -3
94 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i8 [[SWITCH_AND]], 0
95 ; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
96 ; CHECK-NEXT:    ret i1 [[TMP3]]
98   switch i8 %0, label %2 [
99   i8 43, label %3
100   i8 45, label %3
101   ]
104   br label %3
107   %4 = phi i1 [ false, %2 ], [ true, %1 ], [ true, %1 ]
108   ret i1 %4
111 define i8 @switch_to_select_same2_case_results_different_default_and_negative_offset_for_case(i32 %i) {
112 ; CHECK-LABEL: @switch_to_select_same2_case_results_different_default_and_negative_offset_for_case(
113 ; CHECK-NEXT:  entry:
114 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[I:%.*]], -5
115 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -3
116 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
117 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i8 3, i8 42
118 ; CHECK-NEXT:    ret i8 [[TMP1]]
120 entry:
121   switch i32 %i, label %default [
122   i32 -3, label %end
123   i32 -5, label %end
124   ]
126 default:
127   br label %end
129 end:
130   %t0 = phi i8 [ 42, %default ], [ 3, %entry ], [ 3, %entry ]
131   ret i8 %t0
134 define i1 @switch_to_select_same4_case_results_different_default(i32 %i) {
135 ; CHECK-LABEL: @switch_to_select_same4_case_results_different_default(
136 ; CHECK-NEXT:  entry:
137 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[I:%.*]], -7
138 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
139 ; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
140 ; CHECK-NEXT:    ret i1 [[TMP0]]
142 entry:
143   switch i32 %i, label %lor.rhs [
144   i32 0, label %lor.end
145   i32 2, label %lor.end
146   i32 4, label %lor.end
147   i32 6, label %lor.end
148   ]
150 lor.rhs:
151   br label %lor.end
153 lor.end:
154   %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
155   ret i1 %0
158 define i1 @switch_to_select_same4_case_results_different_default_alt_bitmask(i32 %i) {
159 ; CHECK-LABEL: @switch_to_select_same4_case_results_different_default_alt_bitmask(
160 ; CHECK-NEXT:  entry:
161 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[I:%.*]], -11
162 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
163 ; CHECK-NEXT:    [[TMP0:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
164 ; CHECK-NEXT:    ret i1 [[TMP0]]
166 entry:
167   switch i32 %i, label %lor.rhs [
168   i32 0, label %lor.end
169   i32 2, label %lor.end
170   i32 8, label %lor.end
171   i32 10, label %lor.end
172   ]
174 lor.rhs:
175   br label %lor.end
177 lor.end:
178   %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
179   ret i1 %0
182 define i1 @switch_to_select_same4_case_results_different_default_positive_offset(i32 %i) {
183 ; CHECK-LABEL: @switch_to_select_same4_case_results_different_default_positive_offset(
184 ; CHECK-NEXT:  entry:
185 ; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[I:%.*]], 2
186 ; CHECK-NEXT:    [[SWITCH_AND:%.*]] = and i32 [[TMP0]], -11
187 ; CHECK-NEXT:    [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 [[SWITCH_AND]], 0
188 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[SWITCH_SELECTCMP]], i1 true, i1 false
189 ; CHECK-NEXT:    ret i1 [[TMP1]]
191 entry:
192   switch i32 %i, label %lor.rhs [
193   i32 2, label %lor.end
194   i32 4, label %lor.end
195   i32 10, label %lor.end
196   i32 12, label %lor.end
197   ]
199 lor.rhs:
200   br label %lor.end
202 lor.end:
203   %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
204   ret i1 %0
207 define i1 @switch_to_select_invalid_mask(i32 %i) {
208 ; CHECK-LABEL: @switch_to_select_invalid_mask(
209 ; CHECK-NEXT:  entry:
210 ; CHECK-NEXT:    switch i32 [[I:%.*]], label [[LOR_RHS:%.*]] [
211 ; CHECK-NEXT:      i32 1, label [[LOR_END:%.*]]
212 ; CHECK-NEXT:      i32 4, label [[LOR_END]]
213 ; CHECK-NEXT:      i32 10, label [[LOR_END]]
214 ; CHECK-NEXT:      i32 12, label [[LOR_END]]
215 ; CHECK-NEXT:    ]
216 ; CHECK:       lor.rhs:
217 ; CHECK-NEXT:    br label [[LOR_END]]
218 ; CHECK:       lor.end:
219 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
220 ; CHECK-NEXT:    ret i1 [[TMP0]]
222 entry:
223   switch i32 %i, label %lor.rhs [
224   i32 1, label %lor.end
225   i32 4, label %lor.end
226   i32 10, label %lor.end
227   i32 12, label %lor.end
228   ]
230 lor.rhs:
231   br label %lor.end
233 lor.end:
234   %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ], [ true, %entry ]
235   ret i1 %0
238 define i1 @switch_to_select_nonpow2_cases(i32 %i) {
239 ; CHECK-LABEL: @switch_to_select_nonpow2_cases(
240 ; CHECK-NEXT:  entry:
241 ; CHECK-NEXT:    switch i32 [[I:%.*]], label [[LOR_RHS:%.*]] [
242 ; CHECK-NEXT:      i32 0, label [[LOR_END:%.*]]
243 ; CHECK-NEXT:      i32 2, label [[LOR_END]]
244 ; CHECK-NEXT:      i32 4, label [[LOR_END]]
245 ; CHECK-NEXT:    ]
246 ; CHECK:       lor.rhs:
247 ; CHECK-NEXT:    br label [[LOR_END]]
248 ; CHECK:       lor.end:
249 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ true, [[ENTRY:%.*]] ], [ false, [[LOR_RHS]] ], [ true, [[ENTRY]] ], [ true, [[ENTRY]] ]
250 ; CHECK-NEXT:    ret i1 [[TMP0]]
252 entry:
253   switch i32 %i, label %lor.rhs [
254   i32 0, label %lor.end
255   i32 2, label %lor.end
256   i32 4, label %lor.end
257   ]
259 lor.rhs:
260   br label %lor.end
262 lor.end:
263   %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ]
264   ret i1 %0
267 ; TODO: we can produce the optimal code when there is no default also
268 define i8 @switch_to_select_two_case_results_no_default(i32 %i) {
269 ; CHECK-LABEL: @switch_to_select_two_case_results_no_default(
270 ; CHECK-NEXT:  entry:
271 ; CHECK-NEXT:    switch i32 [[I:%.*]], label [[DEFAULT:%.*]] [
272 ; CHECK-NEXT:      i32 0, label [[END:%.*]]
273 ; CHECK-NEXT:      i32 2, label [[END]]
274 ; CHECK-NEXT:      i32 4, label [[CASE3:%.*]]
275 ; CHECK-NEXT:      i32 6, label [[CASE4:%.*]]
276 ; CHECK-NEXT:    ]
277 ; CHECK:       case3:
278 ; CHECK-NEXT:    br label [[END]]
279 ; CHECK:       case4:
280 ; CHECK-NEXT:    br label [[END]]
281 ; CHECK:       default:
282 ; CHECK-NEXT:    unreachable
283 ; CHECK:       end:
284 ; CHECK-NEXT:    [[T0:%.*]] = phi i8 [ 44, [[CASE3]] ], [ 44, [[CASE4]] ], [ 42, [[ENTRY:%.*]] ], [ 42, [[ENTRY]] ]
285 ; CHECK-NEXT:    ret i8 [[T0]]
287 entry:
288   switch i32 %i, label %default [
289   i32 0, label %case1
290   i32 2, label %case2
291   i32 4, label %case3
292   i32 6, label %case4
293   ]
295 case1:
296   br label %end
298 case2:
299   br label %end
301 case3:
302   br label %end
304 case4:
305   br label %end
307 default:
308   unreachable
310 end:
311   %t0 = phi i8 [ 42, %case1 ], [ 42, %case2 ], [ 44, %case3 ], [ 44, %case4 ]
312   ret i8 %t0