[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / LandingPadClauses.ll
blob75050c91bbb44ab5512e11b9c414fe488f0c1d1c
1 ; RUN: opt < %s -instcombine -S | FileCheck %s
3 @T1 = external constant i32
4 @T2 = external constant i32
5 @T3 = external constant i32
7 declare i32 @generic_personality(i32, i64, i8*, i8*)
8 declare i32 @__gxx_personality_v0(i32, i64, i8*, i8*)
9 declare i32 @__objc_personality_v0(i32, i64, i8*, i8*)
10 declare i32 @__C_specific_handler(...)
12 declare void @bar()
14 define 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
18 cont.a:
19   invoke void @bar()
20     to label %cont.b unwind label %lpad.b
21 cont.b:
22   invoke void @bar()
23     to label %cont.c unwind label %lpad.c
24 cont.c:
25   invoke void @bar()
26     to label %cont.d unwind label %lpad.d
27 cont.d:
28   invoke void @bar()
29     to label %cont.e unwind label %lpad.e
30 cont.e:
31   invoke void @bar()
32     to label %cont.f unwind label %lpad.f
33 cont.f:
34   invoke void @bar()
35     to label %cont.g unwind label %lpad.g
36 cont.g:
37   invoke void @bar()
38     to label %cont.h unwind label %lpad.h
39 cont.h:
40   invoke void @bar()
41     to label %cont.i unwind label %lpad.i
42 cont.i:
43   ret void
45 lpad.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
57 lpad.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
66 lpad.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
79 lpad.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
87 lpad.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
98 lpad.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
107 lpad.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
118 lpad.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
127 lpad.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
137 define 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
141 cont.a:
142   invoke void @bar()
143     to label %cont.b unwind label %lpad.b
144 cont.b:
145   invoke void @bar()
146     to label %cont.c unwind label %lpad.c
147 cont.c:
148   invoke void @bar()
149     to label %cont.d unwind label %lpad.d
150 cont.d:
151   ret void
153 lpad.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
162 lpad.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
170 lpad.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
178 lpad.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
188 define 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
192 cont.a:
193   invoke void @bar()
194     to label %cont.b unwind label %lpad.b
195 cont.b:
196   invoke void @bar()
197     to label %cont.c unwind label %lpad.c
198 cont.c:
199   invoke void @bar()
200     to label %cont.d unwind label %lpad.d
201 cont.d:
202   ret void
204 lpad.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
213 lpad.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
221 lpad.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
229 lpad.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
239 define 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
243 cont.a:
244   invoke void @bar()
245     to label %cont.b unwind label %lpad.b
246 cont.b:
247   invoke void @bar()
248     to label %cont.c unwind label %lpad.c
249 cont.c:
250   invoke void @bar()
251     to label %cont.d unwind label %lpad.d
252 cont.d:
253   ret void
255 lpad.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
264 lpad.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
272 lpad.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
280 lpad.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