• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; Test switch instructions.
2
3; RUN: %p2i -i %s --insts | FileCheck %s
4; RUN:   %p2i -i %s --args -notranslate -timing | \
5; RUN:   FileCheck --check-prefix=NOIR %s
6
7define internal void @testDefaultSwitch(i32 %a) {
8entry:
9  switch i32 %a, label %exit [
10  ]
11exit:
12  ret void
13}
14
15; CHECK:      define internal void @testDefaultSwitch(i32 %a) {
16; CHECK-NEXT: entry:
17; CHECK-NEXT:   switch i32 %a, label %exit [
18; CHECK-NEXT:   ]
19; CHECK-NEXT: exit:
20; CHECK-NEXT:   ret void
21; CHECK-NEXT: }
22
23define internal i32 @testSwitch(i32 %a) {
24entry:
25  switch i32 %a, label %sw.default [
26    i32 1, label %sw.epilog
27    i32 2, label %sw.epilog
28    i32 3, label %sw.epilog
29    i32 7, label %sw.bb1
30    i32 8, label %sw.bb1
31    i32 15, label %sw.bb2
32    i32 14, label %sw.bb2
33  ]
34
35sw.default:                                       ; preds = %entry
36  %add = add i32 %a, 27
37  br label %sw.epilog
38
39sw.bb1:                                           ; preds = %entry, %entry
40  %phitmp = sub i32 21, %a
41  br label %sw.bb2
42
43sw.bb2:                                           ; preds = %sw.bb1, %entry, %entry
44  %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ]
45  br label %sw.epilog
46
47sw.epilog:                                        ; preds = %sw.bb2, %sw.default, %entry, %entry, %entry
48  %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ]
49  ret i32 %result.1
50}
51
52; CHECK-NEXT:      define internal i32 @testSwitch(i32 %a) {
53; CHECK-NEXT: entry:
54; CHECK-NEXT:   switch i32 %a, label %sw.default [
55; CHECK-NEXT:     i32 1, label %sw.epilog
56; CHECK-NEXT:     i32 2, label %sw.epilog
57; CHECK-NEXT:     i32 3, label %sw.epilog
58; CHECK-NEXT:     i32 7, label %sw.bb1
59; CHECK-NEXT:     i32 8, label %sw.bb1
60; CHECK-NEXT:     i32 15, label %sw.bb2
61; CHECK-NEXT:     i32 14, label %sw.bb2
62; CHECK-NEXT:   ]
63; CHECK-NEXT: sw.default:
64; CHECK-NEXT:   %add = add i32 %a, 27
65; CHECK-NEXT:   br label %sw.epilog
66; CHECK-NEXT: sw.bb1:
67; CHECK-NEXT:   %phitmp = sub i32 21, %a
68; CHECK-NEXT:   br label %sw.bb2
69; CHECK-NEXT: sw.bb2:
70; CHECK-NEXT:   %result.0 = phi i32 [ 1, %entry ], [ 1, %entry ], [ %phitmp, %sw.bb1 ]
71; CHECK-NEXT:   br label %sw.epilog
72; CHECK-NEXT: sw.epilog:
73; CHECK-NEXT:   %result.1 = phi i32 [ %add, %sw.default ], [ %result.0, %sw.bb2 ], [ 17, %entry ], [ 17, %entry ], [ 17, %entry ]
74; CHECK-NEXT:   ret i32 %result.1
75; CHECK-NEXT: }
76
77define internal void @testSignedI32Values(i32 %a) {
78entry:
79  switch i32 %a, label %labelDefault [
80  i32 0, label %label0
81  i32 -1, label %labelM1
82  i32 3, label %labelOther
83  i32 -3, label %labelOther
84  i32 -2147483648, label %labelMin  ; min signed i32
85  i32 2147483647, label %labelMax   ; max signed i32
86  ]
87labelDefault:
88  ret void
89label0:
90  ret void
91labelM1:
92  ret void
93labelMin:
94  ret void
95labelMax:
96  ret void
97labelOther:
98  ret void
99}
100
101; CHECK-NEXT: define internal void @testSignedI32Values(i32 %a) {
102; CHECK-NEXT: entry:
103; CHECK-NEXT:   switch i32 %a, label %labelDefault [
104; CHECK-NEXT:     i32 0, label %label0
105; CHECK-NEXT:     i32 -1, label %labelM1
106; CHECK-NEXT:     i32 3, label %labelOther
107; CHECK-NEXT:     i32 -3, label %labelOther
108; CHECK-NEXT:     i32 -2147483648, label %labelMin
109; CHECK-NEXT:     i32 2147483647, label %labelMax
110; CHECK-NEXT:   ]
111; CHECK-NEXT: labelDefault:
112; CHECK-NEXT:   ret void
113; CHECK-NEXT: label0:
114; CHECK-NEXT:   ret void
115; CHECK-NEXT: labelM1:
116; CHECK-NEXT:   ret void
117; CHECK-NEXT: labelMin:
118; CHECK-NEXT:   ret void
119; CHECK-NEXT: labelMax:
120; CHECK-NEXT:   ret void
121; CHECK-NEXT: labelOther:
122; CHECK-NEXT:   ret void
123; CHECK-NEXT: }
124
125; Test values that cross signed i32 size boundaries.
126define internal void @testSignedI32Boundary(i32 %a) {
127entry:
128  switch i32 %a, label %exit [
129  i32 -2147483649, label %exit  ; min signed i32 - 1
130  i32 2147483648, label %exit   ; max signed i32 + 1
131  ]
132exit:
133  ret void
134}
135
136; CHECK-NEXT: define internal void @testSignedI32Boundary(i32 %a) {
137; CHECK-NEXT: entry:
138; CHECK-NEXT:   switch i32 %a, label %exit [
139; CHECK-NEXT:     i32 2147483647, label %exit
140; CHECK-NEXT:     i32 -2147483648, label %exit
141; CHECK-NEXT:   ]
142; CHECK-NEXT: exit:
143; CHECK-NEXT:   ret void
144; CHECK-NEXT: }
145
146define internal void @testUnsignedI32Values(i32 %a) {
147entry:
148  switch i32 %a, label %exit [
149  i32 0, label %exit
150  i32 2147483647, label %exit   ; max signed i32
151  i32 4294967295, label %exit   ; max unsigned i32
152  ]
153exit:
154  ret void
155}
156
157; CHECK-NEXT: define internal void @testUnsignedI32Values(i32 %a) {
158; CHECK-NEXT: entry:
159; CHECK-NEXT:   switch i32 %a, label %exit [
160; CHECK-NEXT:     i32 0, label %exit
161; CHECK-NEXT:     i32 2147483647, label %exit
162;                 ; Note that -1 is signed version of 4294967295
163; CHECK-NEXT:     i32 -1, label %exit
164; CHECK-NEXT:   ]
165; CHECK-NEXT: exit:
166; CHECK-NEXT:   ret void
167; CHECK-NEXT: }
168
169; Test values that cross unsigned i32 boundaries.
170define internal void @testUnsignedI32Boundary(i32 %a) {
171entry:
172  switch i32 %a, label %exit [
173  i32 4294967296, label %exit   ; max unsigned i32 + 1
174  ]
175exit:
176  ret void
177}
178
179; CHECK-NEXT: define internal void @testUnsignedI32Boundary(i32 %a) {
180; CHECK-NEXT: entry:
181; CHECK-NEXT:   switch i32 %a, label %exit [
182; CHECK-NEXT:     i32 0, label %exit
183; CHECK-NEXT:   ]
184; CHECK-NEXT: exit:
185; CHECK-NEXT:   ret void
186; CHECK-NEXT: }
187
188define internal void @testSignedI64Values(i64 %a) {
189entry:
190  switch i64 %a, label %exit [
191  i64 0, label %exit
192  i64 -9223372036854775808, label %exit   ; min signed i64
193  i64 9223372036854775807, label %exit    ; max signed i64
194  ]
195exit:
196  ret void
197}
198
199; CHECK-NEXT: define internal void @testSignedI64Values(i64 %a) {
200; CHECK-NEXT: entry:
201; CHECK-NEXT:   switch i64 %a, label %exit [
202; CHECK-NEXT:     i64 0, label %exit
203; CHECK-NEXT:     i64 -9223372036854775808, label %exit
204; CHECK-NEXT:     i64 9223372036854775807, label %exit
205; CHECK-NEXT:   ]
206; CHECK-NEXT: exit:
207; CHECK-NEXT:   ret void
208; CHECK-NEXT: }
209
210; Test values that cross signed i64 size boundaries.
211define internal void @testSignedI64Boundary(i64 %a) {
212entry:
213  switch i64 %a, label %exit [
214  i64 0, label %exit
215  i64 -9223372036854775809, label %exit   ; min signed i64 - 1
216  i64 9223372036854775808, label %exit   ; max signed i64 + 1
217  ]
218exit:
219  ret void
220}
221
222; CHECK-NEXT: define internal void @testSignedI64Boundary(i64 %a) {
223; CHECK-NEXT: entry:
224; CHECK-NEXT:   switch i64 %a, label %exit [
225; CHECK-NEXT:     i64 0, label %exit
226; CHECK-NEXT:     i64 9223372036854775807, label %exit
227; CHECK-NEXT:     i64 -9223372036854775808, label %exit
228; CHECK-NEXT:   ]
229; CHECK-NEXT: exit:
230; CHECK-NEXT:   ret void
231; CHECK-NEXT: }
232
233define internal void @testUnsignedI64Values(i64 %a) {
234entry:
235  switch i64 %a, label %exit [
236  i64 0, label %exit
237  i64 9223372036854775807, label %exit   ; max signed i64
238  i64 18446744073709551615, label %exit   ; max unsigned i64
239  ]
240exit:
241  ret void
242}
243
244; CHECK-NEXT: define internal void @testUnsignedI64Values(i64 %a) {
245; CHECK-NEXT: entry:
246; CHECK-NEXT:   switch i64 %a, label %exit [
247; CHECK-NEXT:     i64 0, label %exit
248; CHECK-NEXT:     i64 9223372036854775807, label %exit
249; CHECK-NEXT:     i64 -1, label %exit
250; CHECK-NEXT:   ]
251; CHECK-NEXT: exit:
252; CHECK-NEXT:   ret void
253; CHECK-NEXT: }
254
255; Test values that cross unsigned i64 size boundaries.
256define internal void @testUnsignedI64Boundary(i64 %a) {
257entry:
258  switch i64 %a, label %exit [
259  i64 18446744073709551616, label %exit   ; max unsigned i64 + 1
260  ]
261exit:
262  ret void
263}
264
265; CHECK-NEXT: define internal void @testUnsignedI64Boundary(i64 %a) {
266; CHECK-NEXT: entry:
267; CHECK-NEXT:   switch i64 %a, label %exit [
268; CHECK-NEXT:     i64 0, label %exit
269; CHECK-NEXT:   ]
270; CHECK-NEXT: exit:
271; CHECK-NEXT:   ret void
272; CHECK-NEXT: }
273
274define internal void @testSignedI16Values(i32 %p) {
275entry:
276  %a = trunc i32 %p to i16
277  switch i16 %a, label %exit [
278  i16 0, label %exit
279  i16 -1, label %exit
280  i16 3, label %exit
281  i16 -3, label %exit
282  i16 -32768, label %exit   ; min signed i16
283  i16 32767, label %exit   ; max unsigned i16
284  ]
285exit:
286  ret void
287}
288
289; CHECK-NEXT: define internal void @testSignedI16Values(i32 %p) {
290; CHECK-NEXT: entry:
291; CHECK-NEXT:   %a = trunc i32 %p to i16
292; CHECK-NEXT:   switch i16 %a, label %exit [
293; CHECK-NEXT:     i16 0, label %exit
294; CHECK-NEXT:     i16 -1, label %exit
295; CHECK-NEXT:     i16 3, label %exit
296; CHECK-NEXT:     i16 -3, label %exit
297; CHECK-NEXT:     i16 -32768, label %exit
298; CHECK-NEXT:     i16 32767, label %exit
299; CHECK-NEXT:   ]
300; CHECK-NEXT: exit:
301; CHECK-NEXT:   ret void
302; CHECK-NEXT: }
303
304; Test values that cross signed i16 size boundaries.
305define internal void @testSignedI16Boundary(i32 %p) {
306entry:
307  %a = trunc i32 %p to i16
308  switch i16 %a, label %exit [
309  i16 -32769, label %exit   ; min signed i16 - 1
310  i16 32768, label %exit   ; max unsigned i16 + 1
311  ]
312exit:
313  ret void
314}
315
316; CHECK-NEXT: define internal void @testSignedI16Boundary(i32 %p) {
317; CHECK-NEXT: entry:
318; CHECK-NEXT:   %a = trunc i32 %p to i16
319; CHECK-NEXT:   switch i16 %a, label %exit [
320; CHECK-NEXT:     i16 32767, label %exit
321; CHECK-NEXT:     i16 -32768, label %exit
322; CHECK-NEXT:   ]
323; CHECK-NEXT: exit:
324; CHECK-NEXT:   ret void
325; CHECK-NEXT: }
326
327define internal void @testUnsignedI16Values(i32 %p) {
328entry:
329  %a = trunc i32 %p to i16
330  switch i16 %a, label %exit [
331  i16 0, label %exit
332  i16 32767, label %exit   ; max signed i16
333  i16 65535, label %exit   ; max unsigned i16
334  ]
335exit:
336  ret void
337}
338
339; CHECK-NEXT: define internal void @testUnsignedI16Values(i32 %p) {
340; CHECK-NEXT: entry:
341; CHECK-NEXT:   %a = trunc i32 %p to i16
342; CHECK-NEXT:   switch i16 %a, label %exit [
343; CHECK-NEXT:     i16 0, label %exit
344; CHECK-NEXT:     i16 32767, label %exit
345;                 ; Note that -1 is signed version of 65535
346; CHECK-NEXT:     i16 -1, label %exit
347; CHECK-NEXT:   ]
348; CHECK-NEXT: exit:
349; CHECK-NEXT:   ret void
350; CHECK-NEXT: }
351
352; Test values that cross unsigned i16 size boundaries.
353define internal void @testUnsignedI16Boundary(i32 %p) {
354entry:
355  %a = trunc i32 %p to i16
356  switch i16 %a, label %exit [
357  i16 65536, label %exit   ; max unsigned i16 + 1
358  ]
359exit:
360  ret void
361}
362
363; CHECK-NEXT: define internal void @testUnsignedI16Boundary(i32 %p) {
364; CHECK-NEXT: entry:
365; CHECK-NEXT:   %a = trunc i32 %p to i16
366; CHECK-NEXT:   switch i16 %a, label %exit [
367; CHECK-NEXT:     i16 0, label %exit
368; CHECK-NEXT:   ]
369; CHECK-NEXT: exit:
370; CHECK-NEXT:   ret void
371; CHECK-NEXT: }
372
373define internal void @testSignedI8Values(i32 %p) {
374entry:
375  %a = trunc i32 %p to i8
376  switch i8 %a, label %exit [
377  i8 0, label %exit
378  i8 -1, label %exit
379  i8 3, label %exit
380  i8 -3, label %exit
381  i8 -128, label %exit   ; min signed i8
382  i8 127, label %exit   ; max unsigned i8
383  ]
384exit:
385  ret void
386}
387
388; CHECK-NEXT: define internal void @testSignedI8Values(i32 %p) {
389; CHECK-NEXT: entry:
390; CHECK-NEXT:   %a = trunc i32 %p to i8
391; CHECK-NEXT:   switch i8 %a, label %exit [
392; CHECK-NEXT:     i8 0, label %exit
393; CHECK-NEXT:     i8 -1, label %exit
394; CHECK-NEXT:     i8 3, label %exit
395; CHECK-NEXT:     i8 -3, label %exit
396; CHECK-NEXT:     i8 -128, label %exit
397; CHECK-NEXT:     i8 127, label %exit
398; CHECK-NEXT:   ]
399; CHECK-NEXT: exit:
400; CHECK-NEXT:   ret void
401; CHECK-NEXT: }
402
403; Test values that cross signed i8 size boundaries.
404define internal void @testSignedI8Boundary(i32 %p) {
405entry:
406  %a = trunc i32 %p to i8
407  switch i8 %a, label %exit [
408  i8 -129, label %exit   ; min signed i8 - 1
409  i8 128, label %exit   ; max unsigned i8 + 1
410  ]
411exit:
412  ret void
413}
414
415; CHECK-NEXT: define internal void @testSignedI8Boundary(i32 %p) {
416; CHECK-NEXT: entry:
417; CHECK-NEXT:   %a = trunc i32 %p to i8
418; CHECK-NEXT:   switch i8 %a, label %exit [
419; CHECK-NEXT:     i8 127, label %exit
420; CHECK-NEXT:     i8 -128, label %exit
421; CHECK-NEXT:   ]
422; CHECK-NEXT: exit:
423; CHECK-NEXT:   ret void
424; CHECK-NEXT: }
425
426
427define internal void @testUnsignedI8Values(i32 %p) {
428entry:
429  %a = trunc i32 %p to i8
430  switch i8 %a, label %exit [
431  i8 0, label %exit
432  i8 127, label %exit   ; max signed i8
433  i8 255, label %exit   ; max unsigned i8
434  ]
435exit:
436  ret void
437}
438
439; CHECK-NEXT: define internal void @testUnsignedI8Values(i32 %p) {
440; CHECK-NEXT: entry:
441; CHECK-NEXT:   %a = trunc i32 %p to i8
442; CHECK-NEXT:   switch i8 %a, label %exit [
443; CHECK-NEXT:     i8 0, label %exit
444; CHECK-NEXT:     i8 127, label %exit
445;                 ; Note that -1 is signed version of 255
446; CHECK-NEXT:     i8 -1, label %exit
447; CHECK-NEXT:   ]
448; CHECK-NEXT: exit:
449; CHECK-NEXT:   ret void
450; CHECK-NEXT: }
451
452; Test values that cross unsigned i8 size boundaries.
453define internal void @testUnsignedI8Boundary(i32 %p) {
454entry:
455  %a = trunc i32 %p to i8
456  switch i8 %a, label %exit [
457  i8 256, label %exit   ; max unsigned i8
458  ]
459exit:
460  ret void
461}
462
463; CHECK-NEXT: define internal void @testUnsignedI8Boundary(i32 %p) {
464; CHECK-NEXT: entry:
465; CHECK-NEXT:   %a = trunc i32 %p to i8
466; CHECK-NEXT:   switch i8 %a, label %exit [
467; CHECK-NEXT:     i8 0, label %exit
468; CHECK-NEXT:   ]
469; CHECK-NEXT: exit:
470; CHECK-NEXT:   ret void
471; CHECK-NEXT: }
472
473define internal void @testI1Values(i32 %p) {
474entry:
475  %a = trunc i32 %p to i1
476  switch i1 %a, label %exit [
477  i1 true, label %exit
478  i1 false, label %exit
479  ]
480exit:
481  ret void
482}
483
484; CHECK-NEXT: define internal void @testI1Values(i32 %p) {
485; CHECK-NEXT: entry:
486; CHECK-NEXT:   %a = trunc i32 %p to i1
487; CHECK-NEXT:   switch i1 %a, label %exit [
488; CHECK-NEXT:     i1 -1, label %exit
489; CHECK-NEXT:     i1 0, label %exit
490; CHECK-NEXT:   ]
491; CHECK-NEXT: exit:
492; CHECK-NEXT:   ret void
493; CHECK-NEXT: }
494
495; NOIR: Total across all functions
496