[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / X86 / merge-compatible-invokes-of-landingpad.ll
blob276aa83b032677fa584dd61492039b1f682de3e3
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(
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: @t1_mergeable_invoke(
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: @t2_shared_normal_dest(
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: @t3_shared_identical_normal_dest(
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: @t4_normal_dests(
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: @t5_different_landingpads(
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: @t6_different_invokes(
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: @t7_nomerge0(
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: @t8_nomerge1(
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: @t9_nomerge2(
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: @t10_inlineasm(
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: @t11_phi_in_landingpad_incompatible_incoming_values(
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: @t12_arguments_are_fine(
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: @t13_different_arguments_are_fine(
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: @t14_three_invokes(
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: @t15_three_invokes_only_two_compatible(
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: @t16_four_invokes_forming_two_sets(
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 ; 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:%.*]]
1018 ; CHECK:       if.then0:
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
1023 ; CHECK:       lpad:
1024 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1025 ; CHECK-NEXT:    cleanup
1026 ; CHECK-NEXT:    call void @destructor()
1027 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1028 ; CHECK:       if.else:
1029 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1030 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
1031 ; CHECK:       if.then1:
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
1036 ; CHECK:       if.end:
1037 ; CHECK-NEXT:    call void @sideeffect()
1038 ; CHECK-NEXT:    ret void
1040 entry:
1041   %c0 = call i1 @cond()
1042   br i1 %c0, label %if.then0, label %if.else
1044 if.then0:
1045   invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1047 invoke.cont0:
1048   unreachable
1050 lpad:
1051   %eh = landingpad { ptr, i32 } cleanup
1052   call void @destructor()
1053   resume { ptr, i32 } %eh
1055 if.else:
1056   %c1 = call i1 @cond()
1057   br i1 %c1, label %if.then1, label %if.end
1059 if.then1:
1060   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1062 invoke.cont2:
1063   unreachable
1065 if.end:
1066   call void @sideeffect()
1067   ret void
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:%.*]]
1076 ; CHECK:       lpad:
1077 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1078 ; CHECK-NEXT:    cleanup
1079 ; CHECK-NEXT:    call void @destructor()
1080 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1081 ; CHECK:       if.else:
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
1089 ; CHECK:       if.end:
1090 ; CHECK-NEXT:    call void @sideeffect()
1091 ; CHECK-NEXT:    ret void
1093 entry:
1094   %c0 = call i1 @cond()
1095   br i1 %c0, label %if.then0, label %if.else
1097 if.then0:
1098   invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad
1100 invoke.cont0:
1101   unreachable
1103 lpad:
1104   %eh = landingpad { ptr, i32 } cleanup
1105   call void @destructor()
1106   resume { ptr, i32 } %eh
1108 if.else:
1109   %c1 = call i1 @cond()
1110   br i1 %c1, label %if.then1, label %if.end
1112 if.then1:
1113   invoke void @simple_throw() readnone to label %invoke.cont2 unwind label %lpad
1115 invoke.cont2:
1116   unreachable
1118 if.end:
1119   call void @sideeffect()
1120   ret void
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:%.*]]
1129 ; CHECK:       lpad:
1130 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1131 ; CHECK-NEXT:    cleanup
1132 ; CHECK-NEXT:    call void @destructor()
1133 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1134 ; CHECK:       if.else:
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
1142 ; CHECK:       if.end:
1143 ; CHECK-NEXT:    call void @sideeffect()
1144 ; CHECK-NEXT:    ret void
1146 entry:
1147   %c0 = call i1 @cond()
1148   br i1 %c0, label %if.then0, label %if.else
1150 if.then0:
1151   invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad
1153 invoke.cont0:
1154   unreachable
1156 lpad:
1157   %eh = landingpad { ptr, i32 } cleanup
1158   call void @destructor()
1159   resume { ptr, i32 } %eh
1161 if.else:
1162   %c1 = call i1 @cond()
1163   br i1 %c1, label %if.then1, label %if.end
1165 if.then1:
1166   invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont2 unwind label %lpad
1168 invoke.cont2:
1169   unreachable
1171 if.end:
1172   call void @sideeffect()
1173   ret void
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:%.*]]
1182 ; CHECK:       if.then0:
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
1187 ; CHECK:       lpad:
1188 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1189 ; CHECK-NEXT:    cleanup
1190 ; CHECK-NEXT:    call void @destructor()
1191 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1192 ; CHECK:       if.else:
1193 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1194 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
1195 ; CHECK:       if.then1:
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
1200 ; CHECK:       if.end:
1201 ; CHECK-NEXT:    call void @sideeffect()
1202 ; CHECK-NEXT:    ret void
1204 entry:
1205   %c0 = call i1 @cond()
1206   br i1 %c0, label %if.then0, label %if.else
1208 if.then0:
1209   invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad
1211 invoke.cont0:
1212   unreachable
1214 lpad:
1215   %eh = landingpad { ptr, i32 } cleanup
1216   call void @destructor()
1217   resume { ptr, i32 } %eh
1219 if.else:
1220   %c1 = call i1 @cond()
1221   br i1 %c1, label %if.then1, label %if.end
1223 if.then1:
1224   invoke void @simple_throw() [ "def"(i32 0) ] to label %invoke.cont2 unwind label %lpad
1226 invoke.cont2:
1227   unreachable
1229 if.end:
1230   call void @sideeffect()
1231   ret void
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:%.*]]
1240 ; CHECK:       lpad:
1241 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1242 ; CHECK-NEXT:    cleanup
1243 ; CHECK-NEXT:    call void @destructor()
1244 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1245 ; CHECK:       if.else:
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
1254 ; CHECK:       if.end:
1255 ; CHECK-NEXT:    call void @sideeffect()
1256 ; CHECK-NEXT:    ret void
1258 entry:
1259   %c0 = call i1 @cond()
1260   br i1 %c0, label %if.then0, label %if.else
1262 if.then0:
1263   invoke void @simple_throw() [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
1265 invoke.cont0:
1266   unreachable
1268 lpad:
1269   %eh = landingpad { ptr, i32 } cleanup
1270   call void @destructor()
1271   resume { ptr, i32 } %eh
1273 if.else:
1274   %c1 = call i1 @cond()
1275   br i1 %c1, label %if.then1, label %if.end
1277 if.then1:
1278   invoke void @simple_throw() [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
1280 invoke.cont2:
1281   unreachable
1283 if.end:
1284   call void @sideeffect()
1285   ret void
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:%.*]]
1295 ; CHECK:       lpad:
1296 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1297 ; CHECK-NEXT:    cleanup
1298 ; CHECK-NEXT:    call void @destructor()
1299 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1300 ; CHECK:       if.else:
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
1308 ; CHECK:       if.end:
1309 ; CHECK-NEXT:    call void @sideeffect()
1310 ; CHECK-NEXT:    ret void
1312 entry:
1313   %c0 = call i1 @cond()
1314   br i1 %c0, label %if.then0, label %if.else
1316 if.then0:
1317   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1319 lpad:
1320   %eh = landingpad { ptr, i32 } cleanup
1321   call void @destructor()
1322   resume { ptr, i32 } %eh
1324 if.else:
1325   %c1 = call i1 @cond()
1326   br i1 %c1, label %if.then1, label %if.end
1328 if.then1:
1329   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1331 invoke.cont0:
1332   %deadphi0 = phi i32 [ 0, %if.then0 ]
1333   unreachable
1335 invoke.cont2:
1336   %deadphi2 = phi i32 [ 0, %if.then1 ]
1337   unreachable
1339 if.end:
1340   call void @sideeffect()
1341   ret void
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:%.*]]
1350 ; CHECK:       lpad:
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]]
1357 ; CHECK:       if.else0:
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
1365 ; CHECK:       if.else1:
1366 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1367 ; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
1368 ; CHECK:       if.then2:
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
1373 ; CHECK:       if.end:
1374 ; CHECK-NEXT:    call void @sideeffect()
1375 ; CHECK-NEXT:    ret void
1377 entry:
1378   %c0 = call i1 @cond()
1379   br i1 %c0, label %if.then0, label %if.else0
1381 if.then0:
1382   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
1384 invoke.cont0:
1385   unreachable
1387 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
1394 if.else0:
1395   %c1 = call i1 @cond()
1396   br i1 %c1, label %if.then1, label %if.else1
1398 if.then1:
1399   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1401 invoke.cont2:
1402   unreachable
1404 if.else1:
1405   %c2 = call i1 @cond()
1406   br i1 %c2, label %if.then2, label %if.end
1408 if.then2:
1409   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
1411 invoke.cont3:
1412   unreachable
1414 if.end:
1415   call void @sideeffect()
1416   ret void
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:%.*]]
1426 ; CHECK:       if.then0:
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
1431 ; CHECK:       lpad:
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]]
1440 ; CHECK:       if.else0:
1441 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1442 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_ELSE1:%.*]]
1443 ; CHECK:       if.then1:
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
1448 ; CHECK:       if.else1:
1449 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1450 ; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
1451 ; CHECK:       if.then2:
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
1456 ; CHECK:       if.end:
1457 ; CHECK-NEXT:    call void @sideeffect()
1458 ; CHECK-NEXT:    ret void
1460 entry:
1461   %c0 = call i1 @cond()
1462   br i1 %c0, label %if.then0, label %if.else0
1464 if.then0:
1465   invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad
1467 invoke.cont0:
1468   unreachable
1470 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
1479 if.else0:
1480   %c1 = call i1 @cond()
1481   br i1 %c1, label %if.then1, label %if.else1
1483 if.then1:
1484   invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad
1486 invoke.cont2:
1487   unreachable
1489 if.else1:
1490   %c2 = call i1 @cond()
1491   br i1 %c2, label %if.then2, label %if.end
1493 if.then2:
1494   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
1496 invoke.cont3:
1497   unreachable
1499 if.end:
1500   call void @sideeffect()
1501   ret void
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:%.*]]
1510 ; CHECK:       if.then0:
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
1518 ; CHECK:       lpad:
1519 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1520 ; CHECK-NEXT:    cleanup
1521 ; CHECK-NEXT:    call void @destructor()
1522 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1523 ; CHECK:       if.else:
1524 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1525 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
1526 ; CHECK:       if.then1:
1527 ; CHECK-NEXT:    invoke void @maybe_throw()
1528 ; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
1529 ; CHECK:       if.end:
1530 ; CHECK-NEXT:    call void @sideeffect()
1531 ; CHECK-NEXT:    ret void
1533 entry:
1534   %c0 = call i1 @cond()
1535   br i1 %c0, label %if.then0, label %if.else
1537 if.then0:
1538   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1540 invoke.cont:
1541   %phi = phi i32 [ 0, %if.then0 ], [ -1, %if.then1 ]
1542   call void @consume(i32 %phi)
1543   call void @sideeffect()
1544   unreachable
1546 lpad:
1547   %eh = landingpad { ptr, i32 } cleanup
1548   call void @destructor()
1549   resume { ptr, i32 } %eh
1551 if.else:
1552   %c1 = call i1 @cond()
1553   br i1 %c1, label %if.then1, label %if.end
1555 if.then1:
1556   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1558 if.end:
1559   call void @sideeffect()
1560   ret void
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
1574 ; CHECK:       lpad:
1575 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1576 ; CHECK-NEXT:    cleanup
1577 ; CHECK-NEXT:    call void @destructor()
1578 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1579 ; CHECK:       if.else0:
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:%.*]]
1585 ; CHECK:       if.else1:
1586 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1587 ; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
1588 ; CHECK:       if.then2:
1589 ; CHECK-NEXT:    invoke void @maybe_throw()
1590 ; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
1591 ; CHECK:       if.end:
1592 ; CHECK-NEXT:    call void @sideeffect()
1593 ; CHECK-NEXT:    ret void
1595 entry:
1596   %c0 = call i1 @cond()
1597   br i1 %c0, label %if.then0, label %if.else0
1599 if.then0:
1600   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1602 invoke.cont:
1603   %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
1604   call void @consume(i32 %phi)
1605   call void @sideeffect()
1606   unreachable
1608 lpad:
1609   %eh = landingpad { ptr, i32 } cleanup
1610   call void @destructor()
1611   resume { ptr, i32 } %eh
1613 if.else0:
1614   %c1 = call i1 @cond()
1615   br i1 %c1, label %if.then1, label %if.else1
1617 if.then1:
1618   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1620 if.else1:
1621   %c2 = call i1 @cond()
1622   br i1 %c2, label %if.then2, label %if.end
1624 if.then2:
1625   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1627 if.end:
1628   call void @sideeffect()
1629   ret void
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
1641 ; CHECK:       lpad:
1642 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1643 ; CHECK-NEXT:    cleanup
1644 ; CHECK-NEXT:    call void @destructor()
1645 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1646 ; CHECK:       if.else:
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:%.*]]
1652 ; CHECK:       if.end:
1653 ; CHECK-NEXT:    call void @sideeffect()
1654 ; CHECK-NEXT:    ret void
1656 entry:
1657   %c0 = call i1 @cond()
1658   br i1 %c0, label %if.then0, label %if.else
1660 if.then0:
1661   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1663 invoke.cont:
1664   call void @sideeffect()
1665   unreachable
1667 lpad:
1668   %eh = landingpad { ptr, i32 } cleanup
1669   call void @destructor()
1670   resume { ptr, i32 } %eh
1672 if.else:
1673   %c1 = call i1 @cond()
1674   br i1 %c1, label %if.then1, label %if.end
1676 if.then1:
1677   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1679 if.end:
1680   call void @sideeffect()
1681   ret void
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
1694 ; CHECK:       lpad:
1695 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1696 ; CHECK-NEXT:    cleanup
1697 ; CHECK-NEXT:    call void @destructor()
1698 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1699 ; CHECK:       if.else:
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:%.*]]
1705 ; CHECK:       if.end:
1706 ; CHECK-NEXT:    call void @sideeffect()
1707 ; CHECK-NEXT:    ret void
1709 entry:
1710   %c0 = call i1 @cond()
1711   br i1 %c0, label %if.then0, label %if.else
1713 if.then0:
1714   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1716 invoke.cont:
1717   %phi = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
1718   call void @consume(i32 %phi)
1719   call void @sideeffect()
1720   unreachable
1722 lpad:
1723   %eh = landingpad { ptr, i32 } cleanup
1724   call void @destructor()
1725   resume { ptr, i32 } %eh
1727 if.else:
1728   %c1 = call i1 @cond()
1729   br i1 %c1, label %if.then1, label %if.end
1731 if.then1:
1732   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1734 if.end:
1735   call void @sideeffect()
1736   ret void
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
1748 ; CHECK:       lpad:
1749 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1750 ; CHECK-NEXT:    cleanup
1751 ; CHECK-NEXT:    call void @destructor()
1752 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1753 ; CHECK:       if.else0:
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:%.*]]
1759 ; CHECK:       if.else1:
1760 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
1761 ; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
1762 ; CHECK:       if.then2:
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
1767 ; CHECK:       if.end:
1768 ; CHECK-NEXT:    call void @sideeffect()
1769 ; CHECK-NEXT:    ret void
1771 entry:
1772   %c0 = call i1 @cond()
1773   br i1 %c0, label %if.then0, label %if.else0
1775 if.then0:
1776   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1778 invoke.cont0:
1779   call void @sideeffect()
1780   unreachable
1782 lpad:
1783   %eh = landingpad { ptr, i32 } cleanup
1784   call void @destructor()
1785   resume { ptr, i32 } %eh
1787 if.else0:
1788   %c1 = call i1 @cond()
1789   br i1 %c1, label %if.then1, label %if.else1
1791 if.then1:
1792   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1794 if.else1:
1795   %c2 = call i1 @cond()
1796   br i1 %c2, label %if.then2, label %if.end
1798 if.then2:
1799   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1801 invoke.cont2:
1802   unreachable
1804 if.end:
1805   call void @sideeffect()
1806   ret void
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:%.*]]
1815 ; CHECK:       if.then0:
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
1821 ; CHECK:       lpad:
1822 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1823 ; CHECK-NEXT:    cleanup
1824 ; CHECK-NEXT:    call void @destructor()
1825 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1826 ; CHECK:       if.else:
1827 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
1828 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
1829 ; CHECK:       if.then1:
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
1835 ; CHECK:       if.end:
1836 ; CHECK-NEXT:    call void @sideeffect()
1837 ; CHECK-NEXT:    ret void
1839 entry:
1840   %c0 = call i1 @cond()
1841   br i1 %c0, label %if.then0, label %if.else
1843 if.then0:
1844   invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad
1846 invoke.cont0:
1847   call void @sideeffect()
1848   unreachable
1850 lpad:
1851   %eh = landingpad { ptr, i32 } cleanup
1852   call void @destructor()
1853   resume { ptr, i32 } %eh
1855 if.else:
1856   %c1 = call i1 @cond()
1857   br i1 %c1, label %if.then1, label %if.end
1859 if.then1:
1860   invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad
1862 invoke.cont2:
1863   call void @sideeffect()
1864   unreachable
1866 if.end:
1867   call void @sideeffect()
1868   ret void
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:%.*]]
1879 ; CHECK:       lpad:
1880 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1881 ; CHECK-NEXT:    cleanup
1882 ; CHECK-NEXT:    call void @destructor()
1883 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1884 ; CHECK:       if.else:
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
1892 ; CHECK:       if.end:
1893 ; CHECK-NEXT:    call void @sideeffect()
1894 ; CHECK-NEXT:    ret void
1896 entry:
1897   %c0 = call i1 @cond()
1898   br i1 %c0, label %if.then0, label %if.else
1900 if.then0:
1901   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1903 lpad:
1904   %eh = landingpad { ptr, i32 } cleanup
1905   call void @destructor()
1906   resume { ptr, i32 } %eh
1908 if.else:
1909   %c1 = call i1 @cond()
1910   br i1 %c1, label %if.then1, label %if.end
1912 if.then1:
1913   invoke void @maybe_throw() to label %invoke.cont unwind label %lpad
1915 invoke.cont:
1916   %deadphi0 = phi i32 [ 0, %if.then0 ],  [ -1, %if.then1 ]
1917   unreachable
1919 if.end:
1920   call void @sideeffect()
1921   ret void
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
1936 ; CHECK:       lpad:
1937 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
1938 ; CHECK-NEXT:    cleanup
1939 ; CHECK-NEXT:    call void @destructor()
1940 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
1941 ; CHECK:       if.else:
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:%.*]]
1947 ; CHECK:       if.end:
1948 ; CHECK-NEXT:    call void @sideeffect()
1949 ; CHECK-NEXT:    ret void
1951 entry:
1952   %c0 = call i1 @cond()
1953   br i1 %c0, label %if.then0, label %if.else
1955 if.then0:
1956   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1958 invoke.cont:
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()
1964   unreachable
1966 lpad:
1967   %eh = landingpad { ptr, i32 } cleanup
1968   call void @destructor()
1969   resume { ptr, i32 } %eh
1971 if.else:
1972   %c1 = call i1 @cond()
1973   br i1 %c1, label %if.then1, label %if.end
1975 if.then1:
1976   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
1978 if.end:
1979   call void @sideeffect()
1980   ret void
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:%.*]]
1990 ; CHECK:       if.then0:
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
2000 ; CHECK:       lpad:
2001 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2002 ; CHECK-NEXT:    cleanup
2003 ; CHECK-NEXT:    call void @destructor()
2004 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2005 ; CHECK:       if.else:
2006 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2007 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
2008 ; CHECK:       if.then1:
2009 ; CHECK-NEXT:    [[V1]] = invoke i32 @returning_maybe_throw()
2010 ; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
2011 ; CHECK:       if.end:
2012 ; CHECK-NEXT:    call void @sideeffect()
2013 ; CHECK-NEXT:    ret void
2015 entry:
2016   %c0 = call i1 @cond()
2017   br i1 %c0, label %if.then0, label %if.else
2019 if.then0:
2020   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2022 invoke.cont:
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()
2028   unreachable
2030 lpad:
2031   %eh = landingpad { ptr, i32 } cleanup
2032   call void @destructor()
2033   resume { ptr, i32 } %eh
2035 if.else:
2036   %c1 = call i1 @cond()
2037   br i1 %c1, label %if.then1, label %if.end
2039 if.then1:
2040   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2042 if.end:
2043   call void @sideeffect()
2044   ret void
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:%.*]]
2054 ; CHECK:       if.then0:
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
2064 ; CHECK:       lpad:
2065 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2066 ; CHECK-NEXT:    cleanup
2067 ; CHECK-NEXT:    call void @destructor()
2068 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2069 ; CHECK:       if.else:
2070 ; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
2071 ; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
2072 ; CHECK:       if.then1:
2073 ; CHECK-NEXT:    [[V1]] = invoke i32 @returning_maybe_throw()
2074 ; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
2075 ; CHECK:       if.end:
2076 ; CHECK-NEXT:    call void @sideeffect()
2077 ; CHECK-NEXT:    ret void
2079 entry:
2080   %c0 = call i1 @cond()
2081   br i1 %c0, label %if.then0, label %if.else
2083 if.then0:
2084   %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2086 invoke.cont:
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()
2092   unreachable
2094 lpad:
2095   %eh = landingpad { ptr, i32 } cleanup
2096   call void @destructor()
2097   resume { ptr, i32 } %eh
2099 if.else:
2100   %c1 = call i1 @cond()
2101   br i1 %c1, label %if.then1, label %if.end
2103 if.then1:
2104   %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad
2106 if.end:
2107   call void @sideeffect()
2108   ret void
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:%.*]]
2117 ; CHECK:       lpad:
2118 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2119 ; CHECK-NEXT:    cleanup
2120 ; CHECK-NEXT:    call void @destructor()
2121 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2122 ; CHECK:       if.else:
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
2130 ; CHECK:       if.end:
2131 ; CHECK-NEXT:    call void @sideeffect()
2132 ; CHECK-NEXT:    ret void
2134 entry:
2135   %c0 = call i1 @cond()
2136   br i1 %c0, label %if.then0, label %if.else
2138 if.then0:
2139   invoke void %callee() to label %invoke.cont0 unwind label %lpad
2141 invoke.cont0:
2142   unreachable
2144 lpad:
2145   %eh = landingpad { ptr, i32 } cleanup
2146   call void @destructor()
2147   resume { ptr, i32 } %eh
2149 if.else:
2150   %c1 = call i1 @cond()
2151   br i1 %c1, label %if.then1, label %if.end
2153 if.then1:
2154   invoke void %callee() to label %invoke.cont2 unwind label %lpad
2156 invoke.cont2:
2157   unreachable
2159 if.end:
2160   call void @sideeffect()
2161   ret void
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:%.*]]
2170 ; CHECK:       lpad:
2171 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2172 ; CHECK-NEXT:    cleanup
2173 ; CHECK-NEXT:    call void @destructor()
2174 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2175 ; CHECK:       if.else:
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
2184 ; CHECK:       if.end:
2185 ; CHECK-NEXT:    call void @sideeffect()
2186 ; CHECK-NEXT:    ret void
2188 entry:
2189   %c0 = call i1 @cond()
2190   br i1 %c0, label %if.then0, label %if.else
2192 if.then0:
2193   invoke void %callee0() to label %invoke.cont0 unwind label %lpad
2195 invoke.cont0:
2196   unreachable
2198 lpad:
2199   %eh = landingpad { ptr, i32 } cleanup
2200   call void @destructor()
2201   resume { ptr, i32 } %eh
2203 if.else:
2204   %c1 = call i1 @cond()
2205   br i1 %c1, label %if.then1, label %if.end
2207 if.then1:
2208   invoke void %callee1() to label %invoke.cont2 unwind label %lpad
2210 invoke.cont2:
2211   unreachable
2213 if.end:
2214   call void @sideeffect()
2215   ret void
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:%.*]]
2224 ; CHECK:       lpad:
2225 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2226 ; CHECK-NEXT:    cleanup
2227 ; CHECK-NEXT:    call void @destructor()
2228 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2229 ; CHECK:       if.else0:
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
2237 ; CHECK:       if.else1:
2238 ; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
2239 ; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
2240 ; CHECK:       if.then2:
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
2245 ; CHECK:       if.end:
2246 ; CHECK-NEXT:    call void @sideeffect()
2247 ; CHECK-NEXT:    ret void
2249 entry:
2250   %c0 = call i1 @cond()
2251   br i1 %c0, label %if.then0, label %if.else0
2253 if.then0:
2254   invoke void %callee() to label %invoke.cont0 unwind label %lpad
2256 invoke.cont0:
2257   unreachable
2259 lpad:
2260   %eh = landingpad { ptr, i32 } cleanup
2261   call void @destructor()
2262   resume { ptr, i32 } %eh
2264 if.else0:
2265   %c1 = call i1 @cond()
2266   br i1 %c1, label %if.then1, label %if.else1
2268 if.then1:
2269   invoke void %callee() to label %invoke.cont2 unwind label %lpad
2271 invoke.cont2:
2272   unreachable
2274 if.else1:
2275   %c2 = call i1 @cond()
2276   br i1 %c2, label %if.then2, label %if.end
2278 if.then2:
2279   invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad
2281 invoke.cont3:
2282   unreachable
2284 if.end:
2285   call void @sideeffect()
2286   ret void
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:%.*]]
2295 ; CHECK:       lpad:
2296 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2297 ; CHECK-NEXT:    cleanup
2298 ; CHECK-NEXT:    call void @destructor()
2299 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2300 ; CHECK:       if.else:
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
2310 ; CHECK:       if.end:
2311 ; CHECK-NEXT:    call void @sideeffect()
2312 ; CHECK-NEXT:    ret void
2314 entry:
2315   %c0 = call i1 @cond()
2316   br i1 %c0, label %if.then0, label %if.else
2318 if.then0:
2319   invoke void %callee0(i32 0) to label %invoke.cont0 unwind label %lpad
2321 invoke.cont0:
2322   unreachable
2324 lpad:
2325   %eh = landingpad { ptr, i32 } cleanup
2326   call void @destructor()
2327   resume { ptr, i32 } %eh
2329 if.else:
2330   %c1 = call i1 @cond()
2331   br i1 %c1, label %if.then1, label %if.end
2333 if.then1:
2334   invoke void %callee1(i32 42) to label %invoke.cont2 unwind label %lpad
2336 invoke.cont2:
2337   unreachable
2339 if.end:
2340   call void @sideeffect()
2341   ret void
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:%.*]]
2350 ; CHECK:       lpad:
2351 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2352 ; CHECK-NEXT:    cleanup
2353 ; CHECK-NEXT:    call void @destructor()
2354 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2355 ; CHECK:       if.else:
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
2365 ; CHECK:       if.end:
2366 ; CHECK-NEXT:    call void @sideeffect()
2367 ; CHECK-NEXT:    ret void
2369 entry:
2370   %c0 = call i1 @cond()
2371   br i1 %c0, label %if.then0, label %if.else
2373 if.then0:
2374   invoke void %callee0() [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
2376 invoke.cont0:
2377   unreachable
2379 lpad:
2380   %eh = landingpad { ptr, i32 } cleanup
2381   call void @destructor()
2382   resume { ptr, i32 } %eh
2384 if.else:
2385   %c1 = call i1 @cond()
2386   br i1 %c1, label %if.then1, label %if.end
2388 if.then1:
2389   invoke void %callee1() [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
2391 invoke.cont2:
2392   unreachable
2394 if.end:
2395   call void @sideeffect()
2396   ret void
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:%.*]]
2405 ; CHECK:       lpad:
2406 ; CHECK-NEXT:    [[EH:%.*]] = landingpad { ptr, i32 }
2407 ; CHECK-NEXT:    cleanup
2408 ; CHECK-NEXT:    call void @destructor()
2409 ; CHECK-NEXT:    resume { ptr, i32 } [[EH]]
2410 ; CHECK:       if.else:
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
2421 ; CHECK:       if.end:
2422 ; CHECK-NEXT:    call void @sideeffect()
2423 ; CHECK-NEXT:    ret void
2425 entry:
2426   %c0 = call i1 @cond()
2427   br i1 %c0, label %if.then0, label %if.else
2429 if.then0:
2430   invoke void %callee0(i32 0) [ "abc"(i32 %a) ] to label %invoke.cont0 unwind label %lpad
2432 invoke.cont0:
2433   unreachable
2435 lpad:
2436   %eh = landingpad { ptr, i32 } cleanup
2437   call void @destructor()
2438   resume { ptr, i32 } %eh
2440 if.else:
2441   %c1 = call i1 @cond()
2442   br i1 %c1, label %if.then1, label %if.end
2444 if.then1:
2445   invoke void %callee1(i32 42) [ "abc"(i32 %b) ] to label %invoke.cont2 unwind label %lpad
2447 invoke.cont2:
2448   unreachable
2450 if.end:
2451   call void @sideeffect()
2452   ret void
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:%.*]]
2458 ; CHECK:       if:
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:%.*]]
2461 ; CHECK:       else:
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
2466 ; CHECK:       lpad:
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
2477 else:
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
2481 unreachable:
2482   unreachable
2484 lpad:
2485   %t3 = landingpad token
2486   cleanup
2487   ret void
2490 declare token @llvm.experimental.gc.statepoint.p0(i64 immarg, i32 immarg, ptr, i32 immarg, i32 immarg, ...)
2492 declare i1 @cond()
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) }