diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index 4c5fe4c480a6..f05b6c1eb977 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -297,8 +297,14 @@ void MachineBasicBlock::updateTerminator() { TII->RemoveBranch(*this); } else { // The block has an unconditional fallthrough. If its successor is not - // its layout successor, insert a branch. - TBB = *succ_begin(); + // its layout successor, insert a branch. First we have to locate the + // only non-landing-pad successor, as that is the fallthrough block. + for (succ_iterator SI = succ_begin(), SE = succ_end(); SI != SE; ++SI) { + if ((*SI)->isLandingPad()) + continue; + assert(!TBB && "Found more than one non-landing-pad successor!"); + TBB = *SI; + } if (!isLayoutSuccessor(TBB)) TII->InsertBranch(*this, TBB, 0, Cond, dl); } diff --git a/llvm/test/CodeGen/X86/block-placement.ll b/llvm/test/CodeGen/X86/block-placement.ll index 7361ae4258b0..8a8bf1345e94 100644 --- a/llvm/test/CodeGen/X86/block-placement.ll +++ b/llvm/test/CodeGen/X86/block-placement.ll @@ -475,3 +475,31 @@ exit: } !2 = metadata !{metadata !"branch_weights", i32 3, i32 1} + +declare i32 @__gxx_personality_v0(...) + +define void @test_eh_lpad_successor() { +; Some times the landing pad ends up as the first successor of an invoke block. +; When this happens, a strange result used to fall out of updateTerminators: we +; didn't correctly locate the fallthrough successor, assuming blindly that the +; first one was the fallthrough successor. As a result, we would add an +; erroneous jump to the landing pad thinking *that* was the default successor. +; CHECK: test_eh_lpad_successor +; CHECK: %entry +; CHECK-NOT: jmp +; CHECK: %loop + +entry: + invoke i32 @f() to label %preheader unwind label %lpad + +preheader: + br label %loop + +lpad: + %lpad.val = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + resume { i8*, i32 } %lpad.val + +loop: + br label %loop +}