Compiler projects using llvm
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --check-globals
; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts -S | FileCheck %s
; RUN: opt < %s -passes='simplifycfg<sink-common-insts>' -S | FileCheck %s

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Simple test, nothing interesting happens here.
define void @t0_noop() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t0_noop(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c = call i1 @cond()
  br i1 %c, label %if.then, label %if.end

if.then:
  invoke void @simple_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.end:
  call void @sideeffect()
  ret void
}

; More interesting test, here we can merge the invokes.
define void @t1_mergeable_invoke() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t1_mergeable_invoke(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; normal block is shared, but it is unreachable, so we are fine.
define void @t2_shared_normal_dest() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t2_shared_normal_dest(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; shared normal destination is not unreachable.
define void @t3_shared_identical_normal_dest() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t3_shared_identical_normal_dest(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; normal destinations are not unreachable and not shared and can not be merged.
define void @t4_normal_dests() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t4_normal_dests(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    call void @another_sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  call void @another_sideeffect()
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Invokes lead to different landing pads.
define void @t5_different_landingpads() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t5_different_landingpads(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD0:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       common.resume:
; CHECK-NEXT:    [[COMMON_RESUME_OP:%.*]] = phi { i8*, i32 } [ [[EH0:%.*]], [[LPAD0]] ], [ [[EH1:%.*]], [[LPAD1:%.*]] ]
; CHECK-NEXT:    resume { i8*, i32 } [[COMMON_RESUME_OP]]
; CHECK:       lpad0:
; CHECK-NEXT:    [[EH0]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    br label [[COMMON_RESUME:%.*]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD1]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       lpad1:
; CHECK-NEXT:    [[EH1]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @another_destructor()
; CHECK-NEXT:    br label [[COMMON_RESUME]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad0

invoke.cont0:
  unreachable

lpad0:
  %eh0 = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh0

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad1

invoke.cont2:
  unreachable

lpad1:
  %eh1 = landingpad { i8*, i32 } cleanup
  call void @another_destructor()
  resume { i8*, i32 } %eh1

if.end:
  call void @sideeffect()
  ret void
}

; The invoked functions are different
define void @t6_different_invokes() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t6_different_invokes(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @another_simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @another_simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Merging of this invoke is disallowed
define void @t7_nomerge0() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t7_nomerge0(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1:[0-9]+]]
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() nomerge to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}
define void @t8_nomerge1() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t8_nomerge1(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1]]
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() nomerge to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}
define void @t9_nomerge2() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t9_nomerge2(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1]]
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR1]]
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() nomerge to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() nomerge to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Just don't deal with inlineasm.
define void @t10_inlineasm() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t10_inlineasm(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void asm sideeffect "something bad", ""()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void asm sideeffect "something bad", ""()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void asm sideeffect "something bad", ""() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void asm sideeffect "something bad", ""() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; landingpad has PHI nodes, and the incoming values are incompatible.
define void @t11_phi_in_landingpad_incompatible_incoming_values() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t11_phi_in_landingpad_incompatible_incoming_values(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ 1, [[IF_THEN1:%.*]] ]
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @consume(i32 [[PHI]])
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %phi = phi i32 [ 0, %if.then0 ], [ 1, %if.then1 ]
  %eh = landingpad { i8*, i32 } cleanup
  call void @consume(i32 %phi)
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; It is okay for the invoke to take arguments
define void @t12_arguments_are_fine() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t12_arguments_are_fine(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw_taking_argument(i32 42)
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; It is okay for the invoke to take different arguments
define void @t13_different_arguments_are_fine() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t13_different_arguments_are_fine(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 42, [[IF_ELSE]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT:    invoke void @simple_throw_taking_argument(i32 [[TMP0]])
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw_taking_argument(i32 0) to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw_taking_argument(i32 42) to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; There can be more than two invokes in a set
define void @t14_three_invokes() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t14_three_invokes(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN2_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN2_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then2.invoke:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[IF_THEN2_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then2.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad

invoke.cont3:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; If not all invokes of landingpad are compatible then we still merge compatible ones.
define void @t15_three_invokes_only_two_compatible() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t15_three_invokes_only_two_compatible(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then2:
; CHECK-NEXT:    invoke void @another_simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont3:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @another_simple_throw() to label %invoke.cont3 unwind label %lpad

invoke.cont3:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; We succeed in merging invokes into two sets
define void @t16_four_invokes_forming_two_sets() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t16_four_invokes_forming_two_sets(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN3_INVOKE:%.*]], label [[IF_ELSE2:%.*]]
; CHECK:       if.else2:
; CHECK-NEXT:    [[C3:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C3]], label [[IF_THEN3_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then3.invoke:
; CHECK-NEXT:    invoke void @another_simple_throw()
; CHECK-NEXT:    to label [[IF_THEN3_CONT:%.*]] unwind label [[LPAD]]
; CHECK:       if.then3.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.else2

if.then2:
  invoke void @another_simple_throw() to label %invoke.cont3 unwind label %lpad

invoke.cont3:
  unreachable

if.else2:
  %c3 = call i1 @cond()
  br i1 %c3, label %if.then3, label %if.end

if.then3:
  invoke void @another_simple_throw() to label %invoke.cont4 unwind label %lpad

invoke.cont4:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Attributes must match
define void @t17_mismatched_attrs_prevent_merge() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t17_mismatched_attrs_prevent_merge(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR2:[0-9]+]]
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Common attributes are preserved
define void @t18_attributes_are_preserved() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t18_attributes_are_preserved(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw() #[[ATTR2]]
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() readnone to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() readnone to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Fully identical operand bundles are good.
define void @t19_compatible_operand_bundle() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t19_compatible_operand_bundle(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw() [ "abc"(i32 42) ]
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Operand bundles must be compatible, else we can't merge.
define void @t20_incompatible_operand_bundle() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t20_incompatible_operand_bundle(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw() [ "abc"(i32 42) ]
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw() [ "def"(i32 0) ]
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() [ "def"(i32 0) ] to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; We need to PHI together the arguments of the operand bundles.
define void @t21_semicompatible_operand_bundle() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t21_semicompatible_operand_bundle(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[IF_ELSE]] ], [ 42, [[ENTRY:%.*]] ]
; CHECK-NEXT:    invoke void @simple_throw() [ "abc"(i32 [[TMP0]]) ]
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @simple_throw() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @simple_throw() [ "abc"(i32 0) ] to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Even though the normal destinations are unreachable,
; they may have (dead) PHI nodes, so we must cleanup them.
define void @t22_dead_phi_in_normal_dest() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t22_dead_phi_in_normal_dest(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont0:
  %deadphi0 = phi i32 [ 0, %if.then0 ]
  unreachable

invoke.cont2:
  %deadphi2 = phi i32 [ 0, %if.then1 ]
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; landingpad has PHI nodes, and out of three invokes, only two have compatible incoming values.
define void @t23_phi_in_landingpad_compatible_incoming_values() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t23_phi_in_landingpad_compatible_incoming_values(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, [[IF_THEN2:%.*]] ], [ 0, [[IF_THEN1_INVOKE]] ]
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @consume(i32 [[PHI]])
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
; CHECK:       if.then2:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont3:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
  %eh = landingpad { i8*, i32 } cleanup
  call void @consume(i32 %phi)
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad

invoke.cont3:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; landingpad has two PHI nodes, but depending on which PHI you look,
; the invoke sets would be different, so we can't merge invokes here.
define void @t24_phi_in_landingpad_semi_compatible_incoming_values() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t24_phi_in_landingpad_semi_compatible_incoming_values(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[PHI0:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ 0, [[IF_THEN1:%.*]] ], [ -1, [[IF_THEN2:%.*]] ]
; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ 1, [[IF_THEN1]] ], [ 1, [[IF_THEN2]] ]
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @consume(i32 [[PHI0]])
; CHECK-NEXT:    call void @consume(i32 [[PHI1]])
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
; CHECK:       if.then2:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont3:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @simple_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %phi0 = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
  %phi1= phi i32 [ 0, %if.then0 ], [ 1, %if.then1 ], [ 1, %if.then2 ]
  %eh = landingpad { i8*, i32 } cleanup
  call void @consume(i32 %phi0)
  call void @consume(i32 %phi1)
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @simple_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad

invoke.cont3:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; The normal destinations are shared, but the incoming values are incompatible.
define void @t25_incompatible_phis_in_normal_destination() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t25_incompatible_phis_in_normal_destination(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ -1, [[IF_THEN1:%.*]] ]
; CHECK-NEXT:    call void @consume(i32 [[PHI]])
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %phi = phi i32 [ 0, %if.then0 ], [ -1, %if.then1 ]
  call void @consume(i32 %phi)
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; shared normal destination has PHI nodes, and out of three invokes, only two have compatible incoming values.
define void @t26_phi_in_normal_dest_compatible_incoming_values() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t26_phi_in_normal_dest_compatible_incoming_values(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ -1, [[IF_THEN2:%.*]] ], [ 0, [[IF_THEN1_INVOKE]] ]
; CHECK-NEXT:    call void @consume(i32 [[PHI]])
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2]], label [[IF_END:%.*]]
; CHECK:       if.then2:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %phi = phi i32 [ 0, %if.then0 ], [ 0, %if.then1 ], [ -1, %if.then2 ]
  call void @consume(i32 %phi)
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; Invokes return values, but they are unused.
define void @t27_invoke_ret_value_is_used() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t27_invoke_ret_value_is_used(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; Invokes return values, and they are used in a phi node, making the incoming values incompatible.
define void @t28_invoke_ret_value_is_used_in_phi_node() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t28_invoke_ret_value_is_used_in_phi_node(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    call void @consume(i32 [[TMP0:%.*]])
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %phi = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
  call void @consume(i32 %phi)
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; out of three invokes, two share normal destination and another one has unreachable destination
define void @t29_common_normal_destination_and_unreachable_normal_destination() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t29_common_normal_destination_and_unreachable_normal_destination(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then2:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; normal destinations are not unreachable and different but could be merged
define void @t30_completely_different_normal_dests() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t30_completely_different_normal_dests(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT0:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont0:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont2:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @maybe_throw() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @maybe_throw() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  call void @sideeffect()
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Even though the normal destinations are unreachable,
; they may have (dead) PHI nodes with incompatible incoming values,
; so we must cleanup them.
define void @t31_incompatible_dead_phi_in_normal_dest() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t31_incompatible_dead_phi_in_normal_dest(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void @maybe_throw()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void @maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %deadphi0 = phi i32 [ 0, %if.then0 ],  [ -1, %if.then1 ]
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Invokes return values, and they are used in a phi node, making the incoming values incompatible,
; second phi has compatible incoming values
define void @t32_invoke_ret_value_is_used_in_phi_node_other_phi_is_fine() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t32_invoke_ret_value_is_used_in_phi_node_other_phi_is_fine(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    call void @consume(i32 [[TMP0:%.*]])
; CHECK-NEXT:    call void @consume(i32 0)
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %phi0 = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
  %phi1 = phi i32 [ 0, %if.then0 ],   [ 0, %if.then1 ]
  call void @consume(i32 %phi0)
  call void @consume(i32 %phi1)
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; Invokes return values, and they are used in a phi node, making the incoming values incompatible,
; second phi has incompatible incoming values.
define void @t33_invoke_ret_value_is_used_in_phi_node_other_phi_is_bad() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t33_invoke_ret_value_is_used_in_phi_node_other_phi_is_bad(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    [[V0:%.*]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    [[PHI0:%.*]] = phi i32 [ [[V0]], [[IF_THEN0]] ], [ [[V1:%.*]], [[IF_THEN1:%.*]] ]
; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ -1, [[IF_THEN1]] ]
; CHECK-NEXT:    call void @consume(i32 [[PHI0]])
; CHECK-NEXT:    call void @consume(i32 [[PHI1]])
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    [[V1]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %phi0 = phi i32 [ %v0, %if.then0 ], [ %v1, %if.then1 ]
  %phi1 = phi i32 [ 0, %if.then0 ],   [ -1, %if.then1 ]
  call void @consume(i32 %phi0)
  call void @consume(i32 %phi1)
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; Invokes return values, and they are used in a phi node, but when coming from different invokes,
; the incoming value isn't always the invoke, which is not okay.
define void @t34_invoke_ret_value_maybe_incompatibly_used_in_phi_node() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t34_invoke_ret_value_maybe_incompatibly_used_in_phi_node(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN0:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       if.then0:
; CHECK-NEXT:    [[V0:%.*]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       invoke.cont:
; CHECK-NEXT:    [[PHI0:%.*]] = phi i32 [ [[V0]], [[IF_THEN0]] ], [ 0, [[IF_THEN1:%.*]] ]
; CHECK-NEXT:    [[PHI1:%.*]] = phi i32 [ 0, [[IF_THEN0]] ], [ [[V1:%.*]], [[IF_THEN1]] ]
; CHECK-NEXT:    call void @consume(i32 [[PHI0]])
; CHECK-NEXT:    call void @consume(i32 [[PHI1]])
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    unreachable
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1]], label [[IF_END:%.*]]
; CHECK:       if.then1:
; CHECK-NEXT:    [[V1]] = invoke i32 @returning_maybe_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT]] unwind label [[LPAD]]
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  %v0 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

invoke.cont:
  %phi0 = phi i32 [ %v0, %if.then0 ], [ 0, %if.then1 ]
  %phi1 = phi i32 [ 0, %if.then0 ],   [ %v1, %if.then1 ]
  call void @consume(i32 %phi0)
  call void @consume(i32 %phi1)
  call void @sideeffect()
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  %v1 = invoke i32 @returning_maybe_throw() to label %invoke.cont unwind label %lpad

if.end:
  call void @sideeffect()
  ret void
}

; Two mergeable indirect calls, with identical callees.
define void @t35_identical_indirect_callees(void()* %callee) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t35_identical_indirect_callees(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void [[CALLEE:%.*]]()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void %callee() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void %callee() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Two mergeable indirect calls, with different callees.
define void @t36_different_indirect_callees(void()* %callee0, void()* %callee1) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t36_different_indirect_callees(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = phi void ()* [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT:    invoke void [[TMP0]]()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void %callee0() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void %callee1() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; Don't merge direct invoke with indirect ones.
define void @t37_three_invokes_two_indirect_one_direct(void()* %callee) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t37_three_invokes_two_indirect_one_direct(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE0:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else0:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_ELSE1:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    invoke void [[CALLEE:%.*]]()
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.else1:
; CHECK-NEXT:    [[C2:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C2]], label [[IF_THEN2:%.*]], label [[IF_END:%.*]]
; CHECK:       if.then2:
; CHECK-NEXT:    invoke void @simple_throw()
; CHECK-NEXT:    to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD]]
; CHECK:       invoke.cont3:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else0

if.then0:
  invoke void %callee() to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else0:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.else1

if.then1:
  invoke void %callee() to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.else1:
  %c2 = call i1 @cond()
  br i1 %c2, label %if.then2, label %if.end

if.then2:
  invoke void @simple_throw() to label %invoke.cont3 unwind label %lpad

invoke.cont3:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; For indirect invokes, different arguments are fine.
define void @t38_different_arguments_and_operand_bundes_are_fine(void(i32)* %callee0, void(i32)* %callee1) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t38_different_arguments_and_operand_bundes_are_fine(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 42, [[IF_ELSE]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[TMP1:%.*]] = phi void (i32)* [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY]] ]
; CHECK-NEXT:    invoke void [[TMP1]](i32 [[TMP0]])
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void %callee0(i32 0) to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void %callee1(i32 42) to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; For indirect invokes, different operand bundle arguments are fine.
define void @t39_different_arguments_and_operand_bundes_are_fine(void()* %callee0, void()* %callee1) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t39_different_arguments_and_operand_bundes_are_fine(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[IF_ELSE]] ], [ 42, [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[TMP1:%.*]] = phi void ()* [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY]] ]
; CHECK-NEXT:    invoke void [[TMP1]]() [ "abc"(i32 [[TMP0]]) ]
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void %callee0() [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void %callee1() [ "abc"(i32 0) ] to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

; For indirect invokes, both different arguments and operand bundle arguments are fine.
define void @t40_different_arguments_and_operand_bundes_are_fine(void(i32)* %callee0, void(i32)* %callee1) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
; CHECK-LABEL: @t40_different_arguments_and_operand_bundes_are_fine(
; CHECK-NEXT:  entry:
; CHECK-NEXT:    [[C0:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C0]], label [[IF_THEN1_INVOKE:%.*]], label [[IF_ELSE:%.*]]
; CHECK:       lpad:
; CHECK-NEXT:    [[EH:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT:    cleanup
; CHECK-NEXT:    call void @destructor()
; CHECK-NEXT:    resume { i8*, i32 } [[EH]]
; CHECK:       if.else:
; CHECK-NEXT:    [[C1:%.*]] = call i1 @cond()
; CHECK-NEXT:    br i1 [[C1]], label [[IF_THEN1_INVOKE]], label [[IF_END:%.*]]
; CHECK:       if.then1.invoke:
; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 42, [[IF_ELSE]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ 0, [[IF_ELSE]] ], [ 42, [[ENTRY]] ]
; CHECK-NEXT:    [[TMP2:%.*]] = phi void (i32)* [ [[CALLEE1:%.*]], [[IF_ELSE]] ], [ [[CALLEE0:%.*]], [[ENTRY]] ]
; CHECK-NEXT:    invoke void [[TMP2]](i32 [[TMP0]]) [ "abc"(i32 [[TMP1]]) ]
; CHECK-NEXT:    to label [[IF_THEN1_CONT:%.*]] unwind label [[LPAD:%.*]]
; CHECK:       if.then1.cont:
; CHECK-NEXT:    unreachable
; CHECK:       if.end:
; CHECK-NEXT:    call void @sideeffect()
; CHECK-NEXT:    ret void
;
entry:
  %c0 = call i1 @cond()
  br i1 %c0, label %if.then0, label %if.else

if.then0:
  invoke void %callee0(i32 0) [ "abc"(i32 42) ] to label %invoke.cont0 unwind label %lpad

invoke.cont0:
  unreachable

lpad:
  %eh = landingpad { i8*, i32 } cleanup
  call void @destructor()
  resume { i8*, i32 } %eh

if.else:
  %c1 = call i1 @cond()
  br i1 %c1, label %if.then1, label %if.end

if.then1:
  invoke void %callee1(i32 42) [ "abc"(i32 0) ] to label %invoke.cont2 unwind label %lpad

invoke.cont2:
  unreachable

if.end:
  call void @sideeffect()
  ret void
}

declare i1 @cond()

declare void @sideeffect()
declare void @another_sideeffect()

declare void @maybe_throw()

declare void @simple_throw() noreturn
declare void @another_simple_throw() noreturn

declare void @simple_throw_taking_argument(i32) noreturn

declare i32 @returning_maybe_throw()

declare void @destructor()
declare void @another_destructor()

declare void @consume(i32)

declare dso_local i32 @__gxx_personality_v0(...)
;.
; CHECK: attributes #[[ATTR0:[0-9]+]] = { noreturn }
; CHECK: attributes #[[ATTR1]] = { nomerge }
; CHECK: attributes #[[ATTR2]] = { readnone }
;.