1; RUN: opt < %s -instcombine -S | FileCheck %s
2
3@T1 = external constant i32
4@T2 = external constant i32
5@T3 = external constant i32
6
7declare i32 @generic_personality(i32, i64, i8*, i8*)
8declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
9declare i32 @__objc_personality_v0(i32, i64, i8*, i8*)
10declare i32 @__C_specific_handler(...)
11
12declare void @bar()
13
14define void @foo_generic() personality i32 (i32, i64, i8*, i8*)* @generic_personality {
15; CHECK-LABEL: @foo_generic(
16  invoke void @bar()
17    to label %cont.a unwind label %lpad.a
18cont.a:
19  invoke void @bar()
20    to label %cont.b unwind label %lpad.b
21cont.b:
22  invoke void @bar()
23    to label %cont.c unwind label %lpad.c
24cont.c:
25  invoke void @bar()
26    to label %cont.d unwind label %lpad.d
27cont.d:
28  invoke void @bar()
29    to label %cont.e unwind label %lpad.e
30cont.e:
31  invoke void @bar()
32    to label %cont.f unwind label %lpad.f
33cont.f:
34  invoke void @bar()
35    to label %cont.g unwind label %lpad.g
36cont.g:
37  invoke void @bar()
38    to label %cont.h unwind label %lpad.h
39cont.h:
40  invoke void @bar()
41    to label %cont.i unwind label %lpad.i
42cont.i:
43  ret void
44
45lpad.a:
46  %a = landingpad { i8*, i32 }
47          catch i32* @T1
48          catch i32* @T2
49          catch i32* @T1
50          catch i32* @T2
51  unreachable
52; CHECK: %a = landingpad
53; CHECK-NEXT: @T1
54; CHECK-NEXT: @T2
55; CHECK-NEXT: unreachable
56
57lpad.b:
58  %b = landingpad { i8*, i32 }
59          filter [0 x i32*] zeroinitializer
60          catch i32* @T1
61  unreachable
62; CHECK: %b = landingpad
63; CHECK-NEXT: filter
64; CHECK-NEXT: unreachable
65
66lpad.c:
67  %c = landingpad { i8*, i32 }
68          catch i32* @T1
69          filter [1 x i32*] [i32* @T1]
70          catch i32* @T2
71  unreachable
72; Caught types should not be removed from filters
73; CHECK: %c = landingpad
74; CHECK-NEXT: catch i32* @T1
75; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
76; CHECK-NEXT: catch i32* @T2
77; CHECK-NEXT: unreachable
78
79lpad.d:
80  %d = landingpad { i8*, i32 }
81          filter [3 x i32*] zeroinitializer
82  unreachable
83; CHECK: %d = landingpad
84; CHECK-NEXT: filter [1 x i32*] zeroinitializer
85; CHECK-NEXT: unreachable
86
87lpad.e:
88  %e = landingpad { i8*, i32 }
89          catch i32* @T1
90          filter [3 x i32*] [i32* @T1, i32* @T2, i32* @T2]
91  unreachable
92; Caught types should not be removed from filters
93; CHECK: %e = landingpad
94; CHECK-NEXT: catch i32* @T1
95; CHECK-NEXT: filter [2 x i32*] [i32* @T1, i32* @T2]
96; CHECK-NEXT: unreachable
97
98lpad.f:
99  %f = landingpad { i8*, i32 }
100          filter [2 x i32*] [i32* @T2, i32* @T1]
101          filter [1 x i32*] [i32* @T1]
102  unreachable
103; CHECK: %f = landingpad
104; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
105; CHECK-NEXT: unreachable
106
107lpad.g:
108  %g = landingpad { i8*, i32 }
109          filter [1 x i32*] [i32* @T1]
110          catch i32* @T3
111          filter [2 x i32*] [i32* @T2, i32* @T1]
112  unreachable
113; CHECK: %g = landingpad
114; CHECK-NEXT: filter [1 x i32*] [i32* @T1]
115; CHECK-NEXT: catch i32* @T3
116; CHECK-NEXT: unreachable
117
118lpad.h:
119  %h = landingpad { i8*, i32 }
120          filter [2 x i32*] [i32* @T1, i32* null]
121          filter [1 x i32*] zeroinitializer
122  unreachable
123; CHECK: %h = landingpad
124; CHECK-NEXT: filter [1 x i32*] zeroinitializer
125; CHECK-NEXT: unreachable
126
127lpad.i:
128  %i = landingpad { i8*, i32 }
129          cleanup
130          filter [0 x i32*] zeroinitializer
131  unreachable
132; CHECK: %i = landingpad
133; CHECK-NEXT: filter
134; CHECK-NEXT: unreachable
135}
136
137define void @foo_cxx() personality i32 (i32, i64, i8*, i8*)* @__gxx_personality_v0 {
138; CHECK-LABEL: @foo_cxx(
139  invoke void @bar()
140    to label %cont.a unwind label %lpad.a
141cont.a:
142  invoke void @bar()
143    to label %cont.b unwind label %lpad.b
144cont.b:
145  invoke void @bar()
146    to label %cont.c unwind label %lpad.c
147cont.c:
148  invoke void @bar()
149    to label %cont.d unwind label %lpad.d
150cont.d:
151  ret void
152
153lpad.a:
154  %a = landingpad { i8*, i32 }
155          catch i32* null
156          catch i32* @T1
157  unreachable
158; CHECK: %a = landingpad
159; CHECK-NEXT: null
160; CHECK-NEXT: unreachable
161
162lpad.b:
163  %b = landingpad { i8*, i32 }
164          filter [1 x i32*] zeroinitializer
165  unreachable
166; CHECK: %b = landingpad
167; CHECK-NEXT: cleanup
168; CHECK-NEXT: unreachable
169
170lpad.c:
171  %c = landingpad { i8*, i32 }
172          filter [2 x i32*] [i32* @T1, i32* null]
173  unreachable
174; CHECK: %c = landingpad
175; CHECK-NEXT: cleanup
176; CHECK-NEXT: unreachable
177
178lpad.d:
179  %d = landingpad { i8*, i32 }
180          cleanup
181          catch i32* null
182  unreachable
183; CHECK: %d = landingpad
184; CHECK-NEXT: null
185; CHECK-NEXT: unreachable
186}
187
188define void @foo_objc() personality i32 (i32, i64, i8*, i8*)* @__objc_personality_v0 {
189; CHECK-LABEL: @foo_objc(
190  invoke void @bar()
191    to label %cont.a unwind label %lpad.a
192cont.a:
193  invoke void @bar()
194    to label %cont.b unwind label %lpad.b
195cont.b:
196  invoke void @bar()
197    to label %cont.c unwind label %lpad.c
198cont.c:
199  invoke void @bar()
200    to label %cont.d unwind label %lpad.d
201cont.d:
202  ret void
203
204lpad.a:
205  %a = landingpad { i8*, i32 }
206          catch i32* null
207          catch i32* @T1
208  unreachable
209; CHECK: %a = landingpad
210; CHECK-NEXT: null
211; CHECK-NEXT: unreachable
212
213lpad.b:
214  %b = landingpad { i8*, i32 }
215          filter [1 x i32*] zeroinitializer
216  unreachable
217; CHECK: %b = landingpad
218; CHECK-NEXT: cleanup
219; CHECK-NEXT: unreachable
220
221lpad.c:
222  %c = landingpad { i8*, i32 }
223          filter [2 x i32*] [i32* @T1, i32* null]
224  unreachable
225; CHECK: %c = landingpad
226; CHECK-NEXT: cleanup
227; CHECK-NEXT: unreachable
228
229lpad.d:
230  %d = landingpad { i8*, i32 }
231          cleanup
232          catch i32* null
233  unreachable
234; CHECK: %d = landingpad
235; CHECK-NEXT: null
236; CHECK-NEXT: unreachable
237}
238
239define void @foo_seh() personality i32 (...)* @__C_specific_handler {
240; CHECK-LABEL: @foo_seh(
241  invoke void @bar()
242    to label %cont.a unwind label %lpad.a
243cont.a:
244  invoke void @bar()
245    to label %cont.b unwind label %lpad.b
246cont.b:
247  invoke void @bar()
248    to label %cont.c unwind label %lpad.c
249cont.c:
250  invoke void @bar()
251    to label %cont.d unwind label %lpad.d
252cont.d:
253  ret void
254
255lpad.a:
256  %a = landingpad { i8*, i32 }
257          catch i32* null
258          catch i32* @T1
259  unreachable
260; CHECK: %a = landingpad
261; CHECK-NEXT: null
262; CHECK-NEXT: unreachable
263
264lpad.b:
265  %b = landingpad { i8*, i32 }
266          filter [1 x i32*] zeroinitializer
267  unreachable
268; CHECK: %b = landingpad
269; CHECK-NEXT: cleanup
270; CHECK-NEXT: unreachable
271
272lpad.c:
273  %c = landingpad { i8*, i32 }
274          filter [2 x i32*] [i32* @T1, i32* null]
275  unreachable
276; CHECK: %c = landingpad
277; CHECK-NEXT: cleanup
278; CHECK-NEXT: unreachable
279
280lpad.d:
281  %d = landingpad { i8*, i32 }
282          cleanup
283          catch i32* null
284  unreachable
285; CHECK: %d = landingpad
286; CHECK-NEXT: null
287; CHECK-NEXT: unreachable
288}
289