1 // RUN: %clang_cc1 -triple i386-unknown-unknown -O3 %s -emit-llvm -o - | FileCheck %s
2 
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;
14   }
15   j = j + 1;
16   return j;
17 }
18 
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;
28   }
29   j = j + 1;
30   return j;
31 }
32 
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;
44   }
45   return j;
46 }
47 
48 
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;
62   }
63   return j;
64 }
65 
66 // CHECK-LABEL: define i32 @foo4t()
67 // CHECK: ret i32 376
68 // CHECK: }
69 int foo4t() {
70   // 111 + 1 + 222 + 42 = 376
71   return foo4(111) + foo4(99) + foo4(222) + foo4(601);
72 }
73 
74 // CHECK-LABEL: define void @foo5()
75 // CHECK-NOT: switch
76 // CHECK: }
77 void foo5(){
78     switch(0){
79     default:
80         if (0) {
81 
82         }
83     }
84 }
85 
86 // CHECK-LABEL: define void @foo6()
87 // CHECK-NOT: switch
88 // CHECK: }
89 void foo6(){
90     switch(0){
91     }
92 }
93 
94 // CHECK-LABEL: define void @foo7()
95 // CHECK-NOT: switch
96 // CHECK: }
97 void foo7(){
98     switch(0){
99       foo7();
100     }
101 }
102 
103 
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;
113   }
114 }
115 
116 // Ensure that default after a case range is not ignored.
117 //
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;
127   }
128 }
129 int f9() {
130   return f9_0(2);
131 }
132 
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.
136 //
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;
146   }
147 }
148 
149 int f10() {
150   f10_0(1);
151   return 10;
152 }
153 
154 // This generated incorrect code because of poor switch chaining.
155 //
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;
165   }
166 }
167 
168 // This just asserted because of the way case ranges were calculated.
169 //
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;
179   }
180 }
181 
182 // Make sure return is not constant (if empty range is skipped or miscompiled)
183 //
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;
195   }
196 }
197 
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 // rdar://problem/8837067
201 int f14(int x) {
202   switch (x) {
203 
204   // case range so that the case block has no predecessors
205   case 0 ... 15:
206     // any expression which doesn't introduce a new block
207     (void) 0;
208     // kaboom
209 
210   default:
211     return x;
212   }
213 }
214