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