[ARM] Rewrite how VCMP are lowered, using a single node
[llvm-core.git] / test / Verifier / invalid-eh.ll
blob63485d28627e77698ee0fd17a2655ef63e969680
1 ; UNSUPPORTED: system-windows
3 ; RUN: sed -e s/.T1:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s
4 ; RUN: sed -e s/.T2:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s
5 ; RUN: sed -e s/.T3:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s
6 ; RUN: sed -e s/.T4:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK4 %s
7 ; RUN: sed -e s/.T5:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK5 %s
8 ; RUN: sed -e s/.T6:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK6 %s
9 ; RUN: sed -e s/.T7:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK7 %s
10 ; RUN: sed -e s/.T8:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK8 %s
11 ; RUN: sed -e s/.T9:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK9 %s
12 ; RUN: sed -e s/.T10:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK10 %s
13 ; RUN: sed -e s/.T11:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK11 %s
14 ; RUN: sed -e s/.T12:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK12 %s
15 ; RUN: sed -e s/.T13:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK13 %s
16 ; RUN: sed -e s/.T14:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK14 %s
17 ; RUN: sed -e s/.T15:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK15 %s
18 ; RUN: sed -e s/.T16:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK16 %s
19 ; RUN: sed -e s/.T17:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK17 %s
20 ; RUN: sed -e s/.T18:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK18 %s
21 ; RUN: sed -e s/.T19:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK19 %s
22 ; RUN: sed -e s/.T20:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK20 %s
23 ; RUN: sed -e s/.T21:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK21 %s
24 ; RUN: sed -e s/.T22:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK22 %s
25 ; RUN: sed -e s/.T23:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK23 %s
26 ; RUN: sed -e s/.T24:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK24 %s
27 ; RUN: sed -e s/.T25:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK25 %s
28 ; RUN: sed -e s/.T26:// %s | not opt -verify -disable-output 2>&1 | FileCheck --check-prefix=CHECK26 %s
30 declare void @g()
32 ;T1: define void @f() {
33 ;T1:   entry:
34 ;T1:     catchret from undef to label %next
35 ;T1:     ; CHECK1: CatchReturnInst needs to be provided a CatchPad
36 ;T1:   next:
37 ;T1:     unreachable
38 ;T1: }
40 ;T2: define void @f() {
41 ;T2:   entry:
42 ;T2:     %x = cleanuppad within none []
43 ;T2:     ; catchret's first operand's operator must be catchpad
44 ;T2:     catchret from %x to label %entry
45 ;T2:     ; CHECK2: CatchReturnInst needs to be provided a CatchPad
46 ;T2: }
48 ;T3: define void @f() {
49 ;T3:   entry:
50 ;T3:     cleanupret from undef unwind label %next
51 ;T3:     ; CHECK3: CleanupReturnInst needs to be provided a CleanupPad
52 ;T3:   next:
53 ;T3:     unreachable
54 ;T3: }
56 ;T4: define void @f() {
57 ;T4:   entry:
58 ;T4:     %cs = catchswitch within none [label %next] unwind to caller
59 ;T4:   next:
60 ;T4:     %x = catchpad within %cs []
61 ;T4:     ; cleanupret first operand's operator must be cleanuppad
62 ;T4:     cleanupret from %x unwind to caller
63 ;T4:     ; CHECK4: CleanupReturnInst needs to be provided a CleanupPad
64 ;T4: }
66 ;T5: define void @f() personality void ()* @g {
67 ;T5:   entry:
68 ;T5:     ret void
69 ;T5:   switch:
70 ;T5:     %cs = catchswitch within none [label %catch] unwind to caller
71 ;T5:   catch:
72 ;T5:     catchpad within %cs []
73 ;T5:     unreachable
74 ;T5:   bogus:
75 ;T5:     cleanuppad within %cs []
76 ;T5:     ; CHECK5: CleanupPadInst has an invalid parent
77 ;T5:     unreachable
78 ;T5: }
80 ;T6: define void @f() personality void ()* @g {
81 ;T6:   entry:
82 ;T6:     ret void
83 ;T6:   switch1:
84 ;T6:     %cs1 = catchswitch within none [label %catch1] unwind label %catch2
85 ;T6:     ; CHECK6: Block containg CatchPadInst must be jumped to only by its catchswitch
86 ;T6:   catch1:
87 ;T6:     catchpad within %cs1 []
88 ;T6:     unreachable
89 ;T6:   switch2:
90 ;T6:     %cs2 = catchswitch within none [label %catch2] unwind to caller
91 ;T6:   catch2:
92 ;T6:     catchpad within %cs2 []
93 ;T6:     unreachable
94 ;T6: }
96 ;T7: define void @f() personality void ()* @g {
97 ;T7:   entry:
98 ;T7:     ret void
99 ;T7:   switch1:
100 ;T7:     %cs1 = catchswitch within none [label %catch1] unwind to caller
101 ;T7:   catch1:
102 ;T7:     catchpad within %cs1 []
103 ;T7:     unreachable
104 ;T7:   switch2:
105 ;T7:     %cs2 = catchswitch within %cs1 [label %catch2] unwind to caller
106 ;T7:     ; CHECK7: CatchSwitchInst has an invalid parent
107 ;T7:   catch2:
108 ;T7:     catchpad within %cs2 []
109 ;T7:     unreachable
110 ;T7: }
112 ;T8: define void @f() personality void ()* @g {
113 ;T8:   entry:
114 ;T8:     ret void
115 ;T8:   switch1:
116 ;T8:     %cs1 = catchswitch within none [ label %switch1 ] unwind to caller
117 ;T8:     ; CHECK8: CatchSwitchInst handlers must be catchpads
118 ;T8: }
120 ;T9: define void @f() personality void ()* @g {
121 ;T9:   entry:
122 ;T9:     ret void
123 ;T9:   cleanup:
124 ;T9:     %cp = cleanuppad within none []
125 ;T9:     invoke void @g() [ "funclet"(token %cp) ]
126 ;T9:       to label %exit unwind label %cleanup
127 ;T9:       ; CHECK9: EH pad cannot handle exceptions raised within it
128 ;T9:       ; CHECK9-NEXT: %cp = cleanuppad within none []
129 ;T9:       ; CHECK9-NEXT: invoke void @g() [ "funclet"(token %cp) ]
130 ;T9:   exit:
131 ;T9:     ret void
132 ;T9: }
134 ;T10: define void @f() personality void ()* @g {
135 ;T10:   entry:
136 ;T10:     ret void
137 ;T10:   cleanup1:
138 ;T10:     %cp1 = cleanuppad within none []
139 ;T10:     unreachable
140 ;T10:   switch:
141 ;T10:     %cs = catchswitch within %cp1 [label %catch] unwind to caller
142 ;T10:   catch:
143 ;T10:     %catchp1 = catchpad within %cs [i32 1]
144 ;T10:     unreachable
145 ;T10:   cleanup2:
146 ;T10:     %cp2 = cleanuppad within %catchp1 []
147 ;T10:     unreachable
148 ;T10:   cleanup3:
149 ;T10:     %cp3 = cleanuppad within %cp2 []
150 ;T10:     cleanupret from %cp3 unwind label %switch
151 ;T10:       ; CHECK10: EH pad cannot handle exceptions raised within it
152 ;T10:       ; CHECK10-NEXT: %cs = catchswitch within %cp1 [label %catch] unwind to caller
153 ;T10:       ; CHECK10-NEXT: cleanupret from %cp3 unwind label %switch
154 ;T10: }
156 ;T11: define void @f() personality void ()* @g {
157 ;T11:   entry:
158 ;T11:     ret void
159 ;T11:   cleanup1:
160 ;T11:     %cp1 = cleanuppad within none []
161 ;T11:     unreachable
162 ;T11:   cleanup2:
163 ;T11:     %cp2 = cleanuppad within %cp1 []
164 ;T11:     unreachable
165 ;T11:   switch:
166 ;T11:     %cs = catchswitch within none [label %catch] unwind label %cleanup2
167 ;T11:     ; CHECK11: A single unwind edge may only enter one EH pad
168 ;T11:     ; CHECK11-NEXT: %cs = catchswitch within none [label %catch] unwind label %cleanup2
169 ;T11:   catch:
170 ;T11:     catchpad within %cs [i32 1]
171 ;T11:     unreachable
172 ;T11: }
174 ;T12: define void @f() personality void ()* @g {
175 ;T12:   entry:
176 ;T12:     ret void
177 ;T12:   cleanup:
178 ;T12:     %cp = cleanuppad within none []
179 ;T12:     cleanupret from %cp unwind label %switch
180 ;T12:     ; CHECK12: A cleanupret must exit its cleanup
181 ;T12:     ; CHECK12-NEXT: cleanupret from %cp unwind label %switch
182 ;T12:   switch:
183 ;T12:     %cs = catchswitch within %cp [label %catch] unwind to caller
184 ;T12:   catch:
185 ;T12:     catchpad within %cs [i32 1]
186 ;T12:     unreachable
187 ;T12: }
189 ;T13: define void @f() personality void ()* @g {
190 ;T13:   entry:
191 ;T13:     ret void
192 ;T13:   switch:
193 ;T13:     %cs = catchswitch within none [label %catch] unwind label %switch
194 ;T13:     ; CHECK13: EH pad cannot handle exceptions raised within it
195 ;T13:     ; CHECK13-NEXT:  %cs = catchswitch within none [label %catch] unwind label %switch
196 ;T13:   catch:
197 ;T13:     catchpad within %cs [i32 0]
198 ;T13:     unreachable
199 ;T13: }
201 ;T14: define void @f() personality void ()* @g {
202 ;T14:   entry:
203 ;T14:     ret void
204 ;T14:   cleanup:
205 ;T14:     %cp = cleanuppad within none []
206 ;T14:     unreachable
207 ;T14:   left:
208 ;T14:     cleanupret from %cp unwind label %switch
209 ;T14:   right:
210 ;T14:     cleanupret from %cp unwind to caller
211 ;T14:     ; CHECK14: Unwind edges out of a funclet pad must have the same unwind dest
212 ;T14:     ; CHECK14-NEXT: %cp = cleanuppad within none []
213 ;T14:     ; CHECK14-NEXT: cleanupret from %cp unwind label %switch
214 ;T14:     ; CHECK14-NEXT: cleanupret from %cp unwind to caller
215 ;T14:   switch:
216 ;T14:     %cs = catchswitch within none [label %catch] unwind to caller
217 ;T14:   catch:
218 ;T14:     catchpad within %cs [i32 1]
219 ;T14:     unreachable
220 ;T14: }
222 ;T15: define void @f() personality void ()* @g {
223 ;T15:   entry:
224 ;T15:     ret void
225 ;T15:   switch:
226 ;T15:     %cs = catchswitch within none [label %catch] unwind to caller
227 ;T15:   catch:
228 ;T15:     %catch.pad = catchpad within %cs [i32 1]
229 ;T15:     invoke void @g() [ "funclet"(token %catch.pad) ]
230 ;T15:       to label %unreachable unwind label %target1
231 ;T15:   unreachable:
232 ;T15:     unreachable
233 ;T15:   target1:
234 ;T15:     cleanuppad within none []
235 ;T15:     unreachable
236 ;T15:   target2:
237 ;T15:     cleanuppad within none []
238 ;T15:     unreachable
239 ;T15:   nested.1:
240 ;T15:     %nested.pad.1 = cleanuppad within %catch.pad []
241 ;T15:     unreachable
242 ;T15:   nested.2:
243 ;T15:     %nested.pad.2 = cleanuppad within %nested.pad.1 []
244 ;T15:     cleanupret from %nested.pad.2 unwind label %target2
245 ;T15:     ; CHECK15: Unwind edges out of a funclet pad must have the same unwind dest
246 ;T15:     ; CHECK15-NEXT: %catch.pad = catchpad within %cs [i32 1]
247 ;T15:     ; CHECK15-NEXT: cleanupret from %nested.pad.2 unwind label %target2
248 ;T15:     ; CHECK15-NEXT: invoke void @g() [ "funclet"(token %catch.pad) ]
249 ;T15:     ; CHECK15-NEXT:   to label %unreachable unwind label %target1
250 ;T15: }
252 ;T16: define void @f() personality void ()* @g {
253 ;T16:   entry:
254 ;T16:     ret void
255 ;T16:   switch:
256 ;T16:     %cs = catchswitch within none [label %catch] unwind to caller
257 ;T16:   catch:
258 ;T16:     %catch.pad = catchpad within %cs [i32 1]
259 ;T16:     invoke void @g() [ "funclet"(token %catch.pad) ]
260 ;T16:       to label %unreachable unwind label %target1
261 ;T16:     ; CHECK16: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
262 ;T16:     ; CHECK16-NEXT:   %catch.pad = catchpad within %cs [i32 1]
263 ;T16:     ; CHECK16-NEXT:  invoke void @g() [ "funclet"(token %catch.pad) ]
264 ;T16:     ; CHECK16-NEXT:          to label %unreachable unwind label %target1
265 ;T16:     ; CHECK16-NEXT:  %cs = catchswitch within none [label %catch] unwind to caller
266 ;T16:   unreachable:
267 ;T16:     unreachable
268 ;T16:   target1:
269 ;T16:     cleanuppad within none []
270 ;T16:     unreachable
271 ;T16: }
273 ;T17: define void @f() personality void ()* @g {
274 ;T17:   entry:
275 ;T17:     ret void
276 ;T17:   switch:
277 ;T17:     %cs = catchswitch within none [label %catch] unwind label %target1
278 ;T17:   catch:
279 ;T17:     %catch.pad = catchpad within %cs [i32 1]
280 ;T17:     invoke void @g() [ "funclet"(token %catch.pad) ]
281 ;T17:       to label %unreachable unwind label %target2
282 ;T17:     ; CHECK17: Unwind edges out of a catch must have the same unwind dest as the parent catchswitch
283 ;T17:     ; CHECK17-NEXT:  %catch.pad = catchpad within %cs [i32 1]
284 ;T17:     ; CHECK17-NEXT:  invoke void @g() [ "funclet"(token %catch.pad) ]
285 ;T17:     ; CHECK17-NEXT:          to label %unreachable unwind label %target2
286 ;T17:     ; CHECK17-NEXT:  %cs = catchswitch within none [label %catch] unwind label %target1
287 ;T17:   unreachable:
288 ;T17:     unreachable
289 ;T17:   target1:
290 ;T17:     cleanuppad within none []
291 ;T17:     unreachable
292 ;T17:   target2:
293 ;T17:     cleanuppad within none []
294 ;T17:     unreachable
295 ;T17: }
297 ;T18: define void @f() personality void ()* @g {
298 ;T18:   entry:
299 ;T18:     invoke void @g()
300 ;T18:       to label %invoke.cont unwind label %left
301 ;T18:   invoke.cont:
302 ;T18:     invoke void @g()
303 ;T18:       to label %unreachable unwind label %right
304 ;T18:   left:
305 ;T18:     %cp.left = cleanuppad within none []
306 ;T18:     invoke void @g() [ "funclet"(token %cp.left) ]
307 ;T18:       to label %unreachable unwind label %right
308 ;T18:   right:
309 ;T18:     %cp.right = cleanuppad within none []
310 ;T18:     invoke void @g() [ "funclet"(token %cp.right) ]
311 ;T18:       to label %unreachable unwind label %left
312 ;T18:     ; CHECK18: EH pads can't handle each other's exceptions
313 ;T18:     ; CHECK18-NEXT: %cp.left = cleanuppad within none []
314 ;T18:     ; CHECK18-NEXT:  invoke void @g() [ "funclet"(token %cp.left) ]
315 ;T18:     ; CHECK18-NEXT:          to label %unreachable unwind label %right
316 ;T18:     ; CHECK18-NEXT:  %cp.right = cleanuppad within none []
317 ;T18:     ; CHECK18-NEXT:  invoke void @g() [ "funclet"(token %cp.right) ]
318 ;T18:     ; CHECK18-NEXT:          to label %unreachable unwind label %left
319 ;T18:   unreachable:
320 ;T18:     unreachable
321 ;T18: }
323 ;T19: define void @f() personality void ()* @g {
324 ;T19:   entry:
325 ;T19:     ret void
326 ;T19:   red:
327 ;T19:     %redpad = cleanuppad within none []
328 ;T19:     unreachable
329 ;T19:   red.inner:
330 ;T19:     %innerpad = cleanuppad within %redpad []
331 ;T19:     invoke void @g() [ "funclet"(token %innerpad) ]
332 ;T19:       to label %unreachable unwind label %green
333 ;T19:   green:
334 ;T19:     %greenswitch = catchswitch within none [label %catch] unwind label %blue
335 ;T19:   catch:
336 ;T19:     catchpad within %greenswitch [i32 42]
337 ;T19:     unreachable
338 ;T19:   blue:
339 ;T19:     %bluepad = cleanuppad within none []
340 ;T19:     cleanupret from %bluepad unwind label %red
341 ;T19:     ; CHECK19: EH pads can't handle each other's exceptions
342 ;T19:     ; CHECK19-NEXT: %redpad = cleanuppad within none []
343 ;T19:     ; CHECK19-NEXT: invoke void @g() [ "funclet"(token %innerpad) ]
344 ;T19:     ; CHECK19-NEXT:         to label %unreachable unwind label %green
345 ;T19:     ; CHECK19-NEXT: %greenswitch = catchswitch within none [label %catch] unwind label %blue
346 ;T19:     ; CHECK19-NEXT: %bluepad = cleanuppad within none []
347 ;T19:     ; CHECK19-NEXT: cleanupret from %bluepad unwind label %red
348 ;T19:   unreachable:
349 ;T19:     unreachable
350 ;T19: }
352 ;T20: define void @f() personality void ()* @g {
353 ;T20:   entry:
354 ;T20:     ret void
355 ;T20:   switch:
356 ;T20:     %cs = catchswitch within none [label %catch] unwind label %catch
357 ;T20:     ; CHECK20: Catchswitch cannot unwind to one of its catchpads
358 ;T20:     ; CHECK20-NEXT: %cs = catchswitch within none [label %catch] unwind label %catch
359 ;T20:     ; CHECK20-NEXT: %cp = catchpad within %cs [i32 4]
360 ;T20:   catch:
361 ;T20:     %cp = catchpad within %cs [i32 4]
362 ;T20:     unreachable
363 ;T20: }
365 ;T21: define void @f() personality void ()* @g {
366 ;T21:   entry:
367 ;T21:     ret void
368 ;T21:   switch:
369 ;T21:     %cs = catchswitch within none [label %catch1] unwind label %catch2
370 ;T21:     ; CHECK21: Catchswitch cannot unwind to one of its catchpads
371 ;T21:     ; CHECK21-NEXT: %cs = catchswitch within none [label %catch1] unwind label %catch2
372 ;T21:     ; CHECK21-NEXT: %cp2 = catchpad within %cs [i32 2]
373 ;T21:   catch1:
374 ;T21:     %cp1 = catchpad within %cs [i32 1]
375 ;T21:     unreachable
376 ;T21:   catch2:
377 ;T21:     %cp2 = catchpad within %cs [i32 2]
378 ;T21:     unreachable
379 ;T21: }
381 ;T22: define void @f() personality void ()* @g {
382 ;T22:   invoke void @g()
383 ;T22:           to label %merge unwind label %cleanup
384 ;T22:
385 ;T22: cleanup:
386 ;T22:   %outer = cleanuppad within none []
387 ;T22:   invoke void @g() [ "funclet"(token %outer) ]
388 ;T22:           to label %merge unwind label %merge
389 ;T22:   ; CHECK22: The unwind destination does not have an exception handling instruction!
390 ;T22:   ; CHECK22:   invoke void @g() [ "funclet"(token %outer) ]
391 ;T22:   ; CHECK22:           to label %merge unwind label %merge
392 ;T22:
393 ;T22: merge:
394 ;T22:   unreachable
395 ;T22: }
397 ;T23: define void @f() personality void ()* @g {
398 ;T23:   invoke void @g()
399 ;T23:           to label %exit unwind label %pad
400 ;T23:
401 ;T23: pad:
402 ;T23:   %outer = catchpad within %outer []
403 ;T23:   ; CHECK23: CatchPadInst needs to be directly nested in a CatchSwitchInst.
404 ;T23:   ; CHECK23:   %outer = catchpad within %outer []
405 ;T23:   unreachable
406 ;T23:
407 ;T23: exit:
408 ;T23:   unreachable
409 ;T23: }
411 ;T24: define void @f() personality void ()* @g {
412 ;T24:   invoke void @g()
413 ;T24:           to label %exit unwind label %pad
414 ;T24:   ; CHECK24: A single unwind edge may only enter one EH pad
415 ;T24:   ; CHECK24:   invoke void @g()
416 ;T24:   ; CHECK24:           to label %exit unwind label %pad
417 ;T24:
418 ;T24: pad:
419 ;T24:   %outer = cleanuppad within %outer []
420 ;T24:   ; CHECK24: FuncletPadInst must not be nested within itself
421 ;T24:   ; CHECK24:   %outer = cleanuppad within %outer []
422 ;T24:   unreachable
423 ;T24:
424 ;T24: exit:
425 ;T24:   unreachable
426 ;T24: }
428 ;T25: define void @f() personality void ()* @g {
429 ;T25: entry:
430 ;T25:   unreachable
431 ;T25:
432 ;T25: catch.dispatch:
433 ;T25:   %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
434 ;T25:   ; CHECK25: EH pad jumps through a cycle of pads
435 ;T25:   ; CHECK25:   %cs = catchswitch within %cp2 [label %catch] unwind label %ehcleanup
436 ;T25:
437 ;T25: catch:
438 ;T25:   %cp2 = catchpad within %cs [i8* null, i32 64, i8* null]
439 ;T25:   unreachable
440 ;T25:
441 ;T25: ehcleanup:
442 ;T25:   %cp3 = cleanuppad within none []
443 ;T25:   cleanupret from %cp3 unwind to caller
444 ;T25: }
446 ;T26: define void @f() personality void ()* @g {
447 ;T26: entry:
448 ;T26:   ret void
449 ;T26:
450 ;T26: ehcleanup:
451 ;T26:   cleanuppad within none []
452 ;T26:   cleanupret from none unwind label %ehcleanup
453 ;T26:   ; CHECK26: A cleanupret must exit its cleanup
454 ;T26:   ; CHECK26:   cleanupret from none unwind label %ehcleanup
455 ;T26:   ; CHECK26: CleanupReturnInst needs to be provided a CleanupPad
456 ;T26:   ; CHECK26:   cleanupret from none unwind label %ehcleanup
457 ;T26:   ; CHECK26: token none
458 ;T26: }