[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / switch.c
blob7d1d1bd545017a0cb073d779b779bd7ea85fbc5c
1 // RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s
3 int foo(int i) {
4 int j = 0;
5 switch (i) {
6 case -1:
7 j = 1; break;
8 case 1 :
9 j = 2; break;
10 case 2:
11 j = 3; break;
12 default:
13 j = 42; break;
15 j = j + 1;
16 return j;
19 int foo2(int i) {
20 int j = 0;
21 switch (i) {
22 case 1 :
23 j = 2; break;
24 case 2 ... 10:
25 j = 3; break;
26 default:
27 j = 42; break;
29 j = j + 1;
30 return j;
33 int foo3(int i) {
34 int j = 0;
35 switch (i) {
36 default:
37 j = 42; break;
38 case 111:
39 j = 111; break;
40 case 0 ... 100:
41 j = 1; break;
42 case 222:
43 j = 222; break;
45 return j;
49 static int foo4(int i) {
50 int j = 0;
51 switch (i) {
52 case 111:
53 j = 111; break;
54 case 0 ... 100:
55 j = 1; break;
56 case 222:
57 j = 222; break;
58 default:
59 j = 42; break;
60 case 501 ... 600:
61 j = 5; break;
63 return j;
66 // CHECK-LABEL: define{{.*}} i32 @foo4t()
67 // CHECK: ret i32 376
68 // CHECK: }
69 int foo4t(void) {
70 // 111 + 1 + 222 + 42 = 376
71 return foo4(111) + foo4(99) + foo4(222) + foo4(601);
74 // CHECK-LABEL: define{{.*}} void @foo5()
75 // CHECK-NOT: switch
76 // CHECK: }
77 void foo5(void){
78 switch(0){
79 default:
80 if (0) {
86 // CHECK-LABEL: define{{.*}} void @foo6()
87 // CHECK-NOT: switch
88 // CHECK: }
89 void foo6(void){
90 switch(0){
94 // CHECK-LABEL: define{{.*}} void @foo7()
95 // CHECK-NOT: switch
96 // CHECK: }
97 void foo7(void){
98 switch(0){
99 foo7();
104 // CHECK-LABEL: define{{.*}} i32 @f8(
105 // CHECK: ret i32 3
106 // CHECK: }
107 int f8(unsigned x) {
108 switch(x) {
109 default:
110 return 3;
111 case 0xFFFFFFFF ... 1: // This range should be empty because x is unsigned.
112 return 0;
116 // Ensure that default after a case range is not ignored.
118 // CHECK-LABEL: define{{.*}} i32 @f9()
119 // CHECK: ret i32 10
120 // CHECK: }
121 static int f9_0(unsigned x) {
122 switch(x) {
123 case 10 ... 0xFFFFFFFF:
124 return 0;
125 default:
126 return 10;
129 int f9(void) {
130 return f9_0(2);
133 // Ensure that this doesn't compile to infinite loop in g() due to
134 // miscompilation of fallthrough from default to a (tested) case
135 // range.
137 // CHECK-LABEL: define{{.*}} i32 @f10()
138 // CHECK: ret i32 10
139 // CHECK: }
140 static int f10_0(unsigned x) {
141 switch(x) {
142 default:
143 x += 1;
144 case 10 ... 0xFFFFFFFF:
145 return 0;
149 int f10(void) {
150 f10_0(1);
151 return 10;
154 // This generated incorrect code because of poor switch chaining.
156 // CHECK-LABEL: define{{.*}} i32 @f11(
157 // CHECK: ret i32 3
158 // CHECK: }
159 int f11(int x) {
160 switch(x) {
161 default:
162 return 3;
163 case 10 ... 0xFFFFFFFF:
164 return 0;
168 // This just asserted because of the way case ranges were calculated.
170 // CHECK-LABEL: define{{.*}} i32 @f12(
171 // CHECK: ret i32 3
172 // CHECK: }
173 int f12(int x) {
174 switch (x) {
175 default:
176 return 3;
177 case 10 ... -1:
178 return 0;
182 // Make sure return is not constant (if empty range is skipped or miscompiled)
184 // CHECK-LABEL: define{{.*}} i32 @f13(
185 // CHECK: ret i32 %
186 // CHECK: }
187 int f13(unsigned x) {
188 switch(x) {
189 case 2:
190 // fallthrough empty range
191 case 10 ... 9:
192 return 10;
193 default:
194 return 0;
198 // Don't delete a basic block that we want to introduce later references to.
199 // This isn't really specific to switches, but it's easy to show with them.
200 int f14(int x) {
201 switch (x) {
203 // case range so that the case block has no predecessors
204 case 0 ... 15:
205 // any expression which doesn't introduce a new block
206 (void) 0;
207 // kaboom
209 default:
210 return x;