1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -simplifycfg -switch-to-lookup -S | FileCheck %s
3
4target datalayout = "e-n32"
5
6define i32 @test1(i32 %a) {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], 97
9; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 2
10; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 30
11; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
12; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
13; CHECK-NEXT:    i32 0, label [[ONE:%.*]]
14; CHECK-NEXT:    i32 1, label [[TWO:%.*]]
15; CHECK-NEXT:    i32 2, label [[THREE:%.*]]
16; CHECK-NEXT:    i32 3, label [[THREE]]
17; CHECK-NEXT:    ]
18; CHECK:       def:
19; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
20; CHECK-NEXT:    ret i32 [[MERGE]]
21; CHECK:       one:
22; CHECK-NEXT:    br label [[DEF]]
23; CHECK:       two:
24; CHECK-NEXT:    br label [[DEF]]
25; CHECK:       three:
26; CHECK-NEXT:    br label [[DEF]]
27;
28  switch i32 %a, label %def [
29  i32 97, label %one
30  i32 101, label %two
31  i32 105, label %three
32  i32 109, label %three
33  ]
34
35def:
36  ret i32 8867
37
38one:
39  ret i32 11984
40two:
41  ret i32 1143
42three:
43  ret i32 99783
44}
45
46; Optimization shouldn't trigger; bitwidth > 64
47define i128 @test2(i128 %a) {
48; CHECK-LABEL: @test2(
49; CHECK-NEXT:    switch i128 [[A:%.*]], label [[DEF:%.*]] [
50; CHECK-NEXT:    i128 97, label [[ONE:%.*]]
51; CHECK-NEXT:    i128 101, label [[TWO:%.*]]
52; CHECK-NEXT:    i128 105, label [[THREE:%.*]]
53; CHECK-NEXT:    i128 109, label [[THREE]]
54; CHECK-NEXT:    ]
55; CHECK:       def:
56; CHECK-NEXT:    [[MERGE:%.*]] = phi i128 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
57; CHECK-NEXT:    ret i128 [[MERGE]]
58; CHECK:       one:
59; CHECK-NEXT:    br label [[DEF]]
60; CHECK:       two:
61; CHECK-NEXT:    br label [[DEF]]
62; CHECK:       three:
63; CHECK-NEXT:    br label [[DEF]]
64;
65  switch i128 %a, label %def [
66  i128 97, label %one
67  i128 101, label %two
68  i128 105, label %three
69  i128 109, label %three
70  ]
71
72def:
73  ret i128 8867
74
75one:
76  ret i128 11984
77two:
78  ret i128 1143
79three:
80  ret i128 99783
81}
82
83; Optimization shouldn't trigger; no holes present
84define i32 @test3(i32 %a) {
85; CHECK-LABEL: @test3(
86; CHECK-NEXT:    switch i32 [[A:%.*]], label [[DEF:%.*]] [
87; CHECK-NEXT:    i32 97, label [[ONE:%.*]]
88; CHECK-NEXT:    i32 98, label [[TWO:%.*]]
89; CHECK-NEXT:    i32 99, label [[THREE:%.*]]
90; CHECK-NEXT:    ]
91; CHECK:       def:
92; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
93; CHECK-NEXT:    ret i32 [[MERGE]]
94; CHECK:       one:
95; CHECK-NEXT:    br label [[DEF]]
96; CHECK:       two:
97; CHECK-NEXT:    br label [[DEF]]
98; CHECK:       three:
99; CHECK-NEXT:    br label [[DEF]]
100;
101  switch i32 %a, label %def [
102  i32 97, label %one
103  i32 98, label %two
104  i32 99, label %three
105  ]
106
107def:
108  ret i32 8867
109
110one:
111  ret i32 11984
112two:
113  ret i32 1143
114three:
115  ret i32 99783
116}
117
118; Optimization shouldn't trigger; not an arithmetic progression
119define i32 @test4(i32 %a) {
120; CHECK-LABEL: @test4(
121; CHECK-NEXT:    switch i32 [[A:%.*]], label [[DEF:%.*]] [
122; CHECK-NEXT:    i32 97, label [[ONE:%.*]]
123; CHECK-NEXT:    i32 102, label [[TWO:%.*]]
124; CHECK-NEXT:    i32 105, label [[THREE:%.*]]
125; CHECK-NEXT:    i32 109, label [[THREE]]
126; CHECK-NEXT:    ]
127; CHECK:       def:
128; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
129; CHECK-NEXT:    ret i32 [[MERGE]]
130; CHECK:       one:
131; CHECK-NEXT:    br label [[DEF]]
132; CHECK:       two:
133; CHECK-NEXT:    br label [[DEF]]
134; CHECK:       three:
135; CHECK-NEXT:    br label [[DEF]]
136;
137  switch i32 %a, label %def [
138  i32 97, label %one
139  i32 102, label %two
140  i32 105, label %three
141  i32 109, label %three
142  ]
143
144def:
145  ret i32 8867
146
147one:
148  ret i32 11984
149two:
150  ret i32 1143
151three:
152  ret i32 99783
153}
154
155; Optimization shouldn't trigger; not a power of two
156define i32 @test5(i32 %a) {
157; CHECK-LABEL: @test5(
158; CHECK-NEXT:    switch i32 [[A:%.*]], label [[DEF:%.*]] [
159; CHECK-NEXT:    i32 97, label [[ONE:%.*]]
160; CHECK-NEXT:    i32 102, label [[TWO:%.*]]
161; CHECK-NEXT:    i32 107, label [[THREE:%.*]]
162; CHECK-NEXT:    i32 112, label [[THREE]]
163; CHECK-NEXT:    ]
164; CHECK:       def:
165; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
166; CHECK-NEXT:    ret i32 [[MERGE]]
167; CHECK:       one:
168; CHECK-NEXT:    br label [[DEF]]
169; CHECK:       two:
170; CHECK-NEXT:    br label [[DEF]]
171; CHECK:       three:
172; CHECK-NEXT:    br label [[DEF]]
173;
174  switch i32 %a, label %def [
175  i32 97, label %one
176  i32 102, label %two
177  i32 107, label %three
178  i32 112, label %three
179  ]
180
181def:
182  ret i32 8867
183
184one:
185  ret i32 11984
186two:
187  ret i32 1143
188three:
189  ret i32 99783
190}
191
192define i32 @test6(i32 %a) optsize {
193; CHECK-LABEL: @test6(
194; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], -109
195; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 2
196; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 30
197; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
198; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
199; CHECK-NEXT:    i32 3, label [[ONE:%.*]]
200; CHECK-NEXT:    i32 2, label [[TWO:%.*]]
201; CHECK-NEXT:    i32 1, label [[THREE:%.*]]
202; CHECK-NEXT:    i32 0, label [[THREE]]
203; CHECK-NEXT:    ]
204; CHECK:       def:
205; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
206; CHECK-NEXT:    ret i32 [[MERGE]]
207; CHECK:       one:
208; CHECK-NEXT:    br label [[DEF]]
209; CHECK:       two:
210; CHECK-NEXT:    br label [[DEF]]
211; CHECK:       three:
212; CHECK-NEXT:    br label [[DEF]]
213;
214  switch i32 %a, label %def [
215  i32 -97, label %one
216  i32 -101, label %two
217  i32 -105, label %three
218  i32 -109, label %three
219  ]
220
221def:
222  ret i32 8867
223
224one:
225  ret i32 11984
226two:
227  ret i32 1143
228three:
229  ret i32 99783
230}
231
232define i8 @test7(i8 %a) optsize {
233; CHECK-LABEL: @test7(
234; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[A:%.*]], -36
235; CHECK-NEXT:    [[TMP2:%.*]] = lshr i8 [[TMP1]], 2
236; CHECK-NEXT:    [[TMP3:%.*]] = shl i8 [[TMP1]], 6
237; CHECK-NEXT:    [[TMP4:%.*]] = or i8 [[TMP2]], [[TMP3]]
238; CHECK-NEXT:    [[TMP5:%.*]] = icmp ult i8 [[TMP4]], 4
239; CHECK-NEXT:    br i1 [[TMP5]], label [[SWITCH_LOOKUP:%.*]], label [[DEF:%.*]]
240; CHECK:       switch.lookup:
241; CHECK-NEXT:    [[SWITCH_CAST:%.*]] = zext i8 [[TMP4]] to i32
242; CHECK-NEXT:    [[SWITCH_SHIFTAMT:%.*]] = mul i32 [[SWITCH_CAST]], 8
243; CHECK-NEXT:    [[SWITCH_DOWNSHIFT:%.*]] = lshr i32 -943228976, [[SWITCH_SHIFTAMT]]
244; CHECK-NEXT:    [[SWITCH_MASKED:%.*]] = trunc i32 [[SWITCH_DOWNSHIFT]] to i8
245; CHECK-NEXT:    ret i8 [[SWITCH_MASKED]]
246; CHECK:       def:
247; CHECK-NEXT:    ret i8 -93
248;
249  switch i8 %a, label %def [
250  i8 220, label %one
251  i8 224, label %two
252  i8 228, label %three
253  i8 232, label %three
254  ]
255
256def:
257  ret i8 8867
258
259one:
260  ret i8 11984
261two:
262  ret i8 1143
263three:
264  ret i8 99783
265}
266
267define i32 @test8(i32 %a) optsize {
268; CHECK-LABEL: @test8(
269; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], 97
270; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 2
271; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 30
272; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
273; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
274; CHECK-NEXT:    i32 0, label [[ONE:%.*]]
275; CHECK-NEXT:    i32 1, label [[TWO:%.*]]
276; CHECK-NEXT:    i32 2, label [[THREE:%.*]]
277; CHECK-NEXT:    i32 4, label [[THREE]]
278; CHECK-NEXT:    ]
279; CHECK:       def:
280; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
281; CHECK-NEXT:    ret i32 [[MERGE]]
282; CHECK:       one:
283; CHECK-NEXT:    br label [[DEF]]
284; CHECK:       two:
285; CHECK-NEXT:    br label [[DEF]]
286; CHECK:       three:
287; CHECK-NEXT:    br label [[DEF]]
288;
289  switch i32 %a, label %def [
290  i32 97, label %one
291  i32 101, label %two
292  i32 105, label %three
293  i32 113, label %three
294  ]
295
296def:
297  ret i32 8867
298
299one:
300  ret i32 11984
301two:
302  ret i32 1143
303three:
304  ret i32 99783
305}
306
307define i32 @test9(i32 %a) {
308; CHECK-LABEL: @test9(
309; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[A:%.*]], 6
310; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP1]], 1
311; CHECK-NEXT:    [[TMP3:%.*]] = shl i32 [[TMP1]], 31
312; CHECK-NEXT:    [[TMP4:%.*]] = or i32 [[TMP2]], [[TMP3]]
313; CHECK-NEXT:    switch i32 [[TMP4]], label [[DEF:%.*]] [
314; CHECK-NEXT:    i32 6, label [[ONE:%.*]]
315; CHECK-NEXT:    i32 7, label [[TWO:%.*]]
316; CHECK-NEXT:    i32 0, label [[THREE:%.*]]
317; CHECK-NEXT:    i32 2, label [[THREE]]
318; CHECK-NEXT:    ]
319; CHECK:       def:
320; CHECK-NEXT:    [[MERGE:%.*]] = phi i32 [ 8867, [[TMP0:%.*]] ], [ 11984, [[ONE]] ], [ 1143, [[TWO]] ], [ 99783, [[THREE]] ]
321; CHECK-NEXT:    ret i32 [[MERGE]]
322; CHECK:       one:
323; CHECK-NEXT:    br label [[DEF]]
324; CHECK:       two:
325; CHECK-NEXT:    br label [[DEF]]
326; CHECK:       three:
327; CHECK-NEXT:    br label [[DEF]]
328;
329  switch i32 %a, label %def [
330  i32 18, label %one
331  i32 20, label %two
332  i32 6, label %three
333  i32 10, label %three
334  ]
335
336def:
337  ret i32 8867
338
339one:
340  ret i32 11984
341two:
342  ret i32 1143
343three:
344  ret i32 99783
345}
346
347