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
12int i;
13void dead();
14
15void 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
33void 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
52void 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
71void 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.
85void 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
99void 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
119void 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
139void 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
158void 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
174int 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
190void 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
204void 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]]
227void test13(int x) {
228  switch (x) {
229    case 42: test13(97);  // fallthrough
230    case 11: break;
231    default: test13(42); break;
232  }
233}
234
235