1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals
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: @t0_noop(
12 ; CHECK-NEXT: [[C:%.*]] = call i1 @cond()
13 ; CHECK-NEXT: br i1 [[C]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
15 ; CHECK-NEXT: invoke void @simple_throw()
16 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
18 ; CHECK-NEXT: unreachable
20 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
22 ; CHECK-NEXT: call void @destructor()
23 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
25 ; CHECK-NEXT: call void @sideeffect()
26 ; CHECK-NEXT: ret void
30 br i1 %c, label %if.then, label %if.end
33 invoke void @simple_throw() to label %invoke.cont unwind label %lpad
39 %eh = landingpad { ptr, i32 } cleanup
40 call void @destructor()
41 resume { ptr, i32 } %eh
44 call void @sideeffect()
48 ; More interesting test, here we can merge the invokes.
49 define void @t1_mergeable_invoke() personality ptr @__gxx_personality_v0 {
50 ; CHECK-LABEL: @t1_mergeable_invoke(
52 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
53 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
55 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
57 ; CHECK-NEXT: call void @destructor()
58 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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
68 ; CHECK-NEXT: call void @sideeffect()
69 ; CHECK-NEXT: ret void
73 br i1 %c0, label %if.then0, label %if.else
76 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
82 %eh = landingpad { ptr, i32 } cleanup
83 call void @destructor()
84 resume { ptr, i32 } %eh
88 br i1 %c1, label %if.then1, label %if.end
91 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
97 call void @sideeffect()
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: @t2_shared_normal_dest(
105 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
106 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
108 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
109 ; CHECK-NEXT: cleanup
110 ; CHECK-NEXT: call void @destructor()
111 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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
121 ; CHECK-NEXT: call void @sideeffect()
122 ; CHECK-NEXT: ret void
125 %c0 = call i1 @cond()
126 br i1 %c0, label %if.then0, label %if.else
129 invoke void @simple_throw() to label %invoke.cont unwind label %lpad
135 %eh = landingpad { ptr, i32 } cleanup
136 call void @destructor()
137 resume { ptr, i32 } %eh
140 %c1 = call i1 @cond()
141 br i1 %c1, label %if.then1, label %if.end
144 invoke void @simple_throw() to label %invoke.cont unwind label %lpad
147 call void @sideeffect()
151 ; shared normal destination is not unreachable.
152 define void @t3_shared_identical_normal_dest() personality ptr @__gxx_personality_v0 {
153 ; CHECK-LABEL: @t3_shared_identical_normal_dest(
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
161 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
162 ; CHECK-NEXT: cleanup
163 ; CHECK-NEXT: call void @destructor()
164 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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:%.*]]
172 ; CHECK-NEXT: call void @sideeffect()
173 ; CHECK-NEXT: ret void
176 %c0 = call i1 @cond()
177 br i1 %c0, label %if.then0, label %if.else
180 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
183 call void @sideeffect()
187 %eh = landingpad { ptr, i32 } cleanup
188 call void @destructor()
189 resume { ptr, i32 } %eh
192 %c1 = call i1 @cond()
193 br i1 %c1, label %if.then1, label %if.end
196 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
199 call void @sideeffect()
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: @t4_normal_dests(
207 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
208 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
216 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
217 ; CHECK-NEXT: cleanup
218 ; CHECK-NEXT: call void @destructor()
219 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
221 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
222 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
230 ; CHECK-NEXT: call void @sideeffect()
231 ; CHECK-NEXT: ret void
234 %c0 = call i1 @cond()
235 br i1 %c0, label %if.then0, label %if.else
238 invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
241 call void @sideeffect()
245 %eh = landingpad { ptr, i32 } cleanup
246 call void @destructor()
247 resume { ptr, i32 } %eh
250 %c1 = call i1 @cond()
251 br i1 %c1, label %if.then1, label %if.end
254 invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
257 call void @another_sideeffect()
261 call void @sideeffect()
265 ; Invokes lead to different landing pads.
266 define void @t5_different_landingpads() personality ptr @__gxx_personality_v0 {
267 ; CHECK-LABEL: @t5_different_landingpads(
269 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
270 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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]]
280 ; CHECK-NEXT: [[EH0]] = landingpad { ptr, i32 }
281 ; CHECK-NEXT: cleanup
282 ; CHECK-NEXT: call void @destructor()
283 ; CHECK-NEXT: br label [[COMMON_RESUME:%.*]]
285 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
286 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
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]]
298 ; CHECK-NEXT: call void @sideeffect()
299 ; CHECK-NEXT: ret void
302 %c0 = call i1 @cond()
303 br i1 %c0, label %if.then0, label %if.else
306 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad0
312 %eh0 = landingpad { ptr, i32 } cleanup
313 call void @destructor()
314 resume { ptr, i32 } %eh0
317 %c1 = call i1 @cond()
318 br i1 %c1, label %if.then1, label %if.end
321 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad1
327 %eh1 = landingpad { ptr, i32 } cleanup
328 call void @another_destructor()
329 resume { ptr, i32 } %eh1
332 call void @sideeffect()
336 ; The invoked functions are different
337 define void @t6_different_invokes() personality ptr @__gxx_personality_v0 {
338 ; CHECK-LABEL: @t6_different_invokes(
340 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
341 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
348 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
349 ; CHECK-NEXT: cleanup
350 ; CHECK-NEXT: call void @destructor()
351 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
353 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
354 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
361 ; CHECK-NEXT: call void @sideeffect()
362 ; CHECK-NEXT: ret void
365 %c0 = call i1 @cond()
366 br i1 %c0, label %if.then0, label %if.else
369 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
375 %eh = landingpad { ptr, i32 } cleanup
376 call void @destructor()
377 resume { ptr, i32 } %eh
380 %c1 = call i1 @cond()
381 br i1 %c1, label %if.then1, label %if.end
384 invoke void @another_simple_throw() to label %invoke.cont2 unwind label %lpad
390 call void @sideeffect()
394 ; Merging of this invoke is disallowed
395 define void @t7_nomerge0() personality ptr @__gxx_personality_v0 {
396 ; CHECK-LABEL: @t7_nomerge0(
398 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
399 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
406 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
407 ; CHECK-NEXT: cleanup
408 ; CHECK-NEXT: call void @destructor()
409 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
411 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
412 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
419 ; CHECK-NEXT: call void @sideeffect()
420 ; CHECK-NEXT: ret void
423 %c0 = call i1 @cond()
424 br i1 %c0, label %if.then0, label %if.else
427 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
433 %eh = landingpad { ptr, i32 } cleanup
434 call void @destructor()
435 resume { ptr, i32 } %eh
438 %c1 = call i1 @cond()
439 br i1 %c1, label %if.then1, label %if.end
442 invoke void @simple_throw() nomerge to label %invoke.cont2 unwind label %lpad
448 call void @sideeffect()
451 define void @t8_nomerge1() personality ptr @__gxx_personality_v0 {
452 ; CHECK-LABEL: @t8_nomerge1(
454 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
455 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
462 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
463 ; CHECK-NEXT: cleanup
464 ; CHECK-NEXT: call void @destructor()
465 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
467 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
468 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
475 ; CHECK-NEXT: call void @sideeffect()
476 ; CHECK-NEXT: ret void
479 %c0 = call i1 @cond()
480 br i1 %c0, label %if.then0, label %if.else
483 invoke void @simple_throw() nomerge to label %invoke.cont0 unwind label %lpad
489 %eh = landingpad { ptr, i32 } cleanup
490 call void @destructor()
491 resume { ptr, i32 } %eh
494 %c1 = call i1 @cond()
495 br i1 %c1, label %if.then1, label %if.end
498 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
504 call void @sideeffect()
507 define void @t9_nomerge2() personality ptr @__gxx_personality_v0 {
508 ; CHECK-LABEL: @t9_nomerge2(
510 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
511 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
518 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
519 ; CHECK-NEXT: cleanup
520 ; CHECK-NEXT: call void @destructor()
521 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
523 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
524 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
531 ; CHECK-NEXT: call void @sideeffect()
532 ; CHECK-NEXT: ret void
535 %c0 = call i1 @cond()
536 br i1 %c0, label %if.then0, label %if.else
539 invoke void @simple_throw() nomerge to label %invoke.cont0 unwind label %lpad
545 %eh = landingpad { ptr, i32 } cleanup
546 call void @destructor()
547 resume { ptr, i32 } %eh
550 %c1 = call i1 @cond()
551 br i1 %c1, label %if.then1, label %if.end
554 invoke void @simple_throw() nomerge to label %invoke.cont2 unwind label %lpad
560 call void @sideeffect()
564 ; Just don't deal with inlineasm.
565 define void @t10_inlineasm() personality ptr @__gxx_personality_v0 {
566 ; CHECK-LABEL: @t10_inlineasm(
568 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
569 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
576 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
577 ; CHECK-NEXT: cleanup
578 ; CHECK-NEXT: call void @destructor()
579 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
581 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
582 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
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
589 ; CHECK-NEXT: call void @sideeffect()
590 ; CHECK-NEXT: ret void
593 %c0 = call i1 @cond()
594 br i1 %c0, label %if.then0, label %if.else
597 invoke void asm sideeffect "something bad", ""() to label %invoke.cont0 unwind label %lpad
603 %eh = landingpad { ptr, i32 } cleanup
604 call void @destructor()
605 resume { ptr, i32 } %eh
608 %c1 = call i1 @cond()
609 br i1 %c1, label %if.then1, label %if.end
612 invoke void asm sideeffect "something bad", ""() to label %invoke.cont2 unwind label %lpad
618 call void @sideeffect()
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: @t11_phi_in_landingpad_incompatible_incoming_values(
626 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
627 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
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
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]]
641 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
642 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
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
649 ; CHECK-NEXT: call void @sideeffect()
650 ; CHECK-NEXT: ret void
653 %c0 = call i1 @cond()
654 br i1 %c0, label %if.then0, label %if.else
657 invoke void @simple_throw() to label %invoke.cont0 unwind label %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
670 %c1 = call i1 @cond()
671 br i1 %c1, label %if.then1, label %if.end
674 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
680 call void @sideeffect()
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: @t12_arguments_are_fine(
688 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
689 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
691 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
692 ; CHECK-NEXT: cleanup
693 ; CHECK-NEXT: call void @destructor()
694 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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
704 ; CHECK-NEXT: call void @sideeffect()
705 ; CHECK-NEXT: ret void
708 %c0 = call i1 @cond()
709 br i1 %c0, label %if.then0, label %if.else
712 invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont0 unwind label %lpad
718 %eh = landingpad { ptr, i32 } cleanup
719 call void @destructor()
720 resume { ptr, i32 } %eh
723 %c1 = call i1 @cond()
724 br i1 %c1, label %if.then1, label %if.end
727 invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont2 unwind label %lpad
733 call void @sideeffect()
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: @t13_different_arguments_are_fine(
741 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
742 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
744 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
745 ; CHECK-NEXT: cleanup
746 ; CHECK-NEXT: call void @destructor()
747 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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
758 ; CHECK-NEXT: call void @sideeffect()
759 ; CHECK-NEXT: ret void
762 %c0 = call i1 @cond()
763 br i1 %c0, label %if.then0, label %if.else
766 invoke void @simple_throw_taking_argument(i32 0) to label %invoke.cont0 unwind label %lpad
772 %eh = landingpad { ptr, i32 } cleanup
773 call void @destructor()
774 resume { ptr, i32 } %eh
777 %c1 = call i1 @cond()
778 br i1 %c1, label %if.then1, label %if.end
781 invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont2 unwind label %lpad
787 call void @sideeffect()
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: @t14_three_invokes(
795 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
796 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN2_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
798 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
799 ; CHECK-NEXT: cleanup
800 ; CHECK-NEXT: call void @destructor()
801 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
803 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
804 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN2_INVOKE]], label [[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
814 ; CHECK-NEXT: call void @sideeffect()
815 ; CHECK-NEXT: ret void
818 %c0 = call i1 @cond()
819 br i1 %c0, label %if.then0, label %if.else0
822 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
828 %eh = landingpad { ptr, i32 } cleanup
829 call void @destructor()
830 resume { ptr, i32 } %eh
833 %c1 = call i1 @cond()
834 br i1 %c1, label %if.then1, label %if.else1
837 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
843 %c2 = call i1 @cond()
844 br i1 %c2, label %if.then2, label %if.end
847 invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
853 call void @sideeffect()
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: @t15_three_invokes_only_two_compatible(
861 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
862 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
864 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
865 ; CHECK-NEXT: cleanup
866 ; CHECK-NEXT: call void @destructor()
867 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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
877 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
878 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
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
885 ; CHECK-NEXT: call void @sideeffect()
886 ; CHECK-NEXT: ret void
889 %c0 = call i1 @cond()
890 br i1 %c0, label %if.then0, label %if.else0
893 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
899 %eh = landingpad { ptr, i32 } cleanup
900 call void @destructor()
901 resume { ptr, i32 } %eh
904 %c1 = call i1 @cond()
905 br i1 %c1, label %if.then1, label %if.else1
908 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
914 %c2 = call i1 @cond()
915 br i1 %c2, label %if.then2, label %if.end
918 invoke void @another_simple_throw() to label %invoke.cont3 unwind label %lpad
924 call void @sideeffect()
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: @t16_four_invokes_forming_two_sets(
932 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
933 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
935 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
936 ; CHECK-NEXT: cleanup
937 ; CHECK-NEXT: call void @destructor()
938 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
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
948 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
949 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN3_INVOKE:%.*]], label [[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
959 ; CHECK-NEXT: call void @sideeffect()
960 ; CHECK-NEXT: ret void
963 %c0 = call i1 @cond()
964 br i1 %c0, label %if.then0, label %if.else0
967 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
973 %eh = landingpad { ptr, i32 } cleanup
974 call void @destructor()
975 resume { ptr, i32 } %eh
978 %c1 = call i1 @cond()
979 br i1 %c1, label %if.then1, label %if.else1
982 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
988 %c2 = call i1 @cond()
989 br i1 %c2, label %if.then2, label %if.else2
992 invoke void @another_simple_throw() to label %invoke.cont3 unwind label %lpad
998 %c3 = call i1 @cond()
999 br i1 %c3, label %if.then3, label %if.end
1002 invoke void @another_simple_throw() to label %invoke.cont4 unwind label %lpad
1008 call void @sideeffect()
1012 ; Attributes must match
1013 define void @t17_mismatched_attrs_prevent_merge() personality ptr @__gxx_personality_v0 {
1014 ; CHECK-LABEL: @t17_mismatched_attrs_prevent_merge(
1015 ; CHECK-NEXT: entry:
1016 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1017 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
1019 ; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2:[0-9]+]]
1020 ; CHECK-NEXT: to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
1021 ; CHECK: invoke.cont0:
1022 ; CHECK-NEXT: unreachable
1024 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1025 ; CHECK-NEXT: cleanup
1026 ; CHECK-NEXT: call void @destructor()
1027 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1029 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1030 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
1032 ; CHECK-NEXT: invoke void @simple_throw()
1033 ; CHECK-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
1034 ; CHECK: invoke.cont2:
1035 ; CHECK-NEXT: unreachable
1037 ; CHECK-NEXT: call void @sideeffect()
1038 ; CHECK-NEXT: ret void
1041 %c0 = call i1 @cond()
1042 br i1 %c0, label %if.then0, label %if.else
1045 invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1051 %eh = landingpad { ptr, i32 } cleanup
1052 call void @destructor()
1053 resume { ptr, i32 } %eh
1056 %c1 = call i1 @cond()
1057 br i1 %c1, label %if.then1, label %if.end
1060 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1066 call void @sideeffect()
1070 ; Common attributes are preserved
1071 define void @t18_attributes_are_preserved() personality ptr @__gxx_personality_v0 {
1072 ; CHECK-LABEL: @t18_attributes_are_preserved(
1073 ; CHECK-NEXT: entry:
1074 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1075 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1077 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1078 ; CHECK-NEXT: cleanup
1079 ; CHECK-NEXT: call void @destructor()
1080 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1082 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1083 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1084 ; CHECK: if.then1.invoke:
1085 ; CHECK-NEXT: invoke void @simple_throw() #[[ATTR2]]
1086 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
1087 ; CHECK: if.then1.cont:
1088 ; CHECK-NEXT: unreachable
1090 ; CHECK-NEXT: call void @sideeffect()
1091 ; CHECK-NEXT: ret void
1094 %c0 = call i1 @cond()
1095 br i1 %c0, label %if.then0, label %if.else
1098 invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1104 %eh = landingpad { ptr, i32 } cleanup
1105 call void @destructor()
1106 resume { ptr, i32 } %eh
1109 %c1 = call i1 @cond()
1110 br i1 %c1, label %if.then1, label %if.end
1113 invoke void @simple_throw() readnone to label %invoke.cont2 unwind label %lpad
1119 call void @sideeffect()
1123 ; Fully identical operand bundles are good.
1124 define void @t19_compatible_operand_bundle() personality ptr @__gxx_personality_v0 {
1125 ; CHECK-LABEL: @t19_compatible_operand_bundle(
1126 ; CHECK-NEXT: entry:
1127 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1128 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1130 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1131 ; CHECK-NEXT: cleanup
1132 ; CHECK-NEXT: call void @destructor()
1133 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1135 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1136 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1137 ; CHECK: if.then1.invoke:
1138 ; CHECK-NEXT: invoke void @simple_throw() [ "abc"(i32 42) ]
1139 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
1140 ; CHECK: if.then1.cont:
1141 ; CHECK-NEXT: unreachable
1143 ; CHECK-NEXT: call void @sideeffect()
1144 ; CHECK-NEXT: ret void
1147 %c0 = call i1 @cond()
1148 br i1 %c0, label %if.then0, label %if.else
1151 invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad
1157 %eh = landingpad { ptr, i32 } cleanup
1158 call void @destructor()
1159 resume { ptr, i32 } %eh
1162 %c1 = call i1 @cond()
1163 br i1 %c1, label %if.then1, label %if.end
1166 invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont2 unwind label %lpad
1172 call void @sideeffect()
1176 ; Operand bundles must be compatible, else we can't merge.
1177 define void @t20_incompatible_operand_bundle() personality ptr @__gxx_personality_v0 {
1178 ; CHECK-LABEL: @t20_incompatible_operand_bundle(
1179 ; CHECK-NEXT: entry:
1180 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1181 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
1183 ; CHECK-NEXT: invoke void @simple_throw() [ "abc"(i32 42) ]
1184 ; CHECK-NEXT: to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
1185 ; CHECK: invoke.cont0:
1186 ; CHECK-NEXT: unreachable
1188 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1189 ; CHECK-NEXT: cleanup
1190 ; CHECK-NEXT: call void @destructor()
1191 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1193 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1194 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
1196 ; CHECK-NEXT: invoke void @simple_throw() [ "def"(i32 0) ]
1197 ; CHECK-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
1198 ; CHECK: invoke.cont2:
1199 ; CHECK-NEXT: unreachable
1201 ; CHECK-NEXT: call void @sideeffect()
1202 ; CHECK-NEXT: ret void
1205 %c0 = call i1 @cond()
1206 br i1 %c0, label %if.then0, label %if.else
1209 invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad
1215 %eh = landingpad { ptr, i32 } cleanup
1216 call void @destructor()
1217 resume { ptr, i32 } %eh
1220 %c1 = call i1 @cond()
1221 br i1 %c1, label %if.then1, label %if.end
1224 invoke void @simple_throw() [ "def"(i32 0) ] to label %invoke.cont2 unwind label %lpad
1230 call void @sideeffect()
1234 ; We need to PHI together the arguments of the operand bundles.
1235 define void @t21_semicompatible_operand_bundle(i32 %a, i32 %b) personality ptr @__gxx_personality_v0 {
1236 ; CHECK-LABEL: @t21_semicompatible_operand_bundle(
1237 ; CHECK-NEXT: entry:
1238 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1239 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1241 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1242 ; CHECK-NEXT: cleanup
1243 ; CHECK-NEXT: call void @destructor()
1244 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1246 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1247 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1248 ; CHECK: if.then1.invoke:
1249 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[B:%.*]], [[IF_ELSE]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
1250 ; CHECK-NEXT: invoke void @simple_throw() [ "abc"(i32 [[TMP0]]) ]
1251 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
1252 ; CHECK: if.then1.cont:
1253 ; CHECK-NEXT: unreachable
1255 ; CHECK-NEXT: call void @sideeffect()
1256 ; CHECK-NEXT: ret void
1259 %c0 = call i1 @cond()
1260 br i1 %c0, label %if.then0, label %if.else
1263 invoke void @simple_throw() [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
1269 %eh = landingpad { ptr, i32 } cleanup
1270 call void @destructor()
1271 resume { ptr, i32 } %eh
1274 %c1 = call i1 @cond()
1275 br i1 %c1, label %if.then1, label %if.end
1278 invoke void @simple_throw() [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
1284 call void @sideeffect()
1288 ; Even though the normal destinations are unreachable,
1289 ; they may have (dead) PHI nodes, so we must cleanup them.
1290 define void @t22_dead_phi_in_normal_dest() personality ptr @__gxx_personality_v0 {
1291 ; CHECK-LABEL: @t22_dead_phi_in_normal_dest(
1292 ; CHECK-NEXT: entry:
1293 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1294 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1296 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1297 ; CHECK-NEXT: cleanup
1298 ; CHECK-NEXT: call void @destructor()
1299 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1301 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1302 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1303 ; CHECK: if.then1.invoke:
1304 ; CHECK-NEXT: invoke void @maybe_throw()
1305 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
1306 ; CHECK: if.then1.cont:
1307 ; CHECK-NEXT: unreachable
1309 ; CHECK-NEXT: call void @sideeffect()
1310 ; CHECK-NEXT: ret void
1313 %c0 = call i1 @cond()
1314 br i1 %c0, label %if.then0, label %if.else
1317 invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1320 %eh = landingpad { ptr, i32 } cleanup
1321 call void @destructor()
1322 resume { ptr, i32 } %eh
1325 %c1 = call i1 @cond()
1326 br i1 %c1, label %if.then1, label %if.end
1329 invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1332 %deadphi0 = phi i32 [ 0, %if.then0 ]
1336 %deadphi2 = phi i32 [ 0, %if.then1 ]
1340 call void @sideeffect()
1344 ; landingpad has PHI nodes, and out of three invokes, only two have compatible incoming values.
1345 define void @t23_phi_in_landingpad_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1346 ; CHECK-LABEL: @t23_phi_in_landingpad_compatible_incoming_values(
1347 ; CHECK-NEXT: entry:
1348 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1349 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
1351 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ -1, [[IF_THEN2:%.*]] ], [ 0, [[IF_THEN1_INVOKE]] ]
1352 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1353 ; CHECK-NEXT: cleanup
1354 ; CHECK-NEXT: call void @consume(i32 [[PHI]])
1355 ; CHECK-NEXT: call void @destructor()
1356 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1358 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1359 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
1360 ; CHECK: if.then1.invoke:
1361 ; CHECK-NEXT: invoke void @simple_throw()
1362 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
1363 ; CHECK: if.then1.cont:
1364 ; CHECK-NEXT: unreachable
1366 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
1367 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
1369 ; CHECK-NEXT: invoke void @simple_throw()
1370 ; CHECK-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
1371 ; CHECK: invoke.cont3:
1372 ; CHECK-NEXT: unreachable
1374 ; CHECK-NEXT: call void @sideeffect()
1375 ; CHECK-NEXT: ret void
1378 %c0 = call i1 @cond()
1379 br i1 %c0, label %if.then0, label %if.else0
1382 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
1388 %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1389 %eh = landingpad { ptr, i32 } cleanup
1390 call void @consume(i32 %phi)
1391 call void @destructor()
1392 resume { ptr, i32 } %eh
1395 %c1 = call i1 @cond()
1396 br i1 %c1, label %if.then1, label %if.else1
1399 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1405 %c2 = call i1 @cond()
1406 br i1 %c2, label %if.then2, label %if.end
1409 invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
1415 call void @sideeffect()
1419 ; landingpad has two PHI nodes, but depending on which PHI you look,
1420 ; the invoke sets would be different, so we can't merge invokes here.
1421 define void @t24_phi_in_landingpad_semi_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1422 ; CHECK-LABEL: @t24_phi_in_landingpad_semi_compatible_incoming_values(
1423 ; CHECK-NEXT: entry:
1424 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1425 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE0:%.*]]
1427 ; CHECK-NEXT: invoke void @simple_throw()
1428 ; CHECK-NEXT: to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
1429 ; CHECK: invoke.cont0:
1430 ; CHECK-NEXT: unreachable
1432 ; CHECK-NEXT: [[PHI0:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ 0, [[IF_THEN1:%.*]] ], [ -1, [[IF_THEN2:%.*]] ]
1433 ; CHECK-NEXT: [[PHI1:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ 1, [[IF_THEN1]] ], [ 1, [[IF_THEN2]] ]
1434 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1435 ; CHECK-NEXT: cleanup
1436 ; CHECK-NEXT: call void @consume(i32 [[PHI0]])
1437 ; CHECK-NEXT: call void @consume(i32 [[PHI1]])
1438 ; CHECK-NEXT: call void @destructor()
1439 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1441 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1442 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1]], label [[IF_ELSE1:%.*]]
1444 ; CHECK-NEXT: invoke void @simple_throw()
1445 ; CHECK-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
1446 ; CHECK: invoke.cont2:
1447 ; CHECK-NEXT: unreachable
1449 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
1450 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
1452 ; CHECK-NEXT: invoke void @simple_throw()
1453 ; CHECK-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
1454 ; CHECK: invoke.cont3:
1455 ; CHECK-NEXT: unreachable
1457 ; CHECK-NEXT: call void @sideeffect()
1458 ; CHECK-NEXT: ret void
1461 %c0 = call i1 @cond()
1462 br i1 %c0, label %if.then0, label %if.else0
1465 invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
1471 %phi0 = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1472 %phi1= phi i32 [ 0, %if.then0 ], [ 1, %if.then1 ], [ 1, %if.then2 ]
1473 %eh = landingpad { ptr, i32 } cleanup
1474 call void @consume(i32 %phi0)
1475 call void @consume(i32 %phi1)
1476 call void @destructor()
1477 resume { ptr, i32 } %eh
1480 %c1 = call i1 @cond()
1481 br i1 %c1, label %if.then1, label %if.else1
1484 invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1490 %c2 = call i1 @cond()
1491 br i1 %c2, label %if.then2, label %if.end
1494 invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
1500 call void @sideeffect()
1504 ; The normal destinations are shared, but the incoming values are incompatible.
1505 define void @t25_incompatible_phis_in_normal_destination() personality ptr @__gxx_personality_v0 {
1506 ; CHECK-LABEL: @t25_incompatible_phis_in_normal_destination(
1507 ; CHECK-NEXT: entry:
1508 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1509 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
1511 ; CHECK-NEXT: invoke void @maybe_throw()
1512 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
1513 ; CHECK: invoke.cont:
1514 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ -1, [[IF_THEN1:%.*]] ]
1515 ; CHECK-NEXT: call void @consume(i32 [[PHI]])
1516 ; CHECK-NEXT: call void @sideeffect()
1517 ; CHECK-NEXT: unreachable
1519 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1520 ; CHECK-NEXT: cleanup
1521 ; CHECK-NEXT: call void @destructor()
1522 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1524 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1525 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
1527 ; CHECK-NEXT: invoke void @maybe_throw()
1528 ; CHECK-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD]]
1530 ; CHECK-NEXT: call void @sideeffect()
1531 ; CHECK-NEXT: ret void
1534 %c0 = call i1 @cond()
1535 br i1 %c0, label %if.then0, label %if.else
1538 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1541 %phi = phi i32 [ 0, %if.then0 ], [ -1, %if.then1 ]
1542 call void @consume(i32 %phi)
1543 call void @sideeffect()
1547 %eh = landingpad { ptr, i32 } cleanup
1548 call void @destructor()
1549 resume { ptr, i32 } %eh
1552 %c1 = call i1 @cond()
1553 br i1 %c1, label %if.then1, label %if.end
1556 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1559 call void @sideeffect()
1563 ; shared normal destination has PHI nodes, and out of three invokes, only two have compatible incoming values.
1564 define void @t26_phi_in_normal_dest_compatible_incoming_values() personality ptr @__gxx_personality_v0 {
1565 ; CHECK-LABEL: @t26_phi_in_normal_dest_compatible_incoming_values(
1566 ; CHECK-NEXT: entry:
1567 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1568 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
1569 ; CHECK: invoke.cont:
1570 ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ -1, [[IF_THEN2:%.*]] ], [ 0, [[IF_THEN1_INVOKE]] ]
1571 ; CHECK-NEXT: call void @consume(i32 [[PHI]])
1572 ; CHECK-NEXT: call void @sideeffect()
1573 ; CHECK-NEXT: unreachable
1575 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1576 ; CHECK-NEXT: cleanup
1577 ; CHECK-NEXT: call void @destructor()
1578 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1580 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1581 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
1582 ; CHECK: if.then1.invoke:
1583 ; CHECK-NEXT: invoke void @maybe_throw()
1584 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
1586 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
1587 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
1589 ; CHECK-NEXT: invoke void @maybe_throw()
1590 ; CHECK-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD]]
1592 ; CHECK-NEXT: call void @sideeffect()
1593 ; CHECK-NEXT: ret void
1596 %c0 = call i1 @cond()
1597 br i1 %c0, label %if.then0, label %if.else0
1600 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1603 %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1604 call void @consume(i32 %phi)
1605 call void @sideeffect()
1609 %eh = landingpad { ptr, i32 } cleanup
1610 call void @destructor()
1611 resume { ptr, i32 } %eh
1614 %c1 = call i1 @cond()
1615 br i1 %c1, label %if.then1, label %if.else1
1618 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1621 %c2 = call i1 @cond()
1622 br i1 %c2, label %if.then2, label %if.end
1625 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1628 call void @sideeffect()
1632 ; Invokes return values, but they are unused.
1633 define void @t27_invoke_ret_value_is_used() personality ptr @__gxx_personality_v0 {
1634 ; CHECK-LABEL: @t27_invoke_ret_value_is_used(
1635 ; CHECK-NEXT: entry:
1636 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1637 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1638 ; CHECK: invoke.cont:
1639 ; CHECK-NEXT: call void @sideeffect()
1640 ; CHECK-NEXT: unreachable
1642 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1643 ; CHECK-NEXT: cleanup
1644 ; CHECK-NEXT: call void @destructor()
1645 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1647 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1648 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1649 ; CHECK: if.then1.invoke:
1650 ; CHECK-NEXT: [[TMP0:%.*]] = invoke i32 @returning_maybe_throw()
1651 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
1653 ; CHECK-NEXT: call void @sideeffect()
1654 ; CHECK-NEXT: ret void
1657 %c0 = call i1 @cond()
1658 br i1 %c0, label %if.then0, label %if.else
1661 %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1664 call void @sideeffect()
1668 %eh = landingpad { ptr, i32 } cleanup
1669 call void @destructor()
1670 resume { ptr, i32 } %eh
1673 %c1 = call i1 @cond()
1674 br i1 %c1, label %if.then1, label %if.end
1677 %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1680 call void @sideeffect()
1684 ; Invokes return values, and they are used in a phi node, making the incoming values incompatible.
1685 define void @t28_invoke_ret_value_is_used_in_phi_node() personality ptr @__gxx_personality_v0 {
1686 ; CHECK-LABEL: @t28_invoke_ret_value_is_used_in_phi_node(
1687 ; CHECK-NEXT: entry:
1688 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1689 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1690 ; CHECK: invoke.cont:
1691 ; CHECK-NEXT: call void @consume(i32 [[TMP0:%.*]])
1692 ; CHECK-NEXT: call void @sideeffect()
1693 ; CHECK-NEXT: unreachable
1695 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1696 ; CHECK-NEXT: cleanup
1697 ; CHECK-NEXT: call void @destructor()
1698 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1700 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1701 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1702 ; CHECK: if.then1.invoke:
1703 ; CHECK-NEXT: [[TMP0]] = invoke i32 @returning_maybe_throw()
1704 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
1706 ; CHECK-NEXT: call void @sideeffect()
1707 ; CHECK-NEXT: ret void
1710 %c0 = call i1 @cond()
1711 br i1 %c0, label %if.then0, label %if.else
1714 %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1717 %phi = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
1718 call void @consume(i32 %phi)
1719 call void @sideeffect()
1723 %eh = landingpad { ptr, i32 } cleanup
1724 call void @destructor()
1725 resume { ptr, i32 } %eh
1728 %c1 = call i1 @cond()
1729 br i1 %c1, label %if.then1, label %if.end
1732 %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1735 call void @sideeffect()
1739 ; out of three invokes, two share normal destination and another one has unreachable destination
1740 define void @t29_common_normal_destination_and_unreachable_normal_destination() personality ptr @__gxx_personality_v0 {
1741 ; CHECK-LABEL: @t29_common_normal_destination_and_unreachable_normal_destination(
1742 ; CHECK-NEXT: entry:
1743 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1744 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
1745 ; CHECK: invoke.cont0:
1746 ; CHECK-NEXT: call void @sideeffect()
1747 ; CHECK-NEXT: unreachable
1749 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1750 ; CHECK-NEXT: cleanup
1751 ; CHECK-NEXT: call void @destructor()
1752 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1754 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1755 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
1756 ; CHECK: if.then1.invoke:
1757 ; CHECK-NEXT: invoke void @maybe_throw()
1758 ; CHECK-NEXT: to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
1760 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
1761 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
1763 ; CHECK-NEXT: invoke void @maybe_throw()
1764 ; CHECK-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
1765 ; CHECK: invoke.cont2:
1766 ; CHECK-NEXT: unreachable
1768 ; CHECK-NEXT: call void @sideeffect()
1769 ; CHECK-NEXT: ret void
1772 %c0 = call i1 @cond()
1773 br i1 %c0, label %if.then0, label %if.else0
1776 invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1779 call void @sideeffect()
1783 %eh = landingpad { ptr, i32 } cleanup
1784 call void @destructor()
1785 resume { ptr, i32 } %eh
1788 %c1 = call i1 @cond()
1789 br i1 %c1, label %if.then1, label %if.else1
1792 invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1795 %c2 = call i1 @cond()
1796 br i1 %c2, label %if.then2, label %if.end
1799 invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1805 call void @sideeffect()
1809 ; normal destinations are not unreachable and different but could be merged
1810 define void @t30_completely_different_normal_dests() personality ptr @__gxx_personality_v0 {
1811 ; CHECK-LABEL: @t30_completely_different_normal_dests(
1812 ; CHECK-NEXT: entry:
1813 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1814 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
1816 ; CHECK-NEXT: invoke void @maybe_throw()
1817 ; CHECK-NEXT: to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
1818 ; CHECK: invoke.cont0:
1819 ; CHECK-NEXT: call void @sideeffect()
1820 ; CHECK-NEXT: unreachable
1822 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1823 ; CHECK-NEXT: cleanup
1824 ; CHECK-NEXT: call void @destructor()
1825 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1827 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1828 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
1830 ; CHECK-NEXT: invoke void @maybe_throw()
1831 ; CHECK-NEXT: to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
1832 ; CHECK: invoke.cont2:
1833 ; CHECK-NEXT: call void @sideeffect()
1834 ; CHECK-NEXT: unreachable
1836 ; CHECK-NEXT: call void @sideeffect()
1837 ; CHECK-NEXT: ret void
1840 %c0 = call i1 @cond()
1841 br i1 %c0, label %if.then0, label %if.else
1844 invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1847 call void @sideeffect()
1851 %eh = landingpad { ptr, i32 } cleanup
1852 call void @destructor()
1853 resume { ptr, i32 } %eh
1856 %c1 = call i1 @cond()
1857 br i1 %c1, label %if.then1, label %if.end
1860 invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1863 call void @sideeffect()
1867 call void @sideeffect()
1871 ; Even though the normal destinations are unreachable,
1872 ; they may have (dead) PHI nodes with incompatible incoming values,
1873 ; so we must cleanup them.
1874 define void @t31_incompatible_dead_phi_in_normal_dest() personality ptr @__gxx_personality_v0 {
1875 ; CHECK-LABEL: @t31_incompatible_dead_phi_in_normal_dest(
1876 ; CHECK-NEXT: entry:
1877 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1878 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1880 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1881 ; CHECK-NEXT: cleanup
1882 ; CHECK-NEXT: call void @destructor()
1883 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1885 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1886 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1887 ; CHECK: if.then1.invoke:
1888 ; CHECK-NEXT: invoke void @maybe_throw()
1889 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
1890 ; CHECK: if.then1.cont:
1891 ; CHECK-NEXT: unreachable
1893 ; CHECK-NEXT: call void @sideeffect()
1894 ; CHECK-NEXT: ret void
1897 %c0 = call i1 @cond()
1898 br i1 %c0, label %if.then0, label %if.else
1901 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1904 %eh = landingpad { ptr, i32 } cleanup
1905 call void @destructor()
1906 resume { ptr, i32 } %eh
1909 %c1 = call i1 @cond()
1910 br i1 %c1, label %if.then1, label %if.end
1913 invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1916 %deadphi0 = phi i32 [ 0, %if.then0 ], [ -1, %if.then1 ]
1920 call void @sideeffect()
1924 ; Invokes return values, and they are used in a phi node, making the incoming values incompatible,
1925 ; second phi has compatible incoming values
1926 define void @t32_invoke_ret_value_is_used_in_phi_node_other_phi_is_fine() personality ptr @__gxx_personality_v0 {
1927 ; CHECK-LABEL: @t32_invoke_ret_value_is_used_in_phi_node_other_phi_is_fine(
1928 ; CHECK-NEXT: entry:
1929 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1930 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
1931 ; CHECK: invoke.cont:
1932 ; CHECK-NEXT: call void @consume(i32 [[TMP0:%.*]])
1933 ; CHECK-NEXT: call void @consume(i32 0)
1934 ; CHECK-NEXT: call void @sideeffect()
1935 ; CHECK-NEXT: unreachable
1937 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
1938 ; CHECK-NEXT: cleanup
1939 ; CHECK-NEXT: call void @destructor()
1940 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
1942 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
1943 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
1944 ; CHECK: if.then1.invoke:
1945 ; CHECK-NEXT: [[TMP0]] = invoke i32 @returning_maybe_throw()
1946 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
1948 ; CHECK-NEXT: call void @sideeffect()
1949 ; CHECK-NEXT: ret void
1952 %c0 = call i1 @cond()
1953 br i1 %c0, label %if.then0, label %if.else
1956 %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1959 %phi0 = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
1960 %phi1 = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ]
1961 call void @consume(i32 %phi0)
1962 call void @consume(i32 %phi1)
1963 call void @sideeffect()
1967 %eh = landingpad { ptr, i32 } cleanup
1968 call void @destructor()
1969 resume { ptr, i32 } %eh
1972 %c1 = call i1 @cond()
1973 br i1 %c1, label %if.then1, label %if.end
1976 %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1979 call void @sideeffect()
1983 ; Invokes return values, and they are used in a phi node, making the incoming values incompatible,
1984 ; second phi has incompatible incoming values.
1985 define void @t33_invoke_ret_value_is_used_in_phi_node_other_phi_is_bad() personality ptr @__gxx_personality_v0 {
1986 ; CHECK-LABEL: @t33_invoke_ret_value_is_used_in_phi_node_other_phi_is_bad(
1987 ; CHECK-NEXT: entry:
1988 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
1989 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
1991 ; CHECK-NEXT: [[V0:%.*]] = invoke i32 @returning_maybe_throw()
1992 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
1993 ; CHECK: invoke.cont:
1994 ; CHECK-NEXT: [[PHI0:%.*]] = phi i32 [ [[V0]], [[IF_THEN0]] ], [ [[V1:%.*]], [[IF_THEN1:%.*]] ]
1995 ; CHECK-NEXT: [[PHI1:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ -1, [[IF_THEN1]] ]
1996 ; CHECK-NEXT: call void @consume(i32 [[PHI0]])
1997 ; CHECK-NEXT: call void @consume(i32 [[PHI1]])
1998 ; CHECK-NEXT: call void @sideeffect()
1999 ; CHECK-NEXT: unreachable
2001 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2002 ; CHECK-NEXT: cleanup
2003 ; CHECK-NEXT: call void @destructor()
2004 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2006 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2007 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
2009 ; CHECK-NEXT: [[V1]] = invoke i32 @returning_maybe_throw()
2010 ; CHECK-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD]]
2012 ; CHECK-NEXT: call void @sideeffect()
2013 ; CHECK-NEXT: ret void
2016 %c0 = call i1 @cond()
2017 br i1 %c0, label %if.then0, label %if.else
2020 %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2023 %phi0 = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
2024 %phi1 = phi i32 [ 0, %if.then0 ], [ -1, %if.then1 ]
2025 call void @consume(i32 %phi0)
2026 call void @consume(i32 %phi1)
2027 call void @sideeffect()
2031 %eh = landingpad { ptr, i32 } cleanup
2032 call void @destructor()
2033 resume { ptr, i32 } %eh
2036 %c1 = call i1 @cond()
2037 br i1 %c1, label %if.then1, label %if.end
2040 %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2043 call void @sideeffect()
2047 ; Invokes return values, and they are used in a phi node, but when coming from different invokes,
2048 ; the incoming value isn't always the invoke, which is not okay.
2049 define void @t34_invoke_ret_value_maybe_incompatibly_used_in_phi_node() personality ptr @__gxx_personality_v0 {
2050 ; CHECK-LABEL: @t34_invoke_ret_value_maybe_incompatibly_used_in_phi_node(
2051 ; CHECK-NEXT: entry:
2052 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2053 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
2055 ; CHECK-NEXT: [[V0:%.*]] = invoke i32 @returning_maybe_throw()
2056 ; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
2057 ; CHECK: invoke.cont:
2058 ; CHECK-NEXT: [[PHI0:%.*]] = phi i32 [ [[V0]], [[IF_THEN0]] ], [ 0, [[IF_THEN1:%.*]] ]
2059 ; CHECK-NEXT: [[PHI1:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ [[V1:%.*]], [[IF_THEN1]] ]
2060 ; CHECK-NEXT: call void @consume(i32 [[PHI0]])
2061 ; CHECK-NEXT: call void @consume(i32 [[PHI1]])
2062 ; CHECK-NEXT: call void @sideeffect()
2063 ; CHECK-NEXT: unreachable
2065 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2066 ; CHECK-NEXT: cleanup
2067 ; CHECK-NEXT: call void @destructor()
2068 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2070 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2071 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
2073 ; CHECK-NEXT: [[V1]] = invoke i32 @returning_maybe_throw()
2074 ; CHECK-NEXT: to label [[INVOKE_CONT]] unwind label [[LPAD]]
2076 ; CHECK-NEXT: call void @sideeffect()
2077 ; CHECK-NEXT: ret void
2080 %c0 = call i1 @cond()
2081 br i1 %c0, label %if.then0, label %if.else
2084 %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2087 %phi0 = phi i32 [ %v0, %if.then0 ], [ 0, %if.then1 ]
2088 %phi1 = phi i32 [ 0, %if.then0 ], [ %v1, %if.then1 ]
2089 call void @consume(i32 %phi0)
2090 call void @consume(i32 %phi1)
2091 call void @sideeffect()
2095 %eh = landingpad { ptr, i32 } cleanup
2096 call void @destructor()
2097 resume { ptr, i32 } %eh
2100 %c1 = call i1 @cond()
2101 br i1 %c1, label %if.then1, label %if.end
2104 %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2107 call void @sideeffect()
2111 ; Two mergeable indirect calls, with identical callees.
2112 define void @t35_identical_indirect_callees(ptr %callee) personality ptr @__gxx_personality_v0 {
2113 ; CHECK-LABEL: @t35_identical_indirect_callees(
2114 ; CHECK-NEXT: entry:
2115 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2116 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
2118 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2119 ; CHECK-NEXT: cleanup
2120 ; CHECK-NEXT: call void @destructor()
2121 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2123 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2124 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
2125 ; CHECK: if.then1.invoke:
2126 ; CHECK-NEXT: invoke void [[CALLEE:%.*]]()
2127 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
2128 ; CHECK: if.then1.cont:
2129 ; CHECK-NEXT: unreachable
2131 ; CHECK-NEXT: call void @sideeffect()
2132 ; CHECK-NEXT: ret void
2135 %c0 = call i1 @cond()
2136 br i1 %c0, label %if.then0, label %if.else
2139 invoke void %callee() to label %invoke.cont0 unwind label %lpad
2145 %eh = landingpad { ptr, i32 } cleanup
2146 call void @destructor()
2147 resume { ptr, i32 } %eh
2150 %c1 = call i1 @cond()
2151 br i1 %c1, label %if.then1, label %if.end
2154 invoke void %callee() to label %invoke.cont2 unwind label %lpad
2160 call void @sideeffect()
2164 ; Two mergeable indirect calls, with different callees.
2165 define void @t36_different_indirect_callees(ptr %callee0, ptr %callee1) personality ptr @__gxx_personality_v0 {
2166 ; CHECK-LABEL: @t36_different_indirect_callees(
2167 ; CHECK-NEXT: entry:
2168 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2169 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
2171 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2172 ; CHECK-NEXT: cleanup
2173 ; CHECK-NEXT: call void @destructor()
2174 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2176 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2177 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
2178 ; CHECK: if.then1.invoke:
2179 ; CHECK-NEXT: [[TMP0:%.*]] = phi ptr [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY:%.*]] ]
2180 ; CHECK-NEXT: invoke void [[TMP0]]()
2181 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
2182 ; CHECK: if.then1.cont:
2183 ; CHECK-NEXT: unreachable
2185 ; CHECK-NEXT: call void @sideeffect()
2186 ; CHECK-NEXT: ret void
2189 %c0 = call i1 @cond()
2190 br i1 %c0, label %if.then0, label %if.else
2193 invoke void %callee0() to label %invoke.cont0 unwind label %lpad
2199 %eh = landingpad { ptr, i32 } cleanup
2200 call void @destructor()
2201 resume { ptr, i32 } %eh
2204 %c1 = call i1 @cond()
2205 br i1 %c1, label %if.then1, label %if.end
2208 invoke void %callee1() to label %invoke.cont2 unwind label %lpad
2214 call void @sideeffect()
2218 ; Don't merge direct invoke with indirect ones.
2219 define void @t37_three_invokes_two_indirect_one_direct(ptr %callee) personality ptr @__gxx_personality_v0 {
2220 ; CHECK-LABEL: @t37_three_invokes_two_indirect_one_direct(
2221 ; CHECK-NEXT: entry:
2222 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2223 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
2225 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2226 ; CHECK-NEXT: cleanup
2227 ; CHECK-NEXT: call void @destructor()
2228 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2230 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2231 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
2232 ; CHECK: if.then1.invoke:
2233 ; CHECK-NEXT: invoke void [[CALLEE:%.*]]()
2234 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
2235 ; CHECK: if.then1.cont:
2236 ; CHECK-NEXT: unreachable
2238 ; CHECK-NEXT: [[C2:%.*]] = call i1 @cond()
2239 ; CHECK-NEXT: br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
2241 ; CHECK-NEXT: invoke void @simple_throw()
2242 ; CHECK-NEXT: to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
2243 ; CHECK: invoke.cont3:
2244 ; CHECK-NEXT: unreachable
2246 ; CHECK-NEXT: call void @sideeffect()
2247 ; CHECK-NEXT: ret void
2250 %c0 = call i1 @cond()
2251 br i1 %c0, label %if.then0, label %if.else0
2254 invoke void %callee() to label %invoke.cont0 unwind label %lpad
2260 %eh = landingpad { ptr, i32 } cleanup
2261 call void @destructor()
2262 resume { ptr, i32 } %eh
2265 %c1 = call i1 @cond()
2266 br i1 %c1, label %if.then1, label %if.else1
2269 invoke void %callee() to label %invoke.cont2 unwind label %lpad
2275 %c2 = call i1 @cond()
2276 br i1 %c2, label %if.then2, label %if.end
2279 invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
2285 call void @sideeffect()
2289 ; For indirect invokes, different arguments are fine.
2290 define void @t38_different_arguments_and_operand_bundes_are_fine(ptr %callee0, ptr %callee1) personality ptr @__gxx_personality_v0 {
2291 ; CHECK-LABEL: @t38_different_arguments_and_operand_bundes_are_fine(
2292 ; CHECK-NEXT: entry:
2293 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2294 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
2296 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2297 ; CHECK-NEXT: cleanup
2298 ; CHECK-NEXT: call void @destructor()
2299 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2301 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2302 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
2303 ; CHECK: if.then1.invoke:
2304 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 42, [[IF_ELSE]] ], [ 0, [[ENTRY:%.*]] ]
2305 ; CHECK-NEXT: [[TMP1:%.*]] = phi ptr [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY]] ]
2306 ; CHECK-NEXT: invoke void [[TMP1]](i32 [[TMP0]])
2307 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
2308 ; CHECK: if.then1.cont:
2309 ; CHECK-NEXT: unreachable
2311 ; CHECK-NEXT: call void @sideeffect()
2312 ; CHECK-NEXT: ret void
2315 %c0 = call i1 @cond()
2316 br i1 %c0, label %if.then0, label %if.else
2319 invoke void %callee0(i32 0) to label %invoke.cont0 unwind label %lpad
2325 %eh = landingpad { ptr, i32 } cleanup
2326 call void @destructor()
2327 resume { ptr, i32 } %eh
2330 %c1 = call i1 @cond()
2331 br i1 %c1, label %if.then1, label %if.end
2334 invoke void %callee1(i32 42) to label %invoke.cont2 unwind label %lpad
2340 call void @sideeffect()
2344 ; For indirect invokes, different operand bundle arguments are fine.
2345 define void @t39_different_arguments_and_operand_bundes_are_fine(ptr %callee0, ptr %callee1, i32 %a, i32 %b) personality ptr @__gxx_personality_v0 {
2346 ; CHECK-LABEL: @t39_different_arguments_and_operand_bundes_are_fine(
2347 ; CHECK-NEXT: entry:
2348 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2349 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
2351 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2352 ; CHECK-NEXT: cleanup
2353 ; CHECK-NEXT: call void @destructor()
2354 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2356 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2357 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
2358 ; CHECK: if.then1.invoke:
2359 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[B:%.*]], [[IF_ELSE]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
2360 ; CHECK-NEXT: [[TMP1:%.*]] = phi ptr [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY]] ]
2361 ; CHECK-NEXT: invoke void [[TMP1]]() [ "abc"(i32 [[TMP0]]) ]
2362 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
2363 ; CHECK: if.then1.cont:
2364 ; CHECK-NEXT: unreachable
2366 ; CHECK-NEXT: call void @sideeffect()
2367 ; CHECK-NEXT: ret void
2370 %c0 = call i1 @cond()
2371 br i1 %c0, label %if.then0, label %if.else
2374 invoke void %callee0() [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
2380 %eh = landingpad { ptr, i32 } cleanup
2381 call void @destructor()
2382 resume { ptr, i32 } %eh
2385 %c1 = call i1 @cond()
2386 br i1 %c1, label %if.then1, label %if.end
2389 invoke void %callee1() [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
2395 call void @sideeffect()
2399 ; For indirect invokes, both different arguments and operand bundle arguments are fine.
2400 define void @t40_different_arguments_and_operand_bundes_are_fine(ptr %callee0, ptr %callee1, i32 %a, i32 %b) personality ptr @__gxx_personality_v0 {
2401 ; CHECK-LABEL: @t40_different_arguments_and_operand_bundes_are_fine(
2402 ; CHECK-NEXT: entry:
2403 ; CHECK-NEXT: [[C0:%.*]] = call i1 @cond()
2404 ; CHECK-NEXT: br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
2406 ; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 }
2407 ; CHECK-NEXT: cleanup
2408 ; CHECK-NEXT: call void @destructor()
2409 ; CHECK-NEXT: resume { ptr, i32 } [[EH]]
2411 ; CHECK-NEXT: [[C1:%.*]] = call i1 @cond()
2412 ; CHECK-NEXT: br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
2413 ; CHECK: if.then1.invoke:
2414 ; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ 42, [[IF_ELSE]] ], [ 0, [[ENTRY:%.*]] ]
2415 ; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[B:%.*]], [[IF_ELSE]] ], [ [[A:%.*]], [[ENTRY]] ]
2416 ; CHECK-NEXT: [[TMP2:%.*]] = phi ptr [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY]] ]
2417 ; CHECK-NEXT: invoke void [[TMP2]](i32 [[TMP0]]) [ "abc"(i32 [[TMP1]]) ]
2418 ; CHECK-NEXT: to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
2419 ; CHECK: if.then1.cont:
2420 ; CHECK-NEXT: unreachable
2422 ; CHECK-NEXT: call void @sideeffect()
2423 ; CHECK-NEXT: ret void
2426 %c0 = call i1 @cond()
2427 br i1 %c0, label %if.then0, label %if.else
2430 invoke void %callee0(i32 0) [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
2436 %eh = landingpad { ptr, i32 } cleanup
2437 call void @destructor()
2438 resume { ptr, i32 } %eh
2441 %c1 = call i1 @cond()
2442 br i1 %c1, label %if.then1, label %if.end
2445 invoke void %callee1(i32 42) [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
2451 call void @sideeffect()
2455 define void @dont_merge_different_immargs(i1 %c1) gc "statepoint-example" personality ptr null {
2456 ; CHECK-LABEL: @dont_merge_different_immargs(
2457 ; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
2459 ; 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)
2460 ; CHECK-NEXT: to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]
2462 ; 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)
2463 ; CHECK-NEXT: to label [[UNREACHABLE]] unwind label [[LPAD]]
2464 ; CHECK: unreachable:
2465 ; CHECK-NEXT: unreachable
2467 ; CHECK-NEXT: [[T3:%.*]] = landingpad token
2468 ; CHECK-NEXT: cleanup
2469 ; CHECK-NEXT: ret void
2471 br i1 %c1, label %if, label %else
2474 %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)
2475 to label %unreachable unwind label %lpad
2478 %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)
2479 to label %unreachable unwind label %lpad
2485 %t3 = landingpad token
2490 declare token @llvm.experimental.gc.statepoint.p0(i64 immarg, i32 immarg, ptr, i32 immarg, i32 immarg, ...)
2494 declare void @sideeffect()
2495 declare void @another_sideeffect()
2497 declare void @maybe_throw()
2499 declare void @simple_throw() noreturn
2500 declare void @another_simple_throw() noreturn
2502 declare void @simple_throw_taking_argument(i32) noreturn
2504 declare i32 @returning_maybe_throw()
2506 declare void @destructor()
2507 declare void @another_destructor()
2509 declare void @consume(i32)
2511 declare dso_local i32 @__gxx_personality_v0(...)
2513 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn }
2514 ; CHECK: attributes #[[ATTR1]] = { nomerge }
2515 ; CHECK: attributes #[[ATTR2]] = { memory(none) }