150
|
1 // RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
|
|
2
|
|
3 // PR9322 and rdar://6970405
|
|
4
|
|
5 // CHECK: @test1
|
|
6 // CHECK-NOT: switch
|
|
7 // CHECK-NOT: @dead
|
|
8 // CHECK: add nsw i32 {{.*}}, 1
|
|
9 // CHECK-NOT: switch
|
|
10 // CHECK-NOT: @dead
|
|
11 // CHECK: ret void
|
|
12 int i;
|
|
13 void dead();
|
|
14
|
|
15 void test1() {
|
|
16 switch (1)
|
|
17 case 1:
|
|
18 ++i;
|
|
19
|
|
20 switch (0)
|
|
21 case 1:
|
|
22 dead();
|
|
23 }
|
|
24
|
|
25
|
|
26 // CHECK: @test2
|
|
27 // CHECK-NOT: switch
|
|
28 // CHECK-NOT: @dead
|
|
29 // CHECK: add nsw i32 {{.*}}, 2
|
|
30 // CHECK-NOT: switch
|
|
31 // CHECK-NOT: @dead
|
|
32 // CHECK: ret void
|
|
33 void test2() {
|
|
34 switch (4) {
|
|
35 case 1:
|
|
36 dead();
|
|
37 break;
|
|
38 case 4:
|
|
39 i += 2;
|
|
40 // Fall off the end of the switch.
|
|
41 }
|
|
42 }
|
|
43
|
|
44
|
|
45 // CHECK: @test3
|
|
46 // CHECK-NOT: switch
|
|
47 // CHECK-NOT: @dead
|
|
48 // CHECK: add nsw i32 {{.*}}, 2
|
|
49 // CHECK-NOT: switch
|
|
50 // CHECK-NOT: @dead
|
|
51 // CHECK: ret void
|
|
52 void test3() {
|
|
53 switch (4) {
|
|
54 case 1:
|
|
55 dead();
|
|
56 break;
|
|
57 case 4: {
|
|
58 i += 2;
|
|
59 break;
|
|
60 }
|
|
61 }
|
|
62 }
|
|
63
|
|
64 // CHECK: @test4
|
|
65 // CHECK-NOT: switch
|
|
66 // CHECK-NOT: @dead
|
|
67 // CHECK: add nsw i32 {{.*}}, 2
|
|
68 // CHECK-NOT: switch
|
|
69 // CHECK-NOT: @dead
|
|
70 // CHECK: ret void
|
|
71 void test4() {
|
|
72 switch (4) {
|
|
73 case 1:
|
|
74 dead();
|
|
75 break;
|
|
76 default: {
|
|
77 i += 2;
|
|
78 break;
|
|
79 }
|
|
80 }
|
|
81 }
|
|
82
|
|
83 // This shouldn't crash codegen, but we don't have to optimize out the switch
|
|
84 // in this case.
|
|
85 void test5() {
|
|
86 switch (1) {
|
|
87 int x; // eliding var decl?
|
|
88 case 1:
|
|
89 x = 4;
|
|
90 i = x;
|
|
91 break;
|
|
92 }
|
|
93 }
|
|
94
|
|
95 // CHECK: @test6
|
|
96 // CHECK-NOT: switch
|
|
97 // CHECK-NOT: @dead
|
|
98 // CHECK: ret void
|
|
99 void test6() {
|
|
100 // Neither case is reachable.
|
|
101 switch (40) {
|
|
102 case 1:
|
|
103 dead();
|
|
104 break;
|
|
105 case 4: {
|
|
106 dead();
|
|
107 break;
|
|
108 }
|
|
109 }
|
|
110 }
|
|
111
|
|
112 // CHECK: @test7
|
|
113 // CHECK-NOT: switch
|
|
114 // CHECK-NOT: @dead
|
|
115 // CHECK: add nsw i32
|
|
116 // CHECK-NOT: switch
|
|
117 // CHECK-NOT: @dead
|
|
118 // CHECK: ret void
|
|
119 void test7() {
|
|
120 switch (4) {
|
|
121 case 1:
|
|
122 dead();
|
|
123 break;
|
|
124 {
|
|
125 case 4: // crazy brace scenario
|
|
126 ++i;
|
|
127 }
|
|
128 break;
|
|
129 }
|
|
130 }
|
|
131
|
|
132 // CHECK: @test8
|
|
133 // CHECK-NOT: switch
|
|
134 // CHECK-NOT: @dead
|
|
135 // CHECK: add nsw i32
|
|
136 // CHECK-NOT: switch
|
|
137 // CHECK-NOT: @dead
|
|
138 // CHECK: ret void
|
|
139 void test8() {
|
|
140 switch (4) {
|
|
141 case 1:
|
|
142 dead();
|
|
143 break;
|
|
144 case 4:
|
|
145 ++i;
|
|
146 // Fall off the end of the switch.
|
|
147 }
|
|
148 }
|
|
149
|
|
150 // CHECK: @test9
|
|
151 // CHECK-NOT: switch
|
|
152 // CHECK-NOT: @dead
|
|
153 // CHECK: add nsw i32
|
|
154 // CHECK: add nsw i32
|
|
155 // CHECK-NOT: switch
|
|
156 // CHECK-NOT: @dead
|
|
157 // CHECK: ret void
|
|
158 void test9(int i) {
|
|
159 switch (1) {
|
|
160 case 5:
|
|
161 dead();
|
|
162 case 1:
|
|
163 ++i;
|
|
164 // Fall through is fine.
|
|
165 case 4:
|
|
166 ++i;
|
|
167 break;
|
|
168 }
|
|
169 }
|
|
170
|
|
171 // CHECK: @test10
|
|
172 // CHECK-NOT: switch
|
|
173 // CHECK: ret i32
|
|
174 int test10(void) {
|
|
175 switch(8) {
|
|
176 case 8:
|
|
177 break;
|
|
178 case 4:
|
|
179 break;
|
|
180 default:
|
|
181 dead();
|
|
182 }
|
|
183
|
|
184 return 0;
|
|
185 }
|
|
186
|
|
187 // CHECK: @test11
|
|
188 // CHECK-NOT: switch
|
|
189 // CHECK: ret void
|
|
190 void test11() {
|
|
191 switch (1) {
|
|
192 case 1:
|
|
193 break;
|
|
194 case 42: ;
|
|
195 int x; // eliding var decl?
|
|
196 x = 4;
|
|
197 break;
|
|
198 }
|
|
199 }
|
|
200
|
|
201 // CHECK: @test12
|
|
202 // CHECK-NOT: switch
|
|
203 // CHECK: ret void
|
|
204 void test12() {
|
|
205 switch (1) {
|
|
206 case 2: {
|
|
207 int a; // Ok to skip this vardecl.
|
|
208 a = 42;
|
|
209 }
|
|
210 case 1:
|
|
211 break;
|
|
212 case 42: ;
|
|
213 int x; // eliding var decl?
|
|
214 x = 4;
|
|
215 break;
|
|
216 }
|
|
217 }
|
|
218
|
|
219 // Verify that case 42 only calls test14 once.
|
|
220 // CHECK: @test13
|
|
221 // CHECK: call void @test13(i32 97)
|
|
222 // CHECK-NEXT: br label %[[EPILOG2:[0-9.a-z]+]]
|
|
223 // CHECK: [[EPILOG2]]
|
|
224 // CHECK-NEXT: br label [[EPILOG:%[0-9.a-z]+]]
|
|
225 // CHECK: call void @test13(i32 42)
|
|
226 // CHECK-NEXT: br label [[EPILOG]]
|
|
227 void test13(int x) {
|
|
228 switch (x) {
|
|
229 case 42: test13(97); // fallthrough
|
|
230 case 11: break;
|
|
231 default: test13(42); break;
|
|
232 }
|
|
233 }
|
|
234
|