Index: lib/CodeGen/MachineBlockPlacement.cpp =================================================================== --- lib/CodeGen/MachineBlockPlacement.cpp +++ lib/CodeGen/MachineBlockPlacement.cpp @@ -409,7 +409,7 @@ SmallVector Successors; for (MachineBasicBlock *Succ : BB->successors()) { bool SkipSucc = false; - if (BlockFilter && !BlockFilter->count(Succ)) { + if (Succ->isEHPad() || (BlockFilter && !BlockFilter->count(Succ))) { SkipSucc = true; } else { BlockChain *SuccChain = BlockToChain[Succ]; @@ -533,6 +533,7 @@ MachineBasicBlock *BestBlock = nullptr; BlockFrequency BestFreq; + bool IsBestEHPad = true; for (MachineBasicBlock *MBB : WorkList) { BlockChain &SuccChain = *BlockToChain[MBB]; if (&SuccChain == &Chain) { @@ -541,14 +542,28 @@ } assert(SuccChain.LoopPredecessors == 0 && "Found CFG-violating block"); + // We prefer non ehpad over ehpads. + bool IsCandidateEHPad = MBB->isEHPad(); + if (IsCandidateEHPad && !IsBestEHPad) + continue; + + if (IsBestEHPad && !IsCandidateEHPad) + BestBlock = nullptr; + BlockFrequency CandidateFreq = MBFI->getBlockFreq(MBB); DEBUG(dbgs() << " " << getBlockName(MBB) << " -> "; MBFI->printBlockFreq(dbgs(), CandidateFreq) << " (freq)\n"); - if (BestBlock && BestFreq >= CandidateFreq) + + // For ehpad, we layout the least probable first as to avoid jumping back + // from least probable landingpads to more probable ones. + if (BestBlock && (IsCandidateEHPad ^ (BestFreq >= CandidateFreq))) continue; + BestBlock = MBB; BestFreq = CandidateFreq; + IsBestEHPad = IsCandidateEHPad; } + return BestBlock; } Index: test/CodeGen/X86/block-placement.ll =================================================================== --- test/CodeGen/X86/block-placement.ll +++ test/CodeGen/X86/block-placement.ll @@ -1083,3 +1083,53 @@ %ret = phi i32 [ %val1, %then ], [ %val2, %else ] ret i32 %ret } + +; Make sure we put landingpads out of the way. +declare i32 @pers(...) + +declare i32 @foo(); + +declare i32 @bar(); + +define i32 @test_lp(i32 %a) personality i32 (...)* @pers { +; CHECK-LABEL: test_lp: +; CHECK: %entry +; CHECK: %hot +; CHECK: %then +; CHECK: %cold +; CHECK: %coldlp +; CHECK: %hotlp +; CHECK: %lpret +entry: + %0 = icmp sgt i32 %a, 1 + br i1 %0, label %hot, label %cold, !prof !3 + +hot: + %1 = invoke i32 @foo() + to label %then unwind label %hotlp + +cold: + %2 = invoke i32 @bar() + to label %then unwind label %coldlp + +then: + %3 = phi i32 [ %1, %hot ], [ %2, %cold ] + ret i32 %3 + +hotlp: + %4 = landingpad { i8*, i32 } + cleanup + br label %lpret + +coldlp: + %5 = landingpad { i8*, i32 } + cleanup + br label %lpret + +lpret: + %6 = phi i32 [-1, %hotlp], [-2, %coldlp] + %7 = add i32 %6, 42 + ret i32 %7 +} + +!3 = !{!"branch_weights", i32 65536, i32 0} Index: test/CodeGen/X86/seh-safe-div-win32.ll =================================================================== --- test/CodeGen/X86/seh-safe-div-win32.ll +++ test/CodeGen/X86/seh-safe-div-win32.ll @@ -65,13 +65,13 @@ ; Landing pad code -; CHECK: [[handler0:LBB0_[0-9]+]]: # %handler0 +; CHECK: [[handler1:LBB0_[0-9]+]]: # %handler1 ; Restore SP ; CHECK: movl {{.*}}(%ebp), %esp ; CHECK: calll _puts ; CHECK: jmp [[cont_bb]] -; CHECK: [[handler1:LBB0_[0-9]+]]: # %handler1 +; CHECK: [[handler0:LBB0_[0-9]+]]: # %handler0 ; Restore SP ; CHECK: movl {{.*}}(%ebp), %esp ; CHECK: calll _puts Index: test/CodeGen/X86/seh-safe-div.ll =================================================================== --- test/CodeGen/X86/seh-safe-div.ll +++ test/CodeGen/X86/seh-safe-div.ll @@ -67,14 +67,14 @@ ; Landing pad code -; CHECK: [[handler0:\.LBB0_[0-9]+]]: # %handler0 +; CHECK: [[handler1:\.LBB0_[0-9]+]]: # %handler1 ; CHECK: callq puts -; CHECK: movl $-1, [[rloc]] +; CHECK: movl $-2, [[rloc]] ; CHECK: jmp [[cont_bb]] -; CHECK: [[handler1:\.LBB0_[0-9]+]]: # %handler1 +; CHECK: [[handler0:\.LBB0_[0-9]+]]: # %handler0 ; CHECK: callq puts -; CHECK: movl $-2, [[rloc]] +; CHECK: movl $-1, [[rloc]] ; CHECK: jmp [[cont_bb]] ; CHECK: .seh_handlerdata Index: test/CodeGen/X86/win-catchpad.ll =================================================================== --- test/CodeGen/X86/win-catchpad.ll +++ test/CodeGen/X86/win-catchpad.ll @@ -63,17 +63,17 @@ ; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont ; X86: retl -; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken -; X86-NEXT: # %handler1 -; X86-NEXT: addl $12, %ebp -; X86: jmp [[contbb]] - ; FIXME: These should be de-duplicated. ; X86: [[restorebb2:LBB0_[0-9]+]]: # Block address taken ; X86-NEXT: # %handler2 ; X86-NEXT: addl $12, %ebp ; X86: jmp [[contbb]] +; X86: [[restorebb1:LBB0_[0-9]+]]: # Block address taken +; X86-NEXT: # %handler1 +; X86-NEXT: addl $12, %ebp +; X86: jmp [[contbb]] + ; X86: "?catch$[[catch1bb:[0-9]+]]@?0?try_catch_catch@4HA": ; X86: LBB0_[[catch1bb]]: # %handler1{{$}} ; X86: pushl %ebp