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