xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGen/switch.c (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s
2*f4a2713aSLionel Sambuc 
foo(int i)3*f4a2713aSLionel Sambuc int foo(int i) {
4*f4a2713aSLionel Sambuc   int j = 0;
5*f4a2713aSLionel Sambuc   switch (i) {
6*f4a2713aSLionel Sambuc   case -1:
7*f4a2713aSLionel Sambuc     j = 1; break;
8*f4a2713aSLionel Sambuc   case 1 :
9*f4a2713aSLionel Sambuc     j = 2; break;
10*f4a2713aSLionel Sambuc   case 2:
11*f4a2713aSLionel Sambuc     j = 3; break;
12*f4a2713aSLionel Sambuc   default:
13*f4a2713aSLionel Sambuc     j = 42; break;
14*f4a2713aSLionel Sambuc   }
15*f4a2713aSLionel Sambuc   j = j + 1;
16*f4a2713aSLionel Sambuc   return j;
17*f4a2713aSLionel Sambuc }
18*f4a2713aSLionel Sambuc 
foo2(int i)19*f4a2713aSLionel Sambuc int foo2(int i) {
20*f4a2713aSLionel Sambuc   int j = 0;
21*f4a2713aSLionel Sambuc   switch (i) {
22*f4a2713aSLionel Sambuc   case 1 :
23*f4a2713aSLionel Sambuc     j = 2; break;
24*f4a2713aSLionel Sambuc   case 2 ... 10:
25*f4a2713aSLionel Sambuc     j = 3; break;
26*f4a2713aSLionel Sambuc   default:
27*f4a2713aSLionel Sambuc     j = 42; break;
28*f4a2713aSLionel Sambuc   }
29*f4a2713aSLionel Sambuc   j = j + 1;
30*f4a2713aSLionel Sambuc   return j;
31*f4a2713aSLionel Sambuc }
32*f4a2713aSLionel Sambuc 
foo3(int i)33*f4a2713aSLionel Sambuc int foo3(int i) {
34*f4a2713aSLionel Sambuc   int j = 0;
35*f4a2713aSLionel Sambuc   switch (i) {
36*f4a2713aSLionel Sambuc   default:
37*f4a2713aSLionel Sambuc     j = 42; break;
38*f4a2713aSLionel Sambuc   case 111:
39*f4a2713aSLionel Sambuc     j = 111; break;
40*f4a2713aSLionel Sambuc   case 0 ... 100:
41*f4a2713aSLionel Sambuc     j = 1; break;
42*f4a2713aSLionel Sambuc   case 222:
43*f4a2713aSLionel Sambuc     j = 222; break;
44*f4a2713aSLionel Sambuc   }
45*f4a2713aSLionel Sambuc   return j;
46*f4a2713aSLionel Sambuc }
47*f4a2713aSLionel Sambuc 
48*f4a2713aSLionel Sambuc 
foo4(int i)49*f4a2713aSLionel Sambuc static int foo4(int i) {
50*f4a2713aSLionel Sambuc   int j = 0;
51*f4a2713aSLionel Sambuc   switch (i) {
52*f4a2713aSLionel Sambuc   case 111:
53*f4a2713aSLionel Sambuc     j = 111; break;
54*f4a2713aSLionel Sambuc   case 0 ... 100:
55*f4a2713aSLionel Sambuc     j = 1; break;
56*f4a2713aSLionel Sambuc   case 222:
57*f4a2713aSLionel Sambuc     j = 222; break;
58*f4a2713aSLionel Sambuc   default:
59*f4a2713aSLionel Sambuc     j = 42; break;
60*f4a2713aSLionel Sambuc   case 501 ... 600:
61*f4a2713aSLionel Sambuc     j = 5; break;
62*f4a2713aSLionel Sambuc   }
63*f4a2713aSLionel Sambuc   return j;
64*f4a2713aSLionel Sambuc }
65*f4a2713aSLionel Sambuc 
66*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @foo4t()
67*f4a2713aSLionel Sambuc // CHECK: ret i32 376
68*f4a2713aSLionel Sambuc // CHECK: }
foo4t()69*f4a2713aSLionel Sambuc int foo4t() {
70*f4a2713aSLionel Sambuc   // 111 + 1 + 222 + 42 = 376
71*f4a2713aSLionel Sambuc   return foo4(111) + foo4(99) + foo4(222) + foo4(601);
72*f4a2713aSLionel Sambuc }
73*f4a2713aSLionel Sambuc 
74*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @foo5()
75*f4a2713aSLionel Sambuc // CHECK-NOT: switch
76*f4a2713aSLionel Sambuc // CHECK: }
foo5()77*f4a2713aSLionel Sambuc void foo5(){
78*f4a2713aSLionel Sambuc     switch(0){
79*f4a2713aSLionel Sambuc     default:
80*f4a2713aSLionel Sambuc         if (0) {
81*f4a2713aSLionel Sambuc 
82*f4a2713aSLionel Sambuc         }
83*f4a2713aSLionel Sambuc     }
84*f4a2713aSLionel Sambuc }
85*f4a2713aSLionel Sambuc 
86*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @foo6()
87*f4a2713aSLionel Sambuc // CHECK-NOT: switch
88*f4a2713aSLionel Sambuc // CHECK: }
foo6()89*f4a2713aSLionel Sambuc void foo6(){
90*f4a2713aSLionel Sambuc     switch(0){
91*f4a2713aSLionel Sambuc     }
92*f4a2713aSLionel Sambuc }
93*f4a2713aSLionel Sambuc 
94*f4a2713aSLionel Sambuc // CHECK-LABEL: define void @foo7()
95*f4a2713aSLionel Sambuc // CHECK-NOT: switch
96*f4a2713aSLionel Sambuc // CHECK: }
foo7()97*f4a2713aSLionel Sambuc void foo7(){
98*f4a2713aSLionel Sambuc     switch(0){
99*f4a2713aSLionel Sambuc       foo7();
100*f4a2713aSLionel Sambuc     }
101*f4a2713aSLionel Sambuc }
102*f4a2713aSLionel Sambuc 
103*f4a2713aSLionel Sambuc 
104*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @f8(
105*f4a2713aSLionel Sambuc // CHECK: ret i32 3
106*f4a2713aSLionel Sambuc // CHECK: }
f8(unsigned x)107*f4a2713aSLionel Sambuc int f8(unsigned x) {
108*f4a2713aSLionel Sambuc   switch(x) {
109*f4a2713aSLionel Sambuc   default:
110*f4a2713aSLionel Sambuc     return 3;
111*f4a2713aSLionel Sambuc   case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
112*f4a2713aSLionel Sambuc     return 0;
113*f4a2713aSLionel Sambuc   }
114*f4a2713aSLionel Sambuc }
115*f4a2713aSLionel Sambuc 
116*f4a2713aSLionel Sambuc // Ensure that default after a case range is not ignored.
117*f4a2713aSLionel Sambuc //
118*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @f9()
119*f4a2713aSLionel Sambuc // CHECK: ret i32 10
120*f4a2713aSLionel Sambuc // CHECK: }
f9_0(unsigned x)121*f4a2713aSLionel Sambuc static int f9_0(unsigned x) {
122*f4a2713aSLionel Sambuc   switch(x) {
123*f4a2713aSLionel Sambuc   case 10 ... 0xFFFFFFFF:
124*f4a2713aSLionel Sambuc     return 0;
125*f4a2713aSLionel Sambuc   default:
126*f4a2713aSLionel Sambuc     return 10;
127*f4a2713aSLionel Sambuc   }
128*f4a2713aSLionel Sambuc }
f9()129*f4a2713aSLionel Sambuc int f9() {
130*f4a2713aSLionel Sambuc   return f9_0(2);
131*f4a2713aSLionel Sambuc }
132*f4a2713aSLionel Sambuc 
133*f4a2713aSLionel Sambuc // Ensure that this doesn't compile to infinite loop in g() due to
134*f4a2713aSLionel Sambuc // miscompilation of fallthrough from default to a (tested) case
135*f4a2713aSLionel Sambuc // range.
136*f4a2713aSLionel Sambuc //
137*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @f10()
138*f4a2713aSLionel Sambuc // CHECK: ret i32 10
139*f4a2713aSLionel Sambuc // CHECK: }
f10_0(unsigned x)140*f4a2713aSLionel Sambuc static int f10_0(unsigned x) {
141*f4a2713aSLionel Sambuc   switch(x) {
142*f4a2713aSLionel Sambuc   default:
143*f4a2713aSLionel Sambuc     x += 1;
144*f4a2713aSLionel Sambuc   case 10 ... 0xFFFFFFFF:
145*f4a2713aSLionel Sambuc     return 0;
146*f4a2713aSLionel Sambuc   }
147*f4a2713aSLionel Sambuc }
148*f4a2713aSLionel Sambuc 
f10()149*f4a2713aSLionel Sambuc int f10() {
150*f4a2713aSLionel Sambuc   f10_0(1);
151*f4a2713aSLionel Sambuc   return 10;
152*f4a2713aSLionel Sambuc }
153*f4a2713aSLionel Sambuc 
154*f4a2713aSLionel Sambuc // This generated incorrect code because of poor switch chaining.
155*f4a2713aSLionel Sambuc //
156*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @f11(
157*f4a2713aSLionel Sambuc // CHECK: ret i32 3
158*f4a2713aSLionel Sambuc // CHECK: }
f11(int x)159*f4a2713aSLionel Sambuc int f11(int x) {
160*f4a2713aSLionel Sambuc   switch(x) {
161*f4a2713aSLionel Sambuc   default:
162*f4a2713aSLionel Sambuc     return 3;
163*f4a2713aSLionel Sambuc   case 10 ... 0xFFFFFFFF:
164*f4a2713aSLionel Sambuc     return 0;
165*f4a2713aSLionel Sambuc   }
166*f4a2713aSLionel Sambuc }
167*f4a2713aSLionel Sambuc 
168*f4a2713aSLionel Sambuc // This just asserted because of the way case ranges were calculated.
169*f4a2713aSLionel Sambuc //
170*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @f12(
171*f4a2713aSLionel Sambuc // CHECK: ret i32 3
172*f4a2713aSLionel Sambuc // CHECK: }
f12(int x)173*f4a2713aSLionel Sambuc int f12(int x) {
174*f4a2713aSLionel Sambuc   switch (x) {
175*f4a2713aSLionel Sambuc   default:
176*f4a2713aSLionel Sambuc     return 3;
177*f4a2713aSLionel Sambuc   case 10 ... -1:
178*f4a2713aSLionel Sambuc     return 0;
179*f4a2713aSLionel Sambuc   }
180*f4a2713aSLionel Sambuc }
181*f4a2713aSLionel Sambuc 
182*f4a2713aSLionel Sambuc // Make sure return is not constant (if empty range is skipped or miscompiled)
183*f4a2713aSLionel Sambuc //
184*f4a2713aSLionel Sambuc // CHECK-LABEL: define i32 @f13(
185*f4a2713aSLionel Sambuc // CHECK: ret i32 %
186*f4a2713aSLionel Sambuc // CHECK: }
f13(unsigned x)187*f4a2713aSLionel Sambuc int f13(unsigned x) {
188*f4a2713aSLionel Sambuc   switch(x) {
189*f4a2713aSLionel Sambuc   case 2:
190*f4a2713aSLionel Sambuc     // fallthrough empty range
191*f4a2713aSLionel Sambuc   case 10 ... 9:
192*f4a2713aSLionel Sambuc     return 10;
193*f4a2713aSLionel Sambuc   default:
194*f4a2713aSLionel Sambuc     return 0;
195*f4a2713aSLionel Sambuc   }
196*f4a2713aSLionel Sambuc }
197*f4a2713aSLionel Sambuc 
198*f4a2713aSLionel Sambuc // Don't delete a basic block that we want to introduce later references to.
199*f4a2713aSLionel Sambuc // This isn't really specific to switches, but it's easy to show with them.
200*f4a2713aSLionel Sambuc // rdar://problem/8837067
f14(int x)201*f4a2713aSLionel Sambuc int f14(int x) {
202*f4a2713aSLionel Sambuc   switch (x) {
203*f4a2713aSLionel Sambuc 
204*f4a2713aSLionel Sambuc   // case range so that the case block has no predecessors
205*f4a2713aSLionel Sambuc   case 0 ... 15:
206*f4a2713aSLionel Sambuc     // any expression which doesn't introduce a new block
207*f4a2713aSLionel Sambuc     (void) 0;
208*f4a2713aSLionel Sambuc     // kaboom
209*f4a2713aSLionel Sambuc 
210*f4a2713aSLionel Sambuc   default:
211*f4a2713aSLionel Sambuc     return x;
212*f4a2713aSLionel Sambuc   }
213*f4a2713aSLionel Sambuc }
214