diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -2005,6 +2005,25 @@ break; } + case X86::ENDBR32: + case X86::ENDBR64: { + // CurrentPatchableFunctionEntrySym can be CurrentFnBegin only for + // -fpatchable-function-entry=N,0. The entry MBB is guaranteed to be + // non-empty. If MI is the initial ENDBR, place the + // __patchable_function_entries label after ENDBR. + if (CurrentPatchableFunctionEntrySym && + CurrentPatchableFunctionEntrySym == CurrentFnBegin && + MI == &MF->front().front()) { + MCInst Inst; + MCInstLowering.Lower(MI, Inst); + EmitAndCountInstruction(Inst); + CurrentPatchableFunctionEntrySym = createTempSymbol("patch"); + OutStreamer->EmitLabel(CurrentPatchableFunctionEntrySym); + return; + } + break; + } + case X86::TAILJMPr: case X86::TAILJMPm: case X86::TAILJMPd: diff --git a/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll b/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll --- a/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll +++ b/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll @@ -15,12 +15,14 @@ define void @f1() "patchable-function-entry"="1" { ; CHECK-LABEL: f1: ; CHECK-NEXT: .Lfunc_begin1: -; CHECK: endbr64 +; CHECK: # %bb.0: +; CHECK-NEXT: endbr64 +; CHECK-NEXT: .Lpatch0: ; CHECK-NEXT: nop ; CHECK-NEXT: retq ; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 ; CHECK-NEXT: .p2align 3 -; CHECK-NEXT: .quad .Lfunc_begin1 +; CHECK-NEXT: .quad .Lpatch0 ret void } @@ -43,6 +45,30 @@ ret void } +;; -fpatchable-function-entry=1 -fcf-protection=branch +;; For M=0, don't create .Lpatch0 if the initial instruction is not ENDBR, +;; even if other basic blocks may have ENDBR. +@buf = internal global [5 x i8*] zeroinitializer +declare i8* @llvm.frameaddress(i32) +declare i8* @llvm.stacksave() +declare i32 @llvm.eh.sjlj.setjmp(i8*) + +define internal void @f1i() "patchable-function-entry"="1" { +; CHECK-LABEL: f1i: +; CHECK-NEXT: .Lfunc_begin3: +; CHECK: # %bb.0: +; CHECK-NEXT: nop +; CHECK-NEXT: pushq %rbp +;; Another basic block has ENDBR, but it doesn't affect our decision to not create .Lpatch0 +; CHECK: endbr64 +; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 +; CHECK-NEXT: .p2align 3 +; CHECK-NEXT: .quad .Lfunc_begin3 +entry: + tail call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([5 x i8*]* @buf to i8*)) + ret void +} + !llvm.module.flags = !{!0} !0 = !{i32 4, !"cf-protection-branch", i32 1}