Index: llvm/lib/Target/X86/X86IndirectBranchTracking.cpp =================================================================== --- llvm/lib/Target/X86/X86IndirectBranchTracking.cpp +++ llvm/lib/Target/X86/X86IndirectBranchTracking.cpp @@ -138,17 +138,38 @@ if (MBB.hasAddressTaken()) Changed |= addENDBR(MBB, MBB.begin()); - // Exception handle may indirectly jump to catch pad, So we should add - // ENDBR before catch pad instructions. - bool EHPadIBTNeeded = MBB.isEHPad(); - for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { if (I->isCall() && IsCallReturnTwice(I->getOperand(0))) Changed |= addENDBR(MBB, std::next(I)); + } - if (EHPadIBTNeeded && I->isEHLabel()) { + // Exception handle may indirectly jump to catch pad, So we should add + // ENDBR before catch pad instructions. For SjLj exception model, it will + // create a new BB(new landingpad) indirectly jump to the old landingpad. + if (TM->Options.ExceptionModel == ExceptionHandling::SjLj) { + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { + // New Landingpad BB without EHLabel. + if (MBB.isEHPad()) { + if (I->isDebugInstr()) + continue; + Changed |= addENDBR(MBB, I); + break; + } else if (I->isEHLabel()) { + // Old Landingpad BB (is not Landingpad now) with + // the the old "callee" EHLabel. + MCSymbol *Sym = I->getOperand(0).getMCSymbol(); + if (!MF.hasCallSiteLandingPad(Sym)) + continue; + Changed |= addENDBR(MBB, std::next(I)); + break; + } + } + } else if (MBB.isEHPad()){ + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) { + if (!I->isEHLabel()) + continue; Changed |= addENDBR(MBB, std::next(I)); - EHPadIBTNeeded = false; + break; } } } Index: llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll =================================================================== --- llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll +++ llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll @@ -1,15 +1,76 @@ -; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s -; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=X86_64 +; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s --check-prefix=X86 +; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -verify-machineinstrs=0 < %s | FileCheck %s --check-prefix=SJLJ + +; X86_64: test_eh: # @test_eh +; X86_64-NEXT: .Lfunc_begin0: +; X86_64: # %bb.0: # %entry +; X86_64-NEXT: endbr64 +; X86_64-NEXT: pushq %rax +; X86_64: .Ltmp0: +; X86_64-NEXT: callq _Z20function_that_throwsv +; X86_64-NEXT: .Ltmp1: +; X86_64-NEXT: # %bb.1: # %try.cont +; X86_64: retq +; X86_64-NEXT: .LBB0_2: # %lpad +; X86_64-NEXT: .cfi_def_cfa_offset 16 +; X86_64-NEXT: .Ltmp2: +; X86_64-NEXT: endbr64 +; X86_64: callq __cxa_begin_catch + + +; X86: test_eh: # @test_eh +; X86-NEXT: .Lfunc_begin0: +; X86: # %bb.0: # %entry +; X86-NEXT: endbr32 +; X86-NEXT: .Ltmp0: +; X86: calll _Z20function_that_throwsv +; X86-NEXT: .Ltmp1: +; X86-NEXT: # %bb.1: # %try.cont +; X86-NEXT: retl +; X86-NEXT: .LBB0_2: # %lpad +; X86-NEXT: .Ltmp2: +; X86-NEXT: endbr32 +; X86: calll __cxa_begin_catch + + +; SJLJ: test_eh: +; SJLJ-NEXT: Lfunc_begin0: +; SJLJ-NEXT: # %bb.0: # %entry +; SJLJ-NEXT: endbr32 +; SJLJ: calll __Unwind_SjLj_Register +; SJLJ: Ltmp0: +; SJLJ: calll __Z20function_that_throwsv +; SJLJ: LBB0_2: # %try.cont +; SJLJ: calll __Unwind_SjLj_Unregister +; SJLJ: retl + +; SJLJ: LBB0_3: +; SJLJ-NEXT: endbr32 +; SJLJ-NEXT: leal +; SJLJ-NEXT: movl +; SJLJ-NEXT: cmpl +; SJLJ-NEXT: jb LBB0_4 + +; SJLJ: LBB0_4: +; SJLJ-NEXT: jmpl *LJTI0_0(,%eax,4) + +; SJLJ: LBB0_6: # %lpad +; SJLJ-NEXT: Ltmp2: +; SJLJ-NEXT: endbr32 +; SJLJ: calll ___cxa_begin_catch +; SJLJ: jmp LBB0_2 +; SJLJ: LJTI0_0: +; SJLJ-NEXT: .long LBB0_6 + -;There should be 2 endbr* instruction at entry and catch pad. -;CHECK-COUNT-2: endbr declare void @_Z20function_that_throwsv() declare i32 @__gxx_personality_sj0(...) declare i8* @__cxa_begin_catch(i8*) declare void @__cxa_end_catch() -define void @test8() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) { +define void @test_eh() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) { entry: invoke void @_Z20function_that_throwsv() to label %try.cont unwind label %lpad