[test] Pre-commit llvm.experimental.memset.pattern tests prior to MemoryLocation...
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / X86 / merge-compatible-invokes-of-landingpad.ll
blob95114abb4ef5fe1be771793b61c9d552d1e093d6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals all --version 5
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s
3 ; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s
5 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
6 target triple = "x86_64-unknown-linux-gnu"
8 ; Simple test, nothing interesting happens here.
9 define void @t0_noop() personality ptr @__gxx_personality_v0 {
10 ; CHECK-LABEL: define void @t0_noop() personality ptr @__gxx_personality_v0 {
11 ; CHECK-NEXT:  [[ENTRY:.*:]]
12 ; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()
13 ; CHECK-NEXT:    br i1 [[C]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
14 ; CHECK:       [[IF_THEN]]:
15 ; CHECK-NEXT:    invoke void @simple_throw()
16 ; CHECK-NEXT:            to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD:.*]]
17 ; CHECK:       [[INVOKE_CONT]]:
18 ; CHECK-NEXT:    unreachable
19 ; CHECK:       [[LPAD]]:
20 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
21 ; CHECK-NEXT:            cleanup
22 ; CHECK-NEXT:    call void @destructor()
23 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
24 ; CHECK:       [[IF_END]]:
25 ; CHECK-NEXT:    call void @sideeffect()
26 ; CHECK-NEXT:    ret void
28 entry:
29   %c = call i1 @cond()
30   br i1 %c, label %if.then, label %if.end
32 if.then:
33   invoke void @simple_throw() to label %invoke.cont unwind label %lpad
35 invoke.cont:
36   unreachable
38 lpad:
39   %eh = landingpad { ptr, i32 } cleanup
40   call void @destructor()
41   resume { ptr, i32 } %eh
43 if.end:
44   call void @sideeffect()
45   ret void
48 ; More interesting test, here we can merge the invokes.
49 define void @t1_mergeable_invoke() personality ptr @__gxx_personality_v0 {
50 ; CHECK-LABEL: define void @t1_mergeable_invoke() personality ptr @__gxx_personality_v0 {
51 ; CHECK-NEXT:  [[ENTRY:.*:]]
52 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
53 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
54 ; CHECK:       [[LPAD:.*]]:
55 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
56 ; CHECK-NEXT:            cleanup
57 ; CHECK-NEXT:    call void @destructor()
58 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
59 ; CHECK:       [[IF_ELSE]]:
60 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
61 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
62 ; CHECK:       [[IF_THEN1_INVOKE]]:
63 ; CHECK-NEXT:    invoke void @simple_throw()
64 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
65 ; CHECK:       [[IF_THEN1_CONT]]:
66 ; CHECK-NEXT:    unreachable
67 ; CHECK:       [[IF_END]]:
68 ; CHECK-NEXT:    call void @sideeffect()
69 ; CHECK-NEXT:    ret void
71 entry:
72   %c0 = call i1 @cond()
73   br i1 %c0, label %if.then0, label %if.else
75 if.then0:
76   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
78 invoke.cont0:
79   unreachable
81 lpad:
82   %eh = landingpad { ptr, i32 } cleanup
83   call void @destructor()
84   resume { ptr, i32 } %eh
86 if.else:
87   %c1 = call i1 @cond()
88   br i1 %c1, label %if.then1, label %if.end
90 if.then1:
91   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
93 invoke.cont2:
94   unreachable
96 if.end:
97   call void @sideeffect()
98   ret void
101 ; normal block is shared, but it is unreachable, so we are fine.
102 define void @t2_shared_normal_dest() personality ptr @__gxx_personality_v0 {
103 ; CHECK-LABEL: define void @t2_shared_normal_dest() personality ptr @__gxx_personality_v0 {
104 ; CHECK-NEXT:  [[ENTRY:.*:]]
105 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
106 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
107 ; CHECK:       [[LPAD:.*]]:
108 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
109 ; CHECK-NEXT:            cleanup
110 ; CHECK-NEXT:    call void @destructor()
111 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
112 ; CHECK:       [[IF_ELSE]]:
113 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
114 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
115 ; CHECK:       [[IF_THEN1_INVOKE]]:
116 ; CHECK-NEXT:    invoke void @simple_throw()
117 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
118 ; CHECK:       [[IF_THEN1_CONT]]:
119 ; CHECK-NEXT:    unreachable
120 ; CHECK:       [[IF_END]]:
121 ; CHECK-NEXT:    call void @sideeffect()
122 ; CHECK-NEXT:    ret void
124 entry:
125   %c0 = call i1 @cond()
126   br i1 %c0, label %if.then0, label %if.else
128 if.then0:
129   invoke void @simple_throw() to label %invoke.cont unwind label %lpad
131 invoke.cont:
132   unreachable
134 lpad:
135   %eh = landingpad { ptr, i32 } cleanup
136   call void @destructor()
137   resume { ptr, i32 } %eh
139 if.else:
140   %c1 = call i1 @cond()
141   br i1 %c1, label %if.then1, label %if.end
143 if.then1:
144   invoke void @simple_throw() to label %invoke.cont unwind label %lpad
146 if.end:
147   call void @sideeffect()
148   ret void
151 ; shared normal destination is not unreachable.
152 define void @t3_shared_identical_normal_dest() personality ptr @__gxx_personality_v0 {
153 ; CHECK-LABEL: define void @t3_shared_identical_normal_dest() personality ptr @__gxx_personality_v0 {
154 ; CHECK-NEXT:  [[ENTRY:.*:]]
155 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
156 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
157 ; CHECK:       [[INVOKE_CONT:.*]]:
158 ; CHECK-NEXT:    call void @sideeffect()
159 ; CHECK-NEXT:    unreachable
160 ; CHECK:       [[LPAD:.*]]:
161 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
162 ; CHECK-NEXT:            cleanup
163 ; CHECK-NEXT:    call void @destructor()
164 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
165 ; CHECK:       [[IF_ELSE]]:
166 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
167 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
168 ; CHECK:       [[IF_THEN1_INVOKE]]:
169 ; CHECK-NEXT:    invoke void @maybe_throw()
170 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
171 ; CHECK:       [[IF_END]]:
172 ; CHECK-NEXT:    call void @sideeffect()
173 ; CHECK-NEXT:    ret void
175 entry:
176   %c0 = call i1 @cond()
177   br i1 %c0, label %if.then0, label %if.else
179 if.then0:
180   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
182 invoke.cont:
183   call void @sideeffect()
184   unreachable
186 lpad:
187   %eh = landingpad { ptr, i32 } cleanup
188   call void @destructor()
189   resume { ptr, i32 } %eh
191 if.else:
192   %c1 = call i1 @cond()
193   br i1 %c1, label %if.then1, label %if.end
195 if.then1:
196   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
198 if.end:
199   call void @sideeffect()
200   ret void
203 ; normal destinations are not unreachable and not shared and can not be merged.
204 define void @t4_normal_dests() personality ptr @__gxx_personality_v0 {
205 ; CHECK-LABEL: define void @t4_normal_dests() personality ptr @__gxx_personality_v0 {
206 ; CHECK-NEXT:  [[ENTRY:.*:]]
207 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
208 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
209 ; CHECK:       [[IF_THEN0]]:
210 ; CHECK-NEXT:    invoke void @maybe_throw()
211 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
212 ; CHECK:       [[INVOKE_CONT0]]:
213 ; CHECK-NEXT:    call void @sideeffect()
214 ; CHECK-NEXT:    unreachable
215 ; CHECK:       [[LPAD]]:
216 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
217 ; CHECK-NEXT:            cleanup
218 ; CHECK-NEXT:    call void @destructor()
219 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
220 ; CHECK:       [[IF_ELSE]]:
221 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
222 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
223 ; CHECK:       [[IF_THEN1]]:
224 ; CHECK-NEXT:    invoke void @maybe_throw()
225 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
226 ; CHECK:       [[INVOKE_CONT2]]:
227 ; CHECK-NEXT:    call void @another_sideeffect()
228 ; CHECK-NEXT:    unreachable
229 ; CHECK:       [[IF_END]]:
230 ; CHECK-NEXT:    call void @sideeffect()
231 ; CHECK-NEXT:    ret void
233 entry:
234   %c0 = call i1 @cond()
235   br i1 %c0, label %if.then0, label %if.else
237 if.then0:
238   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
240 invoke.cont0:
241   call void @sideeffect()
242   unreachable
244 lpad:
245   %eh = landingpad { ptr, i32 } cleanup
246   call void @destructor()
247   resume { ptr, i32 } %eh
249 if.else:
250   %c1 = call i1 @cond()
251   br i1 %c1, label %if.then1, label %if.end
253 if.then1:
254   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
256 invoke.cont2:
257   call void @another_sideeffect()
258   unreachable
260 if.end:
261   call void @sideeffect()
262   ret void
265 ; Invokes lead to different landing pads.
266 define void @t5_different_landingpads() personality ptr @__gxx_personality_v0 {
267 ; CHECK-LABEL: define void @t5_different_landingpads() personality ptr @__gxx_personality_v0 {
268 ; CHECK-NEXT:  [[ENTRY:.*:]]
269 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
270 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
271 ; CHECK:       [[IF_THEN0]]:
272 ; CHECK-NEXT:    invoke void @simple_throw()
273 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD0:.*]]
274 ; CHECK:       [[INVOKE_CONT0]]:
275 ; CHECK-NEXT:    unreachable
276 ; CHECK:       [[COMMON_RESUME:.*]]:
277 ; CHECK-NEXT:    [[COMMON_RESUME_OP:%.*]] = phi { ptr, i32 } [ [[EH0:%.*]], %[[LPAD0]] ], [ [[EH1:%.*]], %[[LPAD1:.*]] ]
278 ; CHECK-NEXT:    resume { ptr, i32 } [[COMMON_RESUME_OP]]
279 ; CHECK:       [[LPAD0]]:
280 ; CHECK-NEXT:    [[EH0]] = landingpad { ptr, i32 }
281 ; CHECK-NEXT:            cleanup
282 ; CHECK-NEXT:    call void @destructor()
283 ; CHECK-NEXT:    br label %[[COMMON_RESUME]]
284 ; CHECK:       [[IF_ELSE]]:
285 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
286 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
287 ; CHECK:       [[IF_THEN1]]:
288 ; CHECK-NEXT:    invoke void @simple_throw()
289 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD1]]
290 ; CHECK:       [[INVOKE_CONT2]]:
291 ; CHECK-NEXT:    unreachable
292 ; CHECK:       [[LPAD1]]:
293 ; CHECK-NEXT:    [[EH1]] = landingpad { ptr, i32 }
294 ; CHECK-NEXT:            cleanup
295 ; CHECK-NEXT:    call void @another_destructor()
296 ; CHECK-NEXT:    br label %[[COMMON_RESUME]]
297 ; CHECK:       [[IF_END]]:
298 ; CHECK-NEXT:    call void @sideeffect()
299 ; CHECK-NEXT:    ret void
301 entry:
302   %c0 = call i1 @cond()
303   br i1 %c0, label %if.then0, label %if.else
305 if.then0:
306   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad0
308 invoke.cont0:
309   unreachable
311 lpad0:
312   %eh0 = landingpad { ptr, i32 } cleanup
313   call void @destructor()
314   resume { ptr, i32 } %eh0
316 if.else:
317   %c1 = call i1 @cond()
318   br i1 %c1, label %if.then1, label %if.end
320 if.then1:
321   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad1
323 invoke.cont2:
324   unreachable
326 lpad1:
327   %eh1 = landingpad { ptr, i32 } cleanup
328   call void @another_destructor()
329   resume { ptr, i32 } %eh1
331 if.end:
332   call void @sideeffect()
333   ret void
336 ; The invoked functions are different
337 define void @t6_different_invokes() personality ptr @__gxx_personality_v0 {
338 ; CHECK-LABEL: define void @t6_different_invokes() personality ptr @__gxx_personality_v0 {
339 ; CHECK-NEXT:  [[ENTRY:.*:]]
340 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
341 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
342 ; CHECK:       [[IF_THEN0]]:
343 ; CHECK-NEXT:    invoke void @simple_throw()
344 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
345 ; CHECK:       [[INVOKE_CONT0]]:
346 ; CHECK-NEXT:    unreachable
347 ; CHECK:       [[LPAD]]:
348 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
349 ; CHECK-NEXT:            cleanup
350 ; CHECK-NEXT:    call void @destructor()
351 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
352 ; CHECK:       [[IF_ELSE]]:
353 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
354 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
355 ; CHECK:       [[IF_THEN1]]:
356 ; CHECK-NEXT:    invoke void @another_simple_throw()
357 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
358 ; CHECK:       [[INVOKE_CONT2]]:
359 ; CHECK-NEXT:    unreachable
360 ; CHECK:       [[IF_END]]:
361 ; CHECK-NEXT:    call void @sideeffect()
362 ; CHECK-NEXT:    ret void
364 entry:
365   %c0 = call i1 @cond()
366   br i1 %c0, label %if.then0, label %if.else
368 if.then0:
369   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
371 invoke.cont0:
372   unreachable
374 lpad:
375   %eh = landingpad { ptr, i32 } cleanup
376   call void @destructor()
377   resume { ptr, i32 } %eh
379 if.else:
380   %c1 = call i1 @cond()
381   br i1 %c1, label %if.then1, label %if.end
383 if.then1:
384   invoke void @another_simple_throw() to label %invoke.cont2 unwind label %lpad
386 invoke.cont2:
387   unreachable
389 if.end:
390   call void @sideeffect()
391   ret void
394 ; Merging of this invoke is disallowed
395 define void @t7_nomerge0() personality ptr @__gxx_personality_v0 {
396 ; CHECK-LABEL: define void @t7_nomerge0() personality ptr @__gxx_personality_v0 {
397 ; CHECK-NEXT:  [[ENTRY:.*:]]
398 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
399 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
400 ; CHECK:       [[IF_THEN0]]:
401 ; CHECK-NEXT:    invoke void @simple_throw()
402 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
403 ; CHECK:       [[INVOKE_CONT0]]:
404 ; CHECK-NEXT:    unreachable
405 ; CHECK:       [[LPAD]]:
406 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
407 ; CHECK-NEXT:            cleanup
408 ; CHECK-NEXT:    call void @destructor()
409 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
410 ; CHECK:       [[IF_ELSE]]:
411 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
412 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
413 ; CHECK:       [[IF_THEN1]]:
414 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1:[0-9]+]]
415 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
416 ; CHECK:       [[INVOKE_CONT2]]:
417 ; CHECK-NEXT:    unreachable
418 ; CHECK:       [[IF_END]]:
419 ; CHECK-NEXT:    call void @sideeffect()
420 ; CHECK-NEXT:    ret void
422 entry:
423   %c0 = call i1 @cond()
424   br i1 %c0, label %if.then0, label %if.else
426 if.then0:
427   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
429 invoke.cont0:
430   unreachable
432 lpad:
433   %eh = landingpad { ptr, i32 } cleanup
434   call void @destructor()
435   resume { ptr, i32 } %eh
437 if.else:
438   %c1 = call i1 @cond()
439   br i1 %c1, label %if.then1, label %if.end
441 if.then1:
442   invoke void @simple_throw() nomerge to label %invoke.cont2 unwind label %lpad
444 invoke.cont2:
445   unreachable
447 if.end:
448   call void @sideeffect()
449   ret void
451 define void @t8_nomerge1() personality ptr @__gxx_personality_v0 {
452 ; CHECK-LABEL: define void @t8_nomerge1() personality ptr @__gxx_personality_v0 {
453 ; CHECK-NEXT:  [[ENTRY:.*:]]
454 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
455 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
456 ; CHECK:       [[IF_THEN0]]:
457 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1]]
458 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
459 ; CHECK:       [[INVOKE_CONT0]]:
460 ; CHECK-NEXT:    unreachable
461 ; CHECK:       [[LPAD]]:
462 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
463 ; CHECK-NEXT:            cleanup
464 ; CHECK-NEXT:    call void @destructor()
465 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
466 ; CHECK:       [[IF_ELSE]]:
467 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
468 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
469 ; CHECK:       [[IF_THEN1]]:
470 ; CHECK-NEXT:    invoke void @simple_throw()
471 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
472 ; CHECK:       [[INVOKE_CONT2]]:
473 ; CHECK-NEXT:    unreachable
474 ; CHECK:       [[IF_END]]:
475 ; CHECK-NEXT:    call void @sideeffect()
476 ; CHECK-NEXT:    ret void
478 entry:
479   %c0 = call i1 @cond()
480   br i1 %c0, label %if.then0, label %if.else
482 if.then0:
483   invoke void @simple_throw() nomerge to label %invoke.cont0 unwind label %lpad
485 invoke.cont0:
486   unreachable
488 lpad:
489   %eh = landingpad { ptr, i32 } cleanup
490   call void @destructor()
491   resume { ptr, i32 } %eh
493 if.else:
494   %c1 = call i1 @cond()
495   br i1 %c1, label %if.then1, label %if.end
497 if.then1:
498   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
500 invoke.cont2:
501   unreachable
503 if.end:
504   call void @sideeffect()
505   ret void
507 define void @t9_nomerge2() personality ptr @__gxx_personality_v0 {
508 ; CHECK-LABEL: define void @t9_nomerge2() personality ptr @__gxx_personality_v0 {
509 ; CHECK-NEXT:  [[ENTRY:.*:]]
510 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
511 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
512 ; CHECK:       [[IF_THEN0]]:
513 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1]]
514 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
515 ; CHECK:       [[INVOKE_CONT0]]:
516 ; CHECK-NEXT:    unreachable
517 ; CHECK:       [[LPAD]]:
518 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
519 ; CHECK-NEXT:            cleanup
520 ; CHECK-NEXT:    call void @destructor()
521 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
522 ; CHECK:       [[IF_ELSE]]:
523 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
524 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
525 ; CHECK:       [[IF_THEN1]]:
526 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1]]
527 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
528 ; CHECK:       [[INVOKE_CONT2]]:
529 ; CHECK-NEXT:    unreachable
530 ; CHECK:       [[IF_END]]:
531 ; CHECK-NEXT:    call void @sideeffect()
532 ; CHECK-NEXT:    ret void
534 entry:
535   %c0 = call i1 @cond()
536   br i1 %c0, label %if.then0, label %if.else
538 if.then0:
539   invoke void @simple_throw() nomerge to label %invoke.cont0 unwind label %lpad
541 invoke.cont0:
542   unreachable
544 lpad:
545   %eh = landingpad { ptr, i32 } cleanup
546   call void @destructor()
547   resume { ptr, i32 } %eh
549 if.else:
550   %c1 = call i1 @cond()
551   br i1 %c1, label %if.then1, label %if.end
553 if.then1:
554   invoke void @simple_throw() nomerge to label %invoke.cont2 unwind label %lpad
556 invoke.cont2:
557   unreachable
559 if.end:
560   call void @sideeffect()
561   ret void
564 ; Just don't deal with inlineasm.
565 define void @t10_inlineasm() personality ptr @__gxx_personality_v0 {
566 ; CHECK-LABEL: define void @t10_inlineasm() personality ptr @__gxx_personality_v0 {
567 ; CHECK-NEXT:  [[ENTRY:.*:]]
568 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
569 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
570 ; CHECK:       [[IF_THEN0]]:
571 ; CHECK-NEXT:    invoke void asm sideeffect "something bad", ""()
572 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
573 ; CHECK:       [[INVOKE_CONT0]]:
574 ; CHECK-NEXT:    unreachable
575 ; CHECK:       [[LPAD]]:
576 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
577 ; CHECK-NEXT:            cleanup
578 ; CHECK-NEXT:    call void @destructor()
579 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
580 ; CHECK:       [[IF_ELSE]]:
581 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
582 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
583 ; CHECK:       [[IF_THEN1]]:
584 ; CHECK-NEXT:    invoke void asm sideeffect "something bad", ""()
585 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
586 ; CHECK:       [[INVOKE_CONT2]]:
587 ; CHECK-NEXT:    unreachable
588 ; CHECK:       [[IF_END]]:
589 ; CHECK-NEXT:    call void @sideeffect()
590 ; CHECK-NEXT:    ret void
592 entry:
593   %c0 = call i1 @cond()
594   br i1 %c0, label %if.then0, label %if.else
596 if.then0:
597   invoke void asm sideeffect "something bad", ""() to label %invoke.cont0 unwind label %lpad
599 invoke.cont0:
600   unreachable
602 lpad:
603   %eh = landingpad { ptr, i32 } cleanup
604   call void @destructor()
605   resume { ptr, i32 } %eh
607 if.else:
608   %c1 = call i1 @cond()
609   br i1 %c1, label %if.then1, label %if.end
611 if.then1:
612   invoke void asm sideeffect "something bad", ""() to label %invoke.cont2 unwind label %lpad
614 invoke.cont2:
615   unreachable
617 if.end:
618   call void @sideeffect()
619   ret void
622 ; landingpad has PHI nodes, and the incoming values are incompatible.
623 define void @t11_phi_in_landingpad_incompatible_incoming_values() personality ptr @__gxx_personality_v0 {
624 ; CHECK-LABEL: define void @t11_phi_in_landingpad_incompatible_incoming_values() personality ptr @__gxx_personality_v0 {
625 ; CHECK-NEXT:  [[ENTRY:.*:]]
626 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
627 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
628 ; CHECK:       [[IF_THEN0]]:
629 ; CHECK-NEXT:    invoke void @simple_throw()
630 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
631 ; CHECK:       [[INVOKE_CONT0]]:
632 ; CHECK-NEXT:    unreachable
633 ; CHECK:       [[LPAD]]:
634 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, %[[IF_THEN0]] ], [ 1, %[[IF_THEN1:.*]] ]
635 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
636 ; CHECK-NEXT:            cleanup
637 ; CHECK-NEXT:    call void @consume(i32 [[PHI]])
638 ; CHECK-NEXT:    call void @destructor()
639 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
640 ; CHECK:       [[IF_ELSE]]:
641 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
642 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1]], label %[[IF_END:.*]]
643 ; CHECK:       [[IF_THEN1]]:
644 ; CHECK-NEXT:    invoke void @simple_throw()
645 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
646 ; CHECK:       [[INVOKE_CONT2]]:
647 ; CHECK-NEXT:    unreachable
648 ; CHECK:       [[IF_END]]:
649 ; CHECK-NEXT:    call void @sideeffect()
650 ; CHECK-NEXT:    ret void
652 entry:
653   %c0 = call i1 @cond()
654   br i1 %c0, label %if.then0, label %if.else
656 if.then0:
657   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
659 invoke.cont0:
660   unreachable
662 lpad:
663   %phi = phi i32 [ 0, %if.then0 ], [ 1, %if.then1 ]
664   %eh = landingpad { ptr, i32 } cleanup
665   call void @consume(i32 %phi)
666   call void @destructor()
667   resume { ptr, i32 } %eh
669 if.else:
670   %c1 = call i1 @cond()
671   br i1 %c1, label %if.then1, label %if.end
673 if.then1:
674   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
676 invoke.cont2:
677   unreachable
679 if.end:
680   call void @sideeffect()
681   ret void
684 ; It is okay for the invoke to take arguments
685 define void @t12_arguments_are_fine() personality ptr @__gxx_personality_v0 {
686 ; CHECK-LABEL: define void @t12_arguments_are_fine() personality ptr @__gxx_personality_v0 {
687 ; CHECK-NEXT:  [[ENTRY:.*:]]
688 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
689 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
690 ; CHECK:       [[LPAD:.*]]:
691 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
692 ; CHECK-NEXT:            cleanup
693 ; CHECK-NEXT:    call void @destructor()
694 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
695 ; CHECK:       [[IF_ELSE]]:
696 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
697 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
698 ; CHECK:       [[IF_THEN1_INVOKE]]:
699 ; CHECK-NEXT:    invoke void @simple_throw_taking_argument(i32 42)
700 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
701 ; CHECK:       [[IF_THEN1_CONT]]:
702 ; CHECK-NEXT:    unreachable
703 ; CHECK:       [[IF_END]]:
704 ; CHECK-NEXT:    call void @sideeffect()
705 ; CHECK-NEXT:    ret void
707 entry:
708   %c0 = call i1 @cond()
709   br i1 %c0, label %if.then0, label %if.else
711 if.then0:
712   invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont0 unwind label %lpad
714 invoke.cont0:
715   unreachable
717 lpad:
718   %eh = landingpad { ptr, i32 } cleanup
719   call void @destructor()
720   resume { ptr, i32 } %eh
722 if.else:
723   %c1 = call i1 @cond()
724   br i1 %c1, label %if.then1, label %if.end
726 if.then1:
727   invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont2 unwind label %lpad
729 invoke.cont2:
730   unreachable
732 if.end:
733   call void @sideeffect()
734   ret void
737 ; It is okay for the invoke to take different arguments
738 define void @t13_different_arguments_are_fine() personality ptr @__gxx_personality_v0 {
739 ; CHECK-LABEL: define void @t13_different_arguments_are_fine() personality ptr @__gxx_personality_v0 {
740 ; CHECK-NEXT:  [[ENTRY:.*]]:
741 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
742 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
743 ; CHECK:       [[LPAD:.*]]:
744 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
745 ; CHECK-NEXT:            cleanup
746 ; CHECK-NEXT:    call void @destructor()
747 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
748 ; CHECK:       [[IF_ELSE]]:
749 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
750 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
751 ; CHECK:       [[IF_THEN1_INVOKE]]:
752 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 42, %[[IF_ELSE]] ], [ 0, %[[ENTRY]] ]
753 ; CHECK-NEXT:    invoke void @simple_throw_taking_argument(i32 [[TMP0]])
754 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
755 ; CHECK:       [[IF_THEN1_CONT]]:
756 ; CHECK-NEXT:    unreachable
757 ; CHECK:       [[IF_END]]:
758 ; CHECK-NEXT:    call void @sideeffect()
759 ; CHECK-NEXT:    ret void
761 entry:
762   %c0 = call i1 @cond()
763   br i1 %c0, label %if.then0, label %if.else
765 if.then0:
766   invoke void @simple_throw_taking_argument(i32 0) to label %invoke.cont0 unwind label %lpad
768 invoke.cont0:
769   unreachable
771 lpad:
772   %eh = landingpad { ptr, i32 } cleanup
773   call void @destructor()
774   resume { ptr, i32 } %eh
776 if.else:
777   %c1 = call i1 @cond()
778   br i1 %c1, label %if.then1, label %if.end
780 if.then1:
781   invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont2 unwind label %lpad
783 invoke.cont2:
784   unreachable
786 if.end:
787   call void @sideeffect()
788   ret void
791 ; There can be more than two invokes in a set
792 define void @t14_three_invokes() personality ptr @__gxx_personality_v0 {
793 ; CHECK-LABEL: define void @t14_three_invokes() personality ptr @__gxx_personality_v0 {
794 ; CHECK-NEXT:  [[ENTRY:.*:]]
795 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
796 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN2_INVOKE:.*]], label %[[IF_ELSE0:.*]]
797 ; CHECK:       [[LPAD:.*]]:
798 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
799 ; CHECK-NEXT:            cleanup
800 ; CHECK-NEXT:    call void @destructor()
801 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
802 ; CHECK:       [[IF_ELSE0]]:
803 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
804 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN2_INVOKE]], label %[[IF_ELSE1:.*]]
805 ; CHECK:       [[IF_ELSE1]]:
806 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
807 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2_INVOKE]], label %[[IF_END:.*]]
808 ; CHECK:       [[IF_THEN2_INVOKE]]:
809 ; CHECK-NEXT:    invoke void @simple_throw()
810 ; CHECK-NEXT:            to label %[[IF_THEN2_CONT:.*]] unwind label %[[LPAD]]
811 ; CHECK:       [[IF_THEN2_CONT]]:
812 ; CHECK-NEXT:    unreachable
813 ; CHECK:       [[IF_END]]:
814 ; CHECK-NEXT:    call void @sideeffect()
815 ; CHECK-NEXT:    ret void
817 entry:
818   %c0 = call i1 @cond()
819   br i1 %c0, label %if.then0, label %if.else0
821 if.then0:
822   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
824 invoke.cont0:
825   unreachable
827 lpad:
828   %eh = landingpad { ptr, i32 } cleanup
829   call void @destructor()
830   resume { ptr, i32 } %eh
832 if.else0:
833   %c1 = call i1 @cond()
834   br i1 %c1, label %if.then1, label %if.else1
836 if.then1:
837   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
839 invoke.cont2:
840   unreachable
842 if.else1:
843   %c2 = call i1 @cond()
844   br i1 %c2, label %if.then2, label %if.end
846 if.then2:
847   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
849 invoke.cont3:
850   unreachable
852 if.end:
853   call void @sideeffect()
854   ret void
857 ; If not all invokes of landingpad are compatible then we still merge compatible ones.
858 define void @t15_three_invokes_only_two_compatible() personality ptr @__gxx_personality_v0 {
859 ; CHECK-LABEL: define void @t15_three_invokes_only_two_compatible() personality ptr @__gxx_personality_v0 {
860 ; CHECK-NEXT:  [[ENTRY:.*:]]
861 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
862 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE0:.*]]
863 ; CHECK:       [[LPAD:.*]]:
864 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
865 ; CHECK-NEXT:            cleanup
866 ; CHECK-NEXT:    call void @destructor()
867 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
868 ; CHECK:       [[IF_ELSE0]]:
869 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
870 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_ELSE1:.*]]
871 ; CHECK:       [[IF_THEN1_INVOKE]]:
872 ; CHECK-NEXT:    invoke void @simple_throw()
873 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
874 ; CHECK:       [[IF_THEN1_CONT]]:
875 ; CHECK-NEXT:    unreachable
876 ; CHECK:       [[IF_ELSE1]]:
877 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
878 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2:.*]], label %[[IF_END:.*]]
879 ; CHECK:       [[IF_THEN2]]:
880 ; CHECK-NEXT:    invoke void @another_simple_throw()
881 ; CHECK-NEXT:            to label %[[INVOKE_CONT3:.*]] unwind label %[[LPAD]]
882 ; CHECK:       [[INVOKE_CONT3]]:
883 ; CHECK-NEXT:    unreachable
884 ; CHECK:       [[IF_END]]:
885 ; CHECK-NEXT:    call void @sideeffect()
886 ; CHECK-NEXT:    ret void
888 entry:
889   %c0 = call i1 @cond()
890   br i1 %c0, label %if.then0, label %if.else0
892 if.then0:
893   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
895 invoke.cont0:
896   unreachable
898 lpad:
899   %eh = landingpad { ptr, i32 } cleanup
900   call void @destructor()
901   resume { ptr, i32 } %eh
903 if.else0:
904   %c1 = call i1 @cond()
905   br i1 %c1, label %if.then1, label %if.else1
907 if.then1:
908   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
910 invoke.cont2:
911   unreachable
913 if.else1:
914   %c2 = call i1 @cond()
915   br i1 %c2, label %if.then2, label %if.end
917 if.then2:
918   invoke void @another_simple_throw() to label %invoke.cont3 unwind label %lpad
920 invoke.cont3:
921   unreachable
923 if.end:
924   call void @sideeffect()
925   ret void
928 ; We succeed in merging invokes into two sets
929 define void @t16_four_invokes_forming_two_sets() personality ptr @__gxx_personality_v0 {
930 ; CHECK-LABEL: define void @t16_four_invokes_forming_two_sets() personality ptr @__gxx_personality_v0 {
931 ; CHECK-NEXT:  [[ENTRY:.*:]]
932 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
933 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE0:.*]]
934 ; CHECK:       [[LPAD:.*]]:
935 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
936 ; CHECK-NEXT:            cleanup
937 ; CHECK-NEXT:    call void @destructor()
938 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
939 ; CHECK:       [[IF_ELSE0]]:
940 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
941 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_ELSE1:.*]]
942 ; CHECK:       [[IF_THEN1_INVOKE]]:
943 ; CHECK-NEXT:    invoke void @simple_throw()
944 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
945 ; CHECK:       [[IF_THEN1_CONT]]:
946 ; CHECK-NEXT:    unreachable
947 ; CHECK:       [[IF_ELSE1]]:
948 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
949 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN3_INVOKE:.*]], label %[[IF_ELSE2:.*]]
950 ; CHECK:       [[IF_ELSE2]]:
951 ; CHECK-NEXT:    [[C3:%.*]] = call i1 @cond()
952 ; CHECK-NEXT:    br i1 [[C3]], label %[[IF_THEN3_INVOKE]], label %[[IF_END:.*]]
953 ; CHECK:       [[IF_THEN3_INVOKE]]:
954 ; CHECK-NEXT:    invoke void @another_simple_throw()
955 ; CHECK-NEXT:            to label %[[IF_THEN3_CONT:.*]] unwind label %[[LPAD]]
956 ; CHECK:       [[IF_THEN3_CONT]]:
957 ; CHECK-NEXT:    unreachable
958 ; CHECK:       [[IF_END]]:
959 ; CHECK-NEXT:    call void @sideeffect()
960 ; CHECK-NEXT:    ret void
962 entry:
963   %c0 = call i1 @cond()
964   br i1 %c0, label %if.then0, label %if.else0
966 if.then0:
967   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
969 invoke.cont0:
970   unreachable
972 lpad:
973   %eh = landingpad { ptr, i32 } cleanup
974   call void @destructor()
975   resume { ptr, i32 } %eh
977 if.else0:
978   %c1 = call i1 @cond()
979   br i1 %c1, label %if.then1, label %if.else1
981 if.then1:
982   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
984 invoke.cont2:
985   unreachable
987 if.else1:
988   %c2 = call i1 @cond()
989   br i1 %c2, label %if.then2, label %if.else2
991 if.then2:
992   invoke void @another_simple_throw() to label %invoke.cont3 unwind label %lpad
994 invoke.cont3:
995   unreachable
997 if.else2:
998   %c3 = call i1 @cond()
999   br i1 %c3, label %if.then3, label %if.end
1001 if.then3:
1002   invoke void @another_simple_throw() to label %invoke.cont4 unwind label %lpad
1004 invoke.cont4:
1005   unreachable
1007 if.end:
1008   call void @sideeffect()
1009   ret void
1012 define void @t17_mismatched_attrs_okay_merge() personality ptr @__gxx_personality_v0 {
1013 ; CHECK-LABEL: define void @t17_mismatched_attrs_okay_merge() personality ptr @__gxx_personality_v0 {
1014 ; CHECK-NEXT:  [[ENTRY:.*:]]
1015 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1016 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1017 ; CHECK:       [[LPAD:.*]]:
1018 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1019 ; CHECK-NEXT:            cleanup
1020 ; CHECK-NEXT:    call void @destructor()
1021 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1022 ; CHECK:       [[IF_ELSE]]:
1023 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1024 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1025 ; CHECK:       [[IF_THEN1_INVOKE]]:
1026 ; CHECK-NEXT:    invoke void @simple_throw()
1027 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1028 ; CHECK:       [[IF_THEN1_CONT]]:
1029 ; CHECK-NEXT:    unreachable
1030 ; CHECK:       [[IF_END]]:
1031 ; CHECK-NEXT:    call void @sideeffect()
1032 ; CHECK-NEXT:    ret void
1034 entry:
1035   %c0 = call i1 @cond()
1036   br i1 %c0, label %if.then0, label %if.else
1038 if.then0:
1039   invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1041 invoke.cont0:
1042   unreachable
1044 lpad:
1045   %eh = landingpad { ptr, i32 } cleanup
1046   call void @destructor()
1047   resume { ptr, i32 } %eh
1049 if.else:
1050   %c1 = call i1 @cond()
1051   br i1 %c1, label %if.then1, label %if.end
1053 if.then1:
1054   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1056 invoke.cont2:
1057   unreachable
1059 if.end:
1060   call void @sideeffect()
1061   ret void
1064 define void @t17_mismatched_attrs_okay_merge_intersect() personality ptr @__gxx_personality_v0 {
1065 ; CHECK-LABEL: define void @t17_mismatched_attrs_okay_merge_intersect() personality ptr @__gxx_personality_v0 {
1066 ; CHECK-NEXT:  [[ENTRY:.*:]]
1067 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1068 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1069 ; CHECK:       [[LPAD:.*]]:
1070 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1071 ; CHECK-NEXT:            cleanup
1072 ; CHECK-NEXT:    call void @destructor()
1073 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1074 ; CHECK:       [[IF_ELSE]]:
1075 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1076 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1077 ; CHECK:       [[IF_THEN1_INVOKE]]:
1078 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR2:[0-9]+]]
1079 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1080 ; CHECK:       [[IF_THEN1_CONT]]:
1081 ; CHECK-NEXT:    unreachable
1082 ; CHECK:       [[IF_END]]:
1083 ; CHECK-NEXT:    call void @sideeffect()
1084 ; CHECK-NEXT:    ret void
1086 entry:
1087   %c0 = call i1 @cond()
1088   br i1 %c0, label %if.then0, label %if.else
1090 if.then0:
1091   invoke void @simple_throw() readnone cold to label %invoke.cont0 unwind label %lpad
1093 invoke.cont0:
1094   unreachable
1096 lpad:
1097   %eh = landingpad { ptr, i32 } cleanup
1098   call void @destructor()
1099   resume { ptr, i32 } %eh
1101 if.else:
1102   %c1 = call i1 @cond()
1103   br i1 %c1, label %if.then1, label %if.end
1105 if.then1:
1106   invoke void @simple_throw() readnone to label %invoke.cont2 unwind label %lpad
1108 invoke.cont2:
1109   unreachable
1111 if.end:
1112   call void @sideeffect()
1113   ret void
1116 define void @t17_mismatched_attrs_okay_merge_intersect2() personality ptr @__gxx_personality_v0 {
1117 ; CHECK-LABEL: define void @t17_mismatched_attrs_okay_merge_intersect2() personality ptr @__gxx_personality_v0 {
1118 ; CHECK-NEXT:  [[ENTRY:.*:]]
1119 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1120 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1121 ; CHECK:       [[LPAD:.*]]:
1122 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1123 ; CHECK-NEXT:            cleanup
1124 ; CHECK-NEXT:    call void @destructor()
1125 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1126 ; CHECK:       [[IF_ELSE]]:
1127 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1128 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1129 ; CHECK:       [[IF_THEN1_INVOKE]]:
1130 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR2]]
1131 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1132 ; CHECK:       [[IF_THEN1_CONT]]:
1133 ; CHECK-NEXT:    unreachable
1134 ; CHECK:       [[IF_END]]:
1135 ; CHECK-NEXT:    call void @sideeffect()
1136 ; CHECK-NEXT:    ret void
1138 entry:
1139   %c0 = call i1 @cond()
1140   br i1 %c0, label %if.then0, label %if.else
1142 if.then0:
1143   invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1145 invoke.cont0:
1146   unreachable
1148 lpad:
1149   %eh = landingpad { ptr, i32 } cleanup
1150   call void @destructor()
1151   resume { ptr, i32 } %eh
1153 if.else:
1154   %c1 = call i1 @cond()
1155   br i1 %c1, label %if.then1, label %if.end
1157 if.then1:
1158   invoke void @simple_throw() readnone cold to label %invoke.cont2 unwind label %lpad
1160 invoke.cont2:
1161   unreachable
1163 if.end:
1164   call void @sideeffect()
1165   ret void
1169 define void @t17_mismatched_attrs_prevent_merge() personality ptr @__gxx_personality_v0 {
1170 ; CHECK-LABEL: define void @t17_mismatched_attrs_prevent_merge() personality ptr @__gxx_personality_v0 {
1171 ; CHECK-NEXT:  [[ENTRY:.*:]]
1172 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1173 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
1174 ; CHECK:       [[IF_THEN0]]:
1175 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR3:[0-9]+]]
1176 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
1177 ; CHECK:       [[INVOKE_CONT0]]:
1178 ; CHECK-NEXT:    unreachable
1179 ; CHECK:       [[LPAD]]:
1180 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1181 ; CHECK-NEXT:            cleanup
1182 ; CHECK-NEXT:    call void @destructor()
1183 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1184 ; CHECK:       [[IF_ELSE]]:
1185 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1186 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
1187 ; CHECK:       [[IF_THEN1]]:
1188 ; CHECK-NEXT:    invoke void @simple_throw()
1189 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
1190 ; CHECK:       [[INVOKE_CONT2]]:
1191 ; CHECK-NEXT:    unreachable
1192 ; CHECK:       [[IF_END]]:
1193 ; CHECK-NEXT:    call void @sideeffect()
1194 ; CHECK-NEXT:    ret void
1196 entry:
1197   %c0 = call i1 @cond()
1198   br i1 %c0, label %if.then0, label %if.else
1200 if.then0:
1201   invoke void @simple_throw() strictfp to label %invoke.cont0 unwind label %lpad
1203 invoke.cont0:
1204   unreachable
1206 lpad:
1207   %eh = landingpad { ptr, i32 } cleanup
1208   call void @destructor()
1209   resume { ptr, i32 } %eh
1211 if.else:
1212   %c1 = call i1 @cond()
1213   br i1 %c1, label %if.then1, label %if.end
1215 if.then1:
1216   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1218 invoke.cont2:
1219   unreachable
1221 if.end:
1222   call void @sideeffect()
1223   ret void
1227 ; Common attributes are preserved
1228 define void @t18_attributes_are_preserved() personality ptr @__gxx_personality_v0 {
1229 ; CHECK-LABEL: define void @t18_attributes_are_preserved() personality ptr @__gxx_personality_v0 {
1230 ; CHECK-NEXT:  [[ENTRY:.*:]]
1231 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1232 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1233 ; CHECK:       [[LPAD:.*]]:
1234 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1235 ; CHECK-NEXT:            cleanup
1236 ; CHECK-NEXT:    call void @destructor()
1237 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1238 ; CHECK:       [[IF_ELSE]]:
1239 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1240 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1241 ; CHECK:       [[IF_THEN1_INVOKE]]:
1242 ; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR2]]
1243 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1244 ; CHECK:       [[IF_THEN1_CONT]]:
1245 ; CHECK-NEXT:    unreachable
1246 ; CHECK:       [[IF_END]]:
1247 ; CHECK-NEXT:    call void @sideeffect()
1248 ; CHECK-NEXT:    ret void
1250 entry:
1251   %c0 = call i1 @cond()
1252   br i1 %c0, label %if.then0, label %if.else
1254 if.then0:
1255   invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1257 invoke.cont0:
1258   unreachable
1260 lpad:
1261   %eh = landingpad { ptr, i32 } cleanup
1262   call void @destructor()
1263   resume { ptr, i32 } %eh
1265 if.else:
1266   %c1 = call i1 @cond()
1267   br i1 %c1, label %if.then1, label %if.end
1269 if.then1:
1270   invoke void @simple_throw() readnone to label %invoke.cont2 unwind label %lpad
1272 invoke.cont2:
1273   unreachable
1275 if.end:
1276   call void @sideeffect()
1277   ret void
1280 ; Fully identical operand bundles are good.
1281 define void @t19_compatible_operand_bundle() personality ptr @__gxx_personality_v0 {
1282 ; CHECK-LABEL: define void @t19_compatible_operand_bundle() personality ptr @__gxx_personality_v0 {
1283 ; CHECK-NEXT:  [[ENTRY:.*:]]
1284 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1285 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1286 ; CHECK:       [[LPAD:.*]]:
1287 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1288 ; CHECK-NEXT:            cleanup
1289 ; CHECK-NEXT:    call void @destructor()
1290 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1291 ; CHECK:       [[IF_ELSE]]:
1292 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1293 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1294 ; CHECK:       [[IF_THEN1_INVOKE]]:
1295 ; CHECK-NEXT:    invoke void @simple_throw() [ "abc"(i32 42) ]
1296 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1297 ; CHECK:       [[IF_THEN1_CONT]]:
1298 ; CHECK-NEXT:    unreachable
1299 ; CHECK:       [[IF_END]]:
1300 ; CHECK-NEXT:    call void @sideeffect()
1301 ; CHECK-NEXT:    ret void
1303 entry:
1304   %c0 = call i1 @cond()
1305   br i1 %c0, label %if.then0, label %if.else
1307 if.then0:
1308   invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad
1310 invoke.cont0:
1311   unreachable
1313 lpad:
1314   %eh = landingpad { ptr, i32 } cleanup
1315   call void @destructor()
1316   resume { ptr, i32 } %eh
1318 if.else:
1319   %c1 = call i1 @cond()
1320   br i1 %c1, label %if.then1, label %if.end
1322 if.then1:
1323   invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont2 unwind label %lpad
1325 invoke.cont2:
1326   unreachable
1328 if.end:
1329   call void @sideeffect()
1330   ret void
1333 ; Operand bundles must be compatible, else we can't merge.
1334 define void @t20_incompatible_operand_bundle() personality ptr @__gxx_personality_v0 {
1335 ; CHECK-LABEL: define void @t20_incompatible_operand_bundle() personality ptr @__gxx_personality_v0 {
1336 ; CHECK-NEXT:  [[ENTRY:.*:]]
1337 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1338 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
1339 ; CHECK:       [[IF_THEN0]]:
1340 ; CHECK-NEXT:    invoke void @simple_throw() [ "abc"(i32 42) ]
1341 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
1342 ; CHECK:       [[INVOKE_CONT0]]:
1343 ; CHECK-NEXT:    unreachable
1344 ; CHECK:       [[LPAD]]:
1345 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1346 ; CHECK-NEXT:            cleanup
1347 ; CHECK-NEXT:    call void @destructor()
1348 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1349 ; CHECK:       [[IF_ELSE]]:
1350 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1351 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
1352 ; CHECK:       [[IF_THEN1]]:
1353 ; CHECK-NEXT:    invoke void @simple_throw() [ "def"(i32 0) ]
1354 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
1355 ; CHECK:       [[INVOKE_CONT2]]:
1356 ; CHECK-NEXT:    unreachable
1357 ; CHECK:       [[IF_END]]:
1358 ; CHECK-NEXT:    call void @sideeffect()
1359 ; CHECK-NEXT:    ret void
1361 entry:
1362   %c0 = call i1 @cond()
1363   br i1 %c0, label %if.then0, label %if.else
1365 if.then0:
1366   invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad
1368 invoke.cont0:
1369   unreachable
1371 lpad:
1372   %eh = landingpad { ptr, i32 } cleanup
1373   call void @destructor()
1374   resume { ptr, i32 } %eh
1376 if.else:
1377   %c1 = call i1 @cond()
1378   br i1 %c1, label %if.then1, label %if.end
1380 if.then1:
1381   invoke void @simple_throw() [ "def"(i32 0) ] to label %invoke.cont2 unwind label %lpad
1383 invoke.cont2:
1384   unreachable
1386 if.end:
1387   call void @sideeffect()
1388   ret void
1391 ; We need to PHI together the arguments of the operand bundles.
1392 define void @t21_semicompatible_operand_bundle(i32 %a, i32 %b) personality ptr @__gxx_personality_v0 {
1393 ; CHECK-LABEL: define void @t21_semicompatible_operand_bundle(
1394 ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) personality ptr @__gxx_personality_v0 {
1395 ; CHECK-NEXT:  [[ENTRY:.*]]:
1396 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1397 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1398 ; CHECK:       [[LPAD:.*]]:
1399 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1400 ; CHECK-NEXT:            cleanup
1401 ; CHECK-NEXT:    call void @destructor()
1402 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1403 ; CHECK:       [[IF_ELSE]]:
1404 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1405 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1406 ; CHECK:       [[IF_THEN1_INVOKE]]:
1407 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ [[B]], %[[IF_ELSE]] ], [ [[A]], %[[ENTRY]] ]
1408 ; CHECK-NEXT:    invoke void @simple_throw() [ "abc"(i32 [[TMP0]]) ]
1409 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1410 ; CHECK:       [[IF_THEN1_CONT]]:
1411 ; CHECK-NEXT:    unreachable
1412 ; CHECK:       [[IF_END]]:
1413 ; CHECK-NEXT:    call void @sideeffect()
1414 ; CHECK-NEXT:    ret void
1416 entry:
1417   %c0 = call i1 @cond()
1418   br i1 %c0, label %if.then0, label %if.else
1420 if.then0:
1421   invoke void @simple_throw() [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
1423 invoke.cont0:
1424   unreachable
1426 lpad:
1427   %eh = landingpad { ptr, i32 } cleanup
1428   call void @destructor()
1429   resume { ptr, i32 } %eh
1431 if.else:
1432   %c1 = call i1 @cond()
1433   br i1 %c1, label %if.then1, label %if.end
1435 if.then1:
1436   invoke void @simple_throw() [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
1438 invoke.cont2:
1439   unreachable
1441 if.end:
1442   call void @sideeffect()
1443   ret void
1446 ; Even though the normal destinations are unreachable,
1447 ; they may have (dead) PHI nodes, so we must cleanup them.
1448 define void @t22_dead_phi_in_normal_dest() personality ptr @__gxx_personality_v0 {
1449 ; CHECK-LABEL: define void @t22_dead_phi_in_normal_dest() personality ptr @__gxx_personality_v0 {
1450 ; CHECK-NEXT:  [[ENTRY:.*:]]
1451 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1452 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1453 ; CHECK:       [[LPAD:.*]]:
1454 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1455 ; CHECK-NEXT:            cleanup
1456 ; CHECK-NEXT:    call void @destructor()
1457 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1458 ; CHECK:       [[IF_ELSE]]:
1459 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1460 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1461 ; CHECK:       [[IF_THEN1_INVOKE]]:
1462 ; CHECK-NEXT:    invoke void @maybe_throw()
1463 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1464 ; CHECK:       [[IF_THEN1_CONT]]:
1465 ; CHECK-NEXT:    unreachable
1466 ; CHECK:       [[IF_END]]:
1467 ; CHECK-NEXT:    call void @sideeffect()
1468 ; CHECK-NEXT:    ret void
1470 entry:
1471   %c0 = call i1 @cond()
1472   br i1 %c0, label %if.then0, label %if.else
1474 if.then0:
1475   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1477 lpad:
1478   %eh = landingpad { ptr, i32 } cleanup
1479   call void @destructor()
1480   resume { ptr, i32 } %eh
1482 if.else:
1483   %c1 = call i1 @cond()
1484   br i1 %c1, label %if.then1, label %if.end
1486 if.then1:
1487   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1489 invoke.cont0:
1490   %deadphi0 = phi i32 [ 0, %if.then0 ]
1491   unreachable
1493 invoke.cont2:
1494   %deadphi2 = phi i32 [ 0, %if.then1 ]
1495   unreachable
1497 if.end:
1498   call void @sideeffect()
1499   ret void
1502 ; landingpad has PHI nodes, and out of three invokes, only two have compatible incoming values.
1503 define void @t23_phi_in_landingpad_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1504 ; CHECK-LABEL: define void @t23_phi_in_landingpad_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1505 ; CHECK-NEXT:  [[ENTRY:.*:]]
1506 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1507 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE0:.*]]
1508 ; CHECK:       [[LPAD:.*]]:
1509 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %[[IF_THEN2:.*]] ], [ 0, %[[IF_THEN1_INVOKE]] ]
1510 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1511 ; CHECK-NEXT:            cleanup
1512 ; CHECK-NEXT:    call void @consume(i32 [[PHI]])
1513 ; CHECK-NEXT:    call void @destructor()
1514 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1515 ; CHECK:       [[IF_ELSE0]]:
1516 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1517 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_ELSE1:.*]]
1518 ; CHECK:       [[IF_THEN1_INVOKE]]:
1519 ; CHECK-NEXT:    invoke void @simple_throw()
1520 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
1521 ; CHECK:       [[IF_THEN1_CONT]]:
1522 ; CHECK-NEXT:    unreachable
1523 ; CHECK:       [[IF_ELSE1]]:
1524 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1525 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2]], label %[[IF_END:.*]]
1526 ; CHECK:       [[IF_THEN2]]:
1527 ; CHECK-NEXT:    invoke void @simple_throw()
1528 ; CHECK-NEXT:            to label %[[INVOKE_CONT3:.*]] unwind label %[[LPAD]]
1529 ; CHECK:       [[INVOKE_CONT3]]:
1530 ; CHECK-NEXT:    unreachable
1531 ; CHECK:       [[IF_END]]:
1532 ; CHECK-NEXT:    call void @sideeffect()
1533 ; CHECK-NEXT:    ret void
1535 entry:
1536   %c0 = call i1 @cond()
1537   br i1 %c0, label %if.then0, label %if.else0
1539 if.then0:
1540   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
1542 invoke.cont0:
1543   unreachable
1545 lpad:
1546   %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1547   %eh = landingpad { ptr, i32 } cleanup
1548   call void @consume(i32 %phi)
1549   call void @destructor()
1550   resume { ptr, i32 } %eh
1552 if.else0:
1553   %c1 = call i1 @cond()
1554   br i1 %c1, label %if.then1, label %if.else1
1556 if.then1:
1557   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1559 invoke.cont2:
1560   unreachable
1562 if.else1:
1563   %c2 = call i1 @cond()
1564   br i1 %c2, label %if.then2, label %if.end
1566 if.then2:
1567   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
1569 invoke.cont3:
1570   unreachable
1572 if.end:
1573   call void @sideeffect()
1574   ret void
1577 ; landingpad has two PHI nodes, but depending on which PHI you look,
1578 ; the invoke sets would be different, so we can't merge invokes here.
1579 define void @t24_phi_in_landingpad_semi_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1580 ; CHECK-LABEL: define void @t24_phi_in_landingpad_semi_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1581 ; CHECK-NEXT:  [[ENTRY:.*:]]
1582 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1583 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE0:.*]]
1584 ; CHECK:       [[IF_THEN0]]:
1585 ; CHECK-NEXT:    invoke void @simple_throw()
1586 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
1587 ; CHECK:       [[INVOKE_CONT0]]:
1588 ; CHECK-NEXT:    unreachable
1589 ; CHECK:       [[LPAD]]:
1590 ; CHECK-NEXT:    [[PHI0:%.*]] = phi i32 [ 0, %[[IF_THEN0]] ], [ 0, %[[IF_THEN1:.*]] ], [ -1, %[[IF_THEN2:.*]] ]
1591 ; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ 0, %[[IF_THEN0]] ], [ 1, %[[IF_THEN1]] ], [ 1, %[[IF_THEN2]] ]
1592 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1593 ; CHECK-NEXT:            cleanup
1594 ; CHECK-NEXT:    call void @consume(i32 [[PHI0]])
1595 ; CHECK-NEXT:    call void @consume(i32 [[PHI1]])
1596 ; CHECK-NEXT:    call void @destructor()
1597 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1598 ; CHECK:       [[IF_ELSE0]]:
1599 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1600 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1]], label %[[IF_ELSE1:.*]]
1601 ; CHECK:       [[IF_THEN1]]:
1602 ; CHECK-NEXT:    invoke void @simple_throw()
1603 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
1604 ; CHECK:       [[INVOKE_CONT2]]:
1605 ; CHECK-NEXT:    unreachable
1606 ; CHECK:       [[IF_ELSE1]]:
1607 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1608 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2]], label %[[IF_END:.*]]
1609 ; CHECK:       [[IF_THEN2]]:
1610 ; CHECK-NEXT:    invoke void @simple_throw()
1611 ; CHECK-NEXT:            to label %[[INVOKE_CONT3:.*]] unwind label %[[LPAD]]
1612 ; CHECK:       [[INVOKE_CONT3]]:
1613 ; CHECK-NEXT:    unreachable
1614 ; CHECK:       [[IF_END]]:
1615 ; CHECK-NEXT:    call void @sideeffect()
1616 ; CHECK-NEXT:    ret void
1618 entry:
1619   %c0 = call i1 @cond()
1620   br i1 %c0, label %if.then0, label %if.else0
1622 if.then0:
1623   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
1625 invoke.cont0:
1626   unreachable
1628 lpad:
1629   %phi0 = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1630   %phi1= phi i32 [ 0, %if.then0 ], [ 1, %if.then1 ], [ 1, %if.then2 ]
1631   %eh = landingpad { ptr, i32 } cleanup
1632   call void @consume(i32 %phi0)
1633   call void @consume(i32 %phi1)
1634   call void @destructor()
1635   resume { ptr, i32 } %eh
1637 if.else0:
1638   %c1 = call i1 @cond()
1639   br i1 %c1, label %if.then1, label %if.else1
1641 if.then1:
1642   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1644 invoke.cont2:
1645   unreachable
1647 if.else1:
1648   %c2 = call i1 @cond()
1649   br i1 %c2, label %if.then2, label %if.end
1651 if.then2:
1652   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
1654 invoke.cont3:
1655   unreachable
1657 if.end:
1658   call void @sideeffect()
1659   ret void
1662 ; The normal destinations are shared, but the incoming values are incompatible.
1663 define void @t25_incompatible_phis_in_normal_destination() personality ptr @__gxx_personality_v0 {
1664 ; CHECK-LABEL: define void @t25_incompatible_phis_in_normal_destination() personality ptr @__gxx_personality_v0 {
1665 ; CHECK-NEXT:  [[ENTRY:.*:]]
1666 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1667 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
1668 ; CHECK:       [[IF_THEN0]]:
1669 ; CHECK-NEXT:    invoke void @maybe_throw()
1670 ; CHECK-NEXT:            to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD:.*]]
1671 ; CHECK:       [[INVOKE_CONT]]:
1672 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, %[[IF_THEN0]] ], [ -1, %[[IF_THEN1:.*]] ]
1673 ; CHECK-NEXT:    call void @consume(i32 [[PHI]])
1674 ; CHECK-NEXT:    call void @sideeffect()
1675 ; CHECK-NEXT:    unreachable
1676 ; CHECK:       [[LPAD]]:
1677 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1678 ; CHECK-NEXT:            cleanup
1679 ; CHECK-NEXT:    call void @destructor()
1680 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1681 ; CHECK:       [[IF_ELSE]]:
1682 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1683 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1]], label %[[IF_END:.*]]
1684 ; CHECK:       [[IF_THEN1]]:
1685 ; CHECK-NEXT:    invoke void @maybe_throw()
1686 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
1687 ; CHECK:       [[IF_END]]:
1688 ; CHECK-NEXT:    call void @sideeffect()
1689 ; CHECK-NEXT:    ret void
1691 entry:
1692   %c0 = call i1 @cond()
1693   br i1 %c0, label %if.then0, label %if.else
1695 if.then0:
1696   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1698 invoke.cont:
1699   %phi = phi i32 [ 0, %if.then0 ], [ -1, %if.then1 ]
1700   call void @consume(i32 %phi)
1701   call void @sideeffect()
1702   unreachable
1704 lpad:
1705   %eh = landingpad { ptr, i32 } cleanup
1706   call void @destructor()
1707   resume { ptr, i32 } %eh
1709 if.else:
1710   %c1 = call i1 @cond()
1711   br i1 %c1, label %if.then1, label %if.end
1713 if.then1:
1714   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1716 if.end:
1717   call void @sideeffect()
1718   ret void
1721 ; shared normal destination has PHI nodes, and out of three invokes, only two have compatible incoming values.
1722 define void @t26_phi_in_normal_dest_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1723 ; CHECK-LABEL: define void @t26_phi_in_normal_dest_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1724 ; CHECK-NEXT:  [[ENTRY:.*:]]
1725 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1726 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE0:.*]]
1727 ; CHECK:       [[INVOKE_CONT:.*]]:
1728 ; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, %[[IF_THEN2:.*]] ], [ 0, %[[IF_THEN1_INVOKE]] ]
1729 ; CHECK-NEXT:    call void @consume(i32 [[PHI]])
1730 ; CHECK-NEXT:    call void @sideeffect()
1731 ; CHECK-NEXT:    unreachable
1732 ; CHECK:       [[LPAD:.*]]:
1733 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1734 ; CHECK-NEXT:            cleanup
1735 ; CHECK-NEXT:    call void @destructor()
1736 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1737 ; CHECK:       [[IF_ELSE0]]:
1738 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1739 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_ELSE1:.*]]
1740 ; CHECK:       [[IF_THEN1_INVOKE]]:
1741 ; CHECK-NEXT:    invoke void @maybe_throw()
1742 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
1743 ; CHECK:       [[IF_ELSE1]]:
1744 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1745 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2]], label %[[IF_END:.*]]
1746 ; CHECK:       [[IF_THEN2]]:
1747 ; CHECK-NEXT:    invoke void @maybe_throw()
1748 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
1749 ; CHECK:       [[IF_END]]:
1750 ; CHECK-NEXT:    call void @sideeffect()
1751 ; CHECK-NEXT:    ret void
1753 entry:
1754   %c0 = call i1 @cond()
1755   br i1 %c0, label %if.then0, label %if.else0
1757 if.then0:
1758   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1760 invoke.cont:
1761   %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1762   call void @consume(i32 %phi)
1763   call void @sideeffect()
1764   unreachable
1766 lpad:
1767   %eh = landingpad { ptr, i32 } cleanup
1768   call void @destructor()
1769   resume { ptr, i32 } %eh
1771 if.else0:
1772   %c1 = call i1 @cond()
1773   br i1 %c1, label %if.then1, label %if.else1
1775 if.then1:
1776   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1778 if.else1:
1779   %c2 = call i1 @cond()
1780   br i1 %c2, label %if.then2, label %if.end
1782 if.then2:
1783   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1785 if.end:
1786   call void @sideeffect()
1787   ret void
1790 ; Invokes return values, but they are unused.
1791 define void @t27_invoke_ret_value_is_used() personality ptr @__gxx_personality_v0 {
1792 ; CHECK-LABEL: define void @t27_invoke_ret_value_is_used() personality ptr @__gxx_personality_v0 {
1793 ; CHECK-NEXT:  [[ENTRY:.*:]]
1794 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1795 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1796 ; CHECK:       [[INVOKE_CONT:.*]]:
1797 ; CHECK-NEXT:    call void @sideeffect()
1798 ; CHECK-NEXT:    unreachable
1799 ; CHECK:       [[LPAD:.*]]:
1800 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1801 ; CHECK-NEXT:            cleanup
1802 ; CHECK-NEXT:    call void @destructor()
1803 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1804 ; CHECK:       [[IF_ELSE]]:
1805 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1806 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1807 ; CHECK:       [[IF_THEN1_INVOKE]]:
1808 ; CHECK-NEXT:    [[TMP0:%.*]] = invoke i32 @returning_maybe_throw()
1809 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
1810 ; CHECK:       [[IF_END]]:
1811 ; CHECK-NEXT:    call void @sideeffect()
1812 ; CHECK-NEXT:    ret void
1814 entry:
1815   %c0 = call i1 @cond()
1816   br i1 %c0, label %if.then0, label %if.else
1818 if.then0:
1819   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1821 invoke.cont:
1822   call void @sideeffect()
1823   unreachable
1825 lpad:
1826   %eh = landingpad { ptr, i32 } cleanup
1827   call void @destructor()
1828   resume { ptr, i32 } %eh
1830 if.else:
1831   %c1 = call i1 @cond()
1832   br i1 %c1, label %if.then1, label %if.end
1834 if.then1:
1835   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1837 if.end:
1838   call void @sideeffect()
1839   ret void
1842 ; Invokes return values, and they are used in a phi node, making the incoming values incompatible.
1843 define void @t28_invoke_ret_value_is_used_in_phi_node() personality ptr @__gxx_personality_v0 {
1844 ; CHECK-LABEL: define void @t28_invoke_ret_value_is_used_in_phi_node() personality ptr @__gxx_personality_v0 {
1845 ; CHECK-NEXT:  [[ENTRY:.*:]]
1846 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1847 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
1848 ; CHECK:       [[INVOKE_CONT:.*]]:
1849 ; CHECK-NEXT:    call void @consume(i32 [[TMP0:%.*]])
1850 ; CHECK-NEXT:    call void @sideeffect()
1851 ; CHECK-NEXT:    unreachable
1852 ; CHECK:       [[LPAD:.*]]:
1853 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1854 ; CHECK-NEXT:            cleanup
1855 ; CHECK-NEXT:    call void @destructor()
1856 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1857 ; CHECK:       [[IF_ELSE]]:
1858 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1859 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
1860 ; CHECK:       [[IF_THEN1_INVOKE]]:
1861 ; CHECK-NEXT:    [[TMP0]] = invoke i32 @returning_maybe_throw()
1862 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
1863 ; CHECK:       [[IF_END]]:
1864 ; CHECK-NEXT:    call void @sideeffect()
1865 ; CHECK-NEXT:    ret void
1867 entry:
1868   %c0 = call i1 @cond()
1869   br i1 %c0, label %if.then0, label %if.else
1871 if.then0:
1872   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1874 invoke.cont:
1875   %phi = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
1876   call void @consume(i32 %phi)
1877   call void @sideeffect()
1878   unreachable
1880 lpad:
1881   %eh = landingpad { ptr, i32 } cleanup
1882   call void @destructor()
1883   resume { ptr, i32 } %eh
1885 if.else:
1886   %c1 = call i1 @cond()
1887   br i1 %c1, label %if.then1, label %if.end
1889 if.then1:
1890   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1892 if.end:
1893   call void @sideeffect()
1894   ret void
1897 ; out of three invokes, two share normal destination and another one has unreachable destination
1898 define void @t29_common_normal_destination_and_unreachable_normal_destination() personality ptr @__gxx_personality_v0 {
1899 ; CHECK-LABEL: define void @t29_common_normal_destination_and_unreachable_normal_destination() personality ptr @__gxx_personality_v0 {
1900 ; CHECK-NEXT:  [[ENTRY:.*:]]
1901 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1902 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE0:.*]]
1903 ; CHECK:       [[INVOKE_CONT0:.*]]:
1904 ; CHECK-NEXT:    call void @sideeffect()
1905 ; CHECK-NEXT:    unreachable
1906 ; CHECK:       [[LPAD:.*]]:
1907 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1908 ; CHECK-NEXT:            cleanup
1909 ; CHECK-NEXT:    call void @destructor()
1910 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1911 ; CHECK:       [[IF_ELSE0]]:
1912 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1913 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_ELSE1:.*]]
1914 ; CHECK:       [[IF_THEN1_INVOKE]]:
1915 ; CHECK-NEXT:    invoke void @maybe_throw()
1916 ; CHECK-NEXT:            to label %[[INVOKE_CONT0]] unwind label %[[LPAD]]
1917 ; CHECK:       [[IF_ELSE1]]:
1918 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1919 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2:.*]], label %[[IF_END:.*]]
1920 ; CHECK:       [[IF_THEN2]]:
1921 ; CHECK-NEXT:    invoke void @maybe_throw()
1922 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
1923 ; CHECK:       [[INVOKE_CONT2]]:
1924 ; CHECK-NEXT:    unreachable
1925 ; CHECK:       [[IF_END]]:
1926 ; CHECK-NEXT:    call void @sideeffect()
1927 ; CHECK-NEXT:    ret void
1929 entry:
1930   %c0 = call i1 @cond()
1931   br i1 %c0, label %if.then0, label %if.else0
1933 if.then0:
1934   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1936 invoke.cont0:
1937   call void @sideeffect()
1938   unreachable
1940 lpad:
1941   %eh = landingpad { ptr, i32 } cleanup
1942   call void @destructor()
1943   resume { ptr, i32 } %eh
1945 if.else0:
1946   %c1 = call i1 @cond()
1947   br i1 %c1, label %if.then1, label %if.else1
1949 if.then1:
1950   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1952 if.else1:
1953   %c2 = call i1 @cond()
1954   br i1 %c2, label %if.then2, label %if.end
1956 if.then2:
1957   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1959 invoke.cont2:
1960   unreachable
1962 if.end:
1963   call void @sideeffect()
1964   ret void
1967 ; normal destinations are not unreachable and different but could be merged
1968 define void @t30_completely_different_normal_dests() personality ptr @__gxx_personality_v0 {
1969 ; CHECK-LABEL: define void @t30_completely_different_normal_dests() personality ptr @__gxx_personality_v0 {
1970 ; CHECK-NEXT:  [[ENTRY:.*:]]
1971 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
1972 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
1973 ; CHECK:       [[IF_THEN0]]:
1974 ; CHECK-NEXT:    invoke void @maybe_throw()
1975 ; CHECK-NEXT:            to label %[[INVOKE_CONT0:.*]] unwind label %[[LPAD:.*]]
1976 ; CHECK:       [[INVOKE_CONT0]]:
1977 ; CHECK-NEXT:    call void @sideeffect()
1978 ; CHECK-NEXT:    unreachable
1979 ; CHECK:       [[LPAD]]:
1980 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1981 ; CHECK-NEXT:            cleanup
1982 ; CHECK-NEXT:    call void @destructor()
1983 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1984 ; CHECK:       [[IF_ELSE]]:
1985 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1986 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1:.*]], label %[[IF_END:.*]]
1987 ; CHECK:       [[IF_THEN1]]:
1988 ; CHECK-NEXT:    invoke void @maybe_throw()
1989 ; CHECK-NEXT:            to label %[[INVOKE_CONT2:.*]] unwind label %[[LPAD]]
1990 ; CHECK:       [[INVOKE_CONT2]]:
1991 ; CHECK-NEXT:    call void @sideeffect()
1992 ; CHECK-NEXT:    unreachable
1993 ; CHECK:       [[IF_END]]:
1994 ; CHECK-NEXT:    call void @sideeffect()
1995 ; CHECK-NEXT:    ret void
1997 entry:
1998   %c0 = call i1 @cond()
1999   br i1 %c0, label %if.then0, label %if.else
2001 if.then0:
2002   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
2004 invoke.cont0:
2005   call void @sideeffect()
2006   unreachable
2008 lpad:
2009   %eh = landingpad { ptr, i32 } cleanup
2010   call void @destructor()
2011   resume { ptr, i32 } %eh
2013 if.else:
2014   %c1 = call i1 @cond()
2015   br i1 %c1, label %if.then1, label %if.end
2017 if.then1:
2018   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
2020 invoke.cont2:
2021   call void @sideeffect()
2022   unreachable
2024 if.end:
2025   call void @sideeffect()
2026   ret void
2029 ; Even though the normal destinations are unreachable,
2030 ; they may have (dead) PHI nodes with incompatible incoming values,
2031 ; so we must cleanup them.
2032 define void @t31_incompatible_dead_phi_in_normal_dest() personality ptr @__gxx_personality_v0 {
2033 ; CHECK-LABEL: define void @t31_incompatible_dead_phi_in_normal_dest() personality ptr @__gxx_personality_v0 {
2034 ; CHECK-NEXT:  [[ENTRY:.*:]]
2035 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2036 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2037 ; CHECK:       [[LPAD:.*]]:
2038 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2039 ; CHECK-NEXT:            cleanup
2040 ; CHECK-NEXT:    call void @destructor()
2041 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2042 ; CHECK:       [[IF_ELSE]]:
2043 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2044 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2045 ; CHECK:       [[IF_THEN1_INVOKE]]:
2046 ; CHECK-NEXT:    invoke void @maybe_throw()
2047 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2048 ; CHECK:       [[IF_THEN1_CONT]]:
2049 ; CHECK-NEXT:    unreachable
2050 ; CHECK:       [[IF_END]]:
2051 ; CHECK-NEXT:    call void @sideeffect()
2052 ; CHECK-NEXT:    ret void
2054 entry:
2055   %c0 = call i1 @cond()
2056   br i1 %c0, label %if.then0, label %if.else
2058 if.then0:
2059   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
2061 lpad:
2062   %eh = landingpad { ptr, i32 } cleanup
2063   call void @destructor()
2064   resume { ptr, i32 } %eh
2066 if.else:
2067   %c1 = call i1 @cond()
2068   br i1 %c1, label %if.then1, label %if.end
2070 if.then1:
2071   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
2073 invoke.cont:
2074   %deadphi0 = phi i32 [ 0, %if.then0 ],  [ -1, %if.then1 ]
2075   unreachable
2077 if.end:
2078   call void @sideeffect()
2079   ret void
2082 ; Invokes return values, and they are used in a phi node, making the incoming values incompatible,
2083 ; second phi has compatible incoming values
2084 define void @t32_invoke_ret_value_is_used_in_phi_node_other_phi_is_fine() personality ptr @__gxx_personality_v0 {
2085 ; CHECK-LABEL: define void @t32_invoke_ret_value_is_used_in_phi_node_other_phi_is_fine() personality ptr @__gxx_personality_v0 {
2086 ; CHECK-NEXT:  [[ENTRY:.*:]]
2087 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2088 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2089 ; CHECK:       [[INVOKE_CONT:.*]]:
2090 ; CHECK-NEXT:    call void @consume(i32 [[TMP0:%.*]])
2091 ; CHECK-NEXT:    call void @consume(i32 0)
2092 ; CHECK-NEXT:    call void @sideeffect()
2093 ; CHECK-NEXT:    unreachable
2094 ; CHECK:       [[LPAD:.*]]:
2095 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2096 ; CHECK-NEXT:            cleanup
2097 ; CHECK-NEXT:    call void @destructor()
2098 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2099 ; CHECK:       [[IF_ELSE]]:
2100 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2101 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2102 ; CHECK:       [[IF_THEN1_INVOKE]]:
2103 ; CHECK-NEXT:    [[TMP0]] = invoke i32 @returning_maybe_throw()
2104 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
2105 ; CHECK:       [[IF_END]]:
2106 ; CHECK-NEXT:    call void @sideeffect()
2107 ; CHECK-NEXT:    ret void
2109 entry:
2110   %c0 = call i1 @cond()
2111   br i1 %c0, label %if.then0, label %if.else
2113 if.then0:
2114   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2116 invoke.cont:
2117   %phi0 = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
2118   %phi1 = phi i32 [ 0, %if.then0 ],   [ 0, %if.then1 ]
2119   call void @consume(i32 %phi0)
2120   call void @consume(i32 %phi1)
2121   call void @sideeffect()
2122   unreachable
2124 lpad:
2125   %eh = landingpad { ptr, i32 } cleanup
2126   call void @destructor()
2127   resume { ptr, i32 } %eh
2129 if.else:
2130   %c1 = call i1 @cond()
2131   br i1 %c1, label %if.then1, label %if.end
2133 if.then1:
2134   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2136 if.end:
2137   call void @sideeffect()
2138   ret void
2141 ; Invokes return values, and they are used in a phi node, making the incoming values incompatible,
2142 ; second phi has incompatible incoming values.
2143 define void @t33_invoke_ret_value_is_used_in_phi_node_other_phi_is_bad() personality ptr @__gxx_personality_v0 {
2144 ; CHECK-LABEL: define void @t33_invoke_ret_value_is_used_in_phi_node_other_phi_is_bad() personality ptr @__gxx_personality_v0 {
2145 ; CHECK-NEXT:  [[ENTRY:.*:]]
2146 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2147 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
2148 ; CHECK:       [[IF_THEN0]]:
2149 ; CHECK-NEXT:    [[V0:%.*]] = invoke i32 @returning_maybe_throw()
2150 ; CHECK-NEXT:            to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD:.*]]
2151 ; CHECK:       [[INVOKE_CONT]]:
2152 ; CHECK-NEXT:    [[PHI0:%.*]] = phi i32 [ [[V0]], %[[IF_THEN0]] ], [ [[V1:%.*]], %[[IF_THEN1:.*]] ]
2153 ; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ 0, %[[IF_THEN0]] ], [ -1, %[[IF_THEN1]] ]
2154 ; CHECK-NEXT:    call void @consume(i32 [[PHI0]])
2155 ; CHECK-NEXT:    call void @consume(i32 [[PHI1]])
2156 ; CHECK-NEXT:    call void @sideeffect()
2157 ; CHECK-NEXT:    unreachable
2158 ; CHECK:       [[LPAD]]:
2159 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2160 ; CHECK-NEXT:            cleanup
2161 ; CHECK-NEXT:    call void @destructor()
2162 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2163 ; CHECK:       [[IF_ELSE]]:
2164 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2165 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1]], label %[[IF_END:.*]]
2166 ; CHECK:       [[IF_THEN1]]:
2167 ; CHECK-NEXT:    [[V1]] = invoke i32 @returning_maybe_throw()
2168 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
2169 ; CHECK:       [[IF_END]]:
2170 ; CHECK-NEXT:    call void @sideeffect()
2171 ; CHECK-NEXT:    ret void
2173 entry:
2174   %c0 = call i1 @cond()
2175   br i1 %c0, label %if.then0, label %if.else
2177 if.then0:
2178   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2180 invoke.cont:
2181   %phi0 = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
2182   %phi1 = phi i32 [ 0, %if.then0 ],   [ -1, %if.then1 ]
2183   call void @consume(i32 %phi0)
2184   call void @consume(i32 %phi1)
2185   call void @sideeffect()
2186   unreachable
2188 lpad:
2189   %eh = landingpad { ptr, i32 } cleanup
2190   call void @destructor()
2191   resume { ptr, i32 } %eh
2193 if.else:
2194   %c1 = call i1 @cond()
2195   br i1 %c1, label %if.then1, label %if.end
2197 if.then1:
2198   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2200 if.end:
2201   call void @sideeffect()
2202   ret void
2205 ; Invokes return values, and they are used in a phi node, but when coming from different invokes,
2206 ; the incoming value isn't always the invoke, which is not okay.
2207 define void @t34_invoke_ret_value_maybe_incompatibly_used_in_phi_node() personality ptr @__gxx_personality_v0 {
2208 ; CHECK-LABEL: define void @t34_invoke_ret_value_maybe_incompatibly_used_in_phi_node() personality ptr @__gxx_personality_v0 {
2209 ; CHECK-NEXT:  [[ENTRY:.*:]]
2210 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2211 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN0:.*]], label %[[IF_ELSE:.*]]
2212 ; CHECK:       [[IF_THEN0]]:
2213 ; CHECK-NEXT:    [[V0:%.*]] = invoke i32 @returning_maybe_throw()
2214 ; CHECK-NEXT:            to label %[[INVOKE_CONT:.*]] unwind label %[[LPAD:.*]]
2215 ; CHECK:       [[INVOKE_CONT]]:
2216 ; CHECK-NEXT:    [[PHI0:%.*]] = phi i32 [ [[V0]], %[[IF_THEN0]] ], [ 0, %[[IF_THEN1:.*]] ]
2217 ; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ 0, %[[IF_THEN0]] ], [ [[V1:%.*]], %[[IF_THEN1]] ]
2218 ; CHECK-NEXT:    call void @consume(i32 [[PHI0]])
2219 ; CHECK-NEXT:    call void @consume(i32 [[PHI1]])
2220 ; CHECK-NEXT:    call void @sideeffect()
2221 ; CHECK-NEXT:    unreachable
2222 ; CHECK:       [[LPAD]]:
2223 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2224 ; CHECK-NEXT:            cleanup
2225 ; CHECK-NEXT:    call void @destructor()
2226 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2227 ; CHECK:       [[IF_ELSE]]:
2228 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2229 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1]], label %[[IF_END:.*]]
2230 ; CHECK:       [[IF_THEN1]]:
2231 ; CHECK-NEXT:    [[V1]] = invoke i32 @returning_maybe_throw()
2232 ; CHECK-NEXT:            to label %[[INVOKE_CONT]] unwind label %[[LPAD]]
2233 ; CHECK:       [[IF_END]]:
2234 ; CHECK-NEXT:    call void @sideeffect()
2235 ; CHECK-NEXT:    ret void
2237 entry:
2238   %c0 = call i1 @cond()
2239   br i1 %c0, label %if.then0, label %if.else
2241 if.then0:
2242   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2244 invoke.cont:
2245   %phi0 = phi i32 [ %v0, %if.then0 ], [ 0, %if.then1 ]
2246   %phi1 = phi i32 [ 0, %if.then0 ],   [ %v1, %if.then1 ]
2247   call void @consume(i32 %phi0)
2248   call void @consume(i32 %phi1)
2249   call void @sideeffect()
2250   unreachable
2252 lpad:
2253   %eh = landingpad { ptr, i32 } cleanup
2254   call void @destructor()
2255   resume { ptr, i32 } %eh
2257 if.else:
2258   %c1 = call i1 @cond()
2259   br i1 %c1, label %if.then1, label %if.end
2261 if.then1:
2262   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2264 if.end:
2265   call void @sideeffect()
2266   ret void
2269 ; Two mergeable indirect calls, with identical callees.
2270 define void @t35_identical_indirect_callees(ptr %callee) personality ptr @__gxx_personality_v0 {
2271 ; CHECK-LABEL: define void @t35_identical_indirect_callees(
2272 ; CHECK-SAME: ptr [[CALLEE:%.*]]) personality ptr @__gxx_personality_v0 {
2273 ; CHECK-NEXT:  [[ENTRY:.*:]]
2274 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2275 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2276 ; CHECK:       [[LPAD:.*]]:
2277 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2278 ; CHECK-NEXT:            cleanup
2279 ; CHECK-NEXT:    call void @destructor()
2280 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2281 ; CHECK:       [[IF_ELSE]]:
2282 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2283 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2284 ; CHECK:       [[IF_THEN1_INVOKE]]:
2285 ; CHECK-NEXT:    invoke void [[CALLEE]]()
2286 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2287 ; CHECK:       [[IF_THEN1_CONT]]:
2288 ; CHECK-NEXT:    unreachable
2289 ; CHECK:       [[IF_END]]:
2290 ; CHECK-NEXT:    call void @sideeffect()
2291 ; CHECK-NEXT:    ret void
2293 entry:
2294   %c0 = call i1 @cond()
2295   br i1 %c0, label %if.then0, label %if.else
2297 if.then0:
2298   invoke void %callee() to label %invoke.cont0 unwind label %lpad
2300 invoke.cont0:
2301   unreachable
2303 lpad:
2304   %eh = landingpad { ptr, i32 } cleanup
2305   call void @destructor()
2306   resume { ptr, i32 } %eh
2308 if.else:
2309   %c1 = call i1 @cond()
2310   br i1 %c1, label %if.then1, label %if.end
2312 if.then1:
2313   invoke void %callee() to label %invoke.cont2 unwind label %lpad
2315 invoke.cont2:
2316   unreachable
2318 if.end:
2319   call void @sideeffect()
2320   ret void
2323 ; Two mergeable indirect calls, with different callees.
2324 define void @t36_different_indirect_callees(ptr %callee0, ptr %callee1) personality ptr @__gxx_personality_v0 {
2325 ; CHECK-LABEL: define void @t36_different_indirect_callees(
2326 ; CHECK-SAME: ptr [[CALLEE0:%.*]], ptr [[CALLEE1:%.*]]) personality ptr @__gxx_personality_v0 {
2327 ; CHECK-NEXT:  [[ENTRY:.*]]:
2328 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2329 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2330 ; CHECK:       [[LPAD:.*]]:
2331 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2332 ; CHECK-NEXT:            cleanup
2333 ; CHECK-NEXT:    call void @destructor()
2334 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2335 ; CHECK:       [[IF_ELSE]]:
2336 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2337 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2338 ; CHECK:       [[IF_THEN1_INVOKE]]:
2339 ; CHECK-NEXT:    [[TMP0:%.*]] = phi ptr [ [[CALLEE1]], %[[IF_ELSE]] ], [ [[CALLEE0]], %[[ENTRY]] ]
2340 ; CHECK-NEXT:    invoke void [[TMP0]]()
2341 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2342 ; CHECK:       [[IF_THEN1_CONT]]:
2343 ; CHECK-NEXT:    unreachable
2344 ; CHECK:       [[IF_END]]:
2345 ; CHECK-NEXT:    call void @sideeffect()
2346 ; CHECK-NEXT:    ret void
2348 entry:
2349   %c0 = call i1 @cond()
2350   br i1 %c0, label %if.then0, label %if.else
2352 if.then0:
2353   invoke void %callee0() to label %invoke.cont0 unwind label %lpad
2355 invoke.cont0:
2356   unreachable
2358 lpad:
2359   %eh = landingpad { ptr, i32 } cleanup
2360   call void @destructor()
2361   resume { ptr, i32 } %eh
2363 if.else:
2364   %c1 = call i1 @cond()
2365   br i1 %c1, label %if.then1, label %if.end
2367 if.then1:
2368   invoke void %callee1() to label %invoke.cont2 unwind label %lpad
2370 invoke.cont2:
2371   unreachable
2373 if.end:
2374   call void @sideeffect()
2375   ret void
2378 ; Don't merge direct invoke with indirect ones.
2379 define void @t37_three_invokes_two_indirect_one_direct(ptr %callee) personality ptr @__gxx_personality_v0 {
2380 ; CHECK-LABEL: define void @t37_three_invokes_two_indirect_one_direct(
2381 ; CHECK-SAME: ptr [[CALLEE:%.*]]) personality ptr @__gxx_personality_v0 {
2382 ; CHECK-NEXT:  [[ENTRY:.*:]]
2383 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2384 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE0:.*]]
2385 ; CHECK:       [[LPAD:.*]]:
2386 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2387 ; CHECK-NEXT:            cleanup
2388 ; CHECK-NEXT:    call void @destructor()
2389 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2390 ; CHECK:       [[IF_ELSE0]]:
2391 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2392 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_ELSE1:.*]]
2393 ; CHECK:       [[IF_THEN1_INVOKE]]:
2394 ; CHECK-NEXT:    invoke void [[CALLEE]]()
2395 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2396 ; CHECK:       [[IF_THEN1_CONT]]:
2397 ; CHECK-NEXT:    unreachable
2398 ; CHECK:       [[IF_ELSE1]]:
2399 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
2400 ; CHECK-NEXT:    br i1 [[C2]], label %[[IF_THEN2:.*]], label %[[IF_END:.*]]
2401 ; CHECK:       [[IF_THEN2]]:
2402 ; CHECK-NEXT:    invoke void @simple_throw()
2403 ; CHECK-NEXT:            to label %[[INVOKE_CONT3:.*]] unwind label %[[LPAD]]
2404 ; CHECK:       [[INVOKE_CONT3]]:
2405 ; CHECK-NEXT:    unreachable
2406 ; CHECK:       [[IF_END]]:
2407 ; CHECK-NEXT:    call void @sideeffect()
2408 ; CHECK-NEXT:    ret void
2410 entry:
2411   %c0 = call i1 @cond()
2412   br i1 %c0, label %if.then0, label %if.else0
2414 if.then0:
2415   invoke void %callee() to label %invoke.cont0 unwind label %lpad
2417 invoke.cont0:
2418   unreachable
2420 lpad:
2421   %eh = landingpad { ptr, i32 } cleanup
2422   call void @destructor()
2423   resume { ptr, i32 } %eh
2425 if.else0:
2426   %c1 = call i1 @cond()
2427   br i1 %c1, label %if.then1, label %if.else1
2429 if.then1:
2430   invoke void %callee() to label %invoke.cont2 unwind label %lpad
2432 invoke.cont2:
2433   unreachable
2435 if.else1:
2436   %c2 = call i1 @cond()
2437   br i1 %c2, label %if.then2, label %if.end
2439 if.then2:
2440   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
2442 invoke.cont3:
2443   unreachable
2445 if.end:
2446   call void @sideeffect()
2447   ret void
2450 ; For indirect invokes, different arguments are fine.
2451 define void @t38_different_arguments_and_operand_bundes_are_fine(ptr %callee0, ptr %callee1) personality ptr @__gxx_personality_v0 {
2452 ; CHECK-LABEL: define void @t38_different_arguments_and_operand_bundes_are_fine(
2453 ; CHECK-SAME: ptr [[CALLEE0:%.*]], ptr [[CALLEE1:%.*]]) personality ptr @__gxx_personality_v0 {
2454 ; CHECK-NEXT:  [[ENTRY:.*]]:
2455 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2456 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2457 ; CHECK:       [[LPAD:.*]]:
2458 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2459 ; CHECK-NEXT:            cleanup
2460 ; CHECK-NEXT:    call void @destructor()
2461 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2462 ; CHECK:       [[IF_ELSE]]:
2463 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2464 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2465 ; CHECK:       [[IF_THEN1_INVOKE]]:
2466 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 42, %[[IF_ELSE]] ], [ 0, %[[ENTRY]] ]
2467 ; CHECK-NEXT:    [[TMP1:%.*]] = phi ptr [ [[CALLEE1]], %[[IF_ELSE]] ], [ [[CALLEE0]], %[[ENTRY]] ]
2468 ; CHECK-NEXT:    invoke void [[TMP1]](i32 [[TMP0]])
2469 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2470 ; CHECK:       [[IF_THEN1_CONT]]:
2471 ; CHECK-NEXT:    unreachable
2472 ; CHECK:       [[IF_END]]:
2473 ; CHECK-NEXT:    call void @sideeffect()
2474 ; CHECK-NEXT:    ret void
2476 entry:
2477   %c0 = call i1 @cond()
2478   br i1 %c0, label %if.then0, label %if.else
2480 if.then0:
2481   invoke void %callee0(i32 0) to label %invoke.cont0 unwind label %lpad
2483 invoke.cont0:
2484   unreachable
2486 lpad:
2487   %eh = landingpad { ptr, i32 } cleanup
2488   call void @destructor()
2489   resume { ptr, i32 } %eh
2491 if.else:
2492   %c1 = call i1 @cond()
2493   br i1 %c1, label %if.then1, label %if.end
2495 if.then1:
2496   invoke void %callee1(i32 42) to label %invoke.cont2 unwind label %lpad
2498 invoke.cont2:
2499   unreachable
2501 if.end:
2502   call void @sideeffect()
2503   ret void
2506 ; For indirect invokes, different operand bundle arguments are fine.
2507 define void @t39_different_arguments_and_operand_bundes_are_fine(ptr %callee0, ptr %callee1, i32 %a, i32 %b) personality ptr @__gxx_personality_v0 {
2508 ; CHECK-LABEL: define void @t39_different_arguments_and_operand_bundes_are_fine(
2509 ; CHECK-SAME: ptr [[CALLEE0:%.*]], ptr [[CALLEE1:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) personality ptr @__gxx_personality_v0 {
2510 ; CHECK-NEXT:  [[ENTRY:.*]]:
2511 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2512 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2513 ; CHECK:       [[LPAD:.*]]:
2514 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2515 ; CHECK-NEXT:            cleanup
2516 ; CHECK-NEXT:    call void @destructor()
2517 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2518 ; CHECK:       [[IF_ELSE]]:
2519 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2520 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2521 ; CHECK:       [[IF_THEN1_INVOKE]]:
2522 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ [[B]], %[[IF_ELSE]] ], [ [[A]], %[[ENTRY]] ]
2523 ; CHECK-NEXT:    [[TMP1:%.*]] = phi ptr [ [[CALLEE1]], %[[IF_ELSE]] ], [ [[CALLEE0]], %[[ENTRY]] ]
2524 ; CHECK-NEXT:    invoke void [[TMP1]]() [ "abc"(i32 [[TMP0]]) ]
2525 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2526 ; CHECK:       [[IF_THEN1_CONT]]:
2527 ; CHECK-NEXT:    unreachable
2528 ; CHECK:       [[IF_END]]:
2529 ; CHECK-NEXT:    call void @sideeffect()
2530 ; CHECK-NEXT:    ret void
2532 entry:
2533   %c0 = call i1 @cond()
2534   br i1 %c0, label %if.then0, label %if.else
2536 if.then0:
2537   invoke void %callee0() [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
2539 invoke.cont0:
2540   unreachable
2542 lpad:
2543   %eh = landingpad { ptr, i32 } cleanup
2544   call void @destructor()
2545   resume { ptr, i32 } %eh
2547 if.else:
2548   %c1 = call i1 @cond()
2549   br i1 %c1, label %if.then1, label %if.end
2551 if.then1:
2552   invoke void %callee1() [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
2554 invoke.cont2:
2555   unreachable
2557 if.end:
2558   call void @sideeffect()
2559   ret void
2562 ; For indirect invokes, both different arguments and operand bundle arguments are fine.
2563 define void @t40_different_arguments_and_operand_bundes_are_fine(ptr %callee0, ptr %callee1, i32 %a, i32 %b) personality ptr @__gxx_personality_v0 {
2564 ; CHECK-LABEL: define void @t40_different_arguments_and_operand_bundes_are_fine(
2565 ; CHECK-SAME: ptr [[CALLEE0:%.*]], ptr [[CALLEE1:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) personality ptr @__gxx_personality_v0 {
2566 ; CHECK-NEXT:  [[ENTRY:.*]]:
2567 ; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
2568 ; CHECK-NEXT:    br i1 [[C0]], label %[[IF_THEN1_INVOKE:.*]], label %[[IF_ELSE:.*]]
2569 ; CHECK:       [[LPAD:.*]]:
2570 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2571 ; CHECK-NEXT:            cleanup
2572 ; CHECK-NEXT:    call void @destructor()
2573 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2574 ; CHECK:       [[IF_ELSE]]:
2575 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2576 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF_THEN1_INVOKE]], label %[[IF_END:.*]]
2577 ; CHECK:       [[IF_THEN1_INVOKE]]:
2578 ; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 42, %[[IF_ELSE]] ], [ 0, %[[ENTRY]] ]
2579 ; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[B]], %[[IF_ELSE]] ], [ [[A]], %[[ENTRY]] ]
2580 ; CHECK-NEXT:    [[TMP2:%.*]] = phi ptr [ [[CALLEE1]], %[[IF_ELSE]] ], [ [[CALLEE0]], %[[ENTRY]] ]
2581 ; CHECK-NEXT:    invoke void [[TMP2]](i32 [[TMP0]]) [ "abc"(i32 [[TMP1]]) ]
2582 ; CHECK-NEXT:            to label %[[IF_THEN1_CONT:.*]] unwind label %[[LPAD]]
2583 ; CHECK:       [[IF_THEN1_CONT]]:
2584 ; CHECK-NEXT:    unreachable
2585 ; CHECK:       [[IF_END]]:
2586 ; CHECK-NEXT:    call void @sideeffect()
2587 ; CHECK-NEXT:    ret void
2589 entry:
2590   %c0 = call i1 @cond()
2591   br i1 %c0, label %if.then0, label %if.else
2593 if.then0:
2594   invoke void %callee0(i32 0) [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
2596 invoke.cont0:
2597   unreachable
2599 lpad:
2600   %eh = landingpad { ptr, i32 } cleanup
2601   call void @destructor()
2602   resume { ptr, i32 } %eh
2604 if.else:
2605   %c1 = call i1 @cond()
2606   br i1 %c1, label %if.then1, label %if.end
2608 if.then1:
2609   invoke void %callee1(i32 42) [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
2611 invoke.cont2:
2612   unreachable
2614 if.end:
2615   call void @sideeffect()
2616   ret void
2619 define void @dont_merge_different_immargs(i1 %c1) gc "statepoint-example" personality ptr null {
2620 ; CHECK-LABEL: define void @dont_merge_different_immargs(
2621 ; CHECK-SAME: i1 [[C1:%.*]]) gc "statepoint-example" personality ptr null {
2622 ; CHECK-NEXT:    br i1 [[C1]], label %[[IF:.*]], label %[[ELSE:.*]]
2623 ; CHECK:       [[IF]]:
2624 ; CHECK-NEXT:    [[T1:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 1, i32 0, ptr elementtype(void (ptr addrspace(1))) null, i32 1, i32 0, ptr addrspace(1) null, i64 0, i64 0)
2625 ; CHECK-NEXT:            to label %[[UNREACHABLE:.*]] unwind label %[[LPAD:.*]]
2626 ; CHECK:       [[ELSE]]:
2627 ; CHECK-NEXT:    [[T2:%.*]] = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr addrspace(1))) null, i32 1, i32 0, ptr addrspace(1) null, i64 0, i64 0)
2628 ; CHECK-NEXT:            to label %[[UNREACHABLE]] unwind label %[[LPAD]]
2629 ; CHECK:       [[UNREACHABLE]]:
2630 ; CHECK-NEXT:    unreachable
2631 ; CHECK:       [[LPAD]]:
2632 ; CHECK-NEXT:    [[T3:%.*]] = landingpad token
2633 ; CHECK-NEXT:            cleanup
2634 ; CHECK-NEXT:    ret void
2636   br i1 %c1, label %if, label %else
2639   %t1 = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 1, i32 0, ptr elementtype(void (ptr addrspace(1))) null, i32 1, i32 0, ptr addrspace(1) null, i64 0, i64 0)
2640   to label %unreachable unwind label %lpad
2642 else:
2643   %t2 = invoke token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void (ptr addrspace(1))) null, i32 1, i32 0, ptr addrspace(1) null, i64 0, i64 0)
2644   to label %unreachable unwind label %lpad
2646 unreachable:
2647   unreachable
2649 lpad:
2650   %t3 = landingpad token
2651   cleanup
2652   ret void
2655 declare token @llvm.experimental.gc.statepoint.p0(i64 immarg, i32 immarg, ptr, i32 immarg, i32 immarg, ...)
2657 declare i1 @cond()
2659 declare void @sideeffect()
2660 declare void @another_sideeffect()
2662 declare void @maybe_throw()
2664 declare void @simple_throw() noreturn
2665 declare void @another_simple_throw() noreturn
2667 declare void @simple_throw_taking_argument(i32) noreturn
2669 declare i32 @returning_maybe_throw()
2671 declare void @destructor()
2672 declare void @another_destructor()
2674 declare void @consume(i32)
2676 declare dso_local i32 @__gxx_personality_v0(...)
2678 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn }
2679 ; CHECK: attributes #[[ATTR1]] = { nomerge }
2680 ; CHECK: attributes #[[ATTR2]] = { memory(none) }
2681 ; CHECK: attributes #[[ATTR3]] = { strictfp }