Author: Fangrui Song Date: 2020-02-05T15:19:04+01:00 New Revision: 4c96b369a074e93a0be536dd795d3f245ef6f18b
URL: https://github.com/llvm/llvm-project/commit/4c96b369a074e93a0be536dd795d3f245ef6f18b DIFF: https://github.com/llvm/llvm-project/commit/4c96b369a074e93a0be536dd795d3f245ef6f18b.diff LOG: [X86] -fpatchable-function-entry=N,0: place patch label after ENDBR{32,64} Similar to D73680 (AArch64 BTI). A local linkage function whose address is not taken does not need ENDBR32/ENDBR64. Placing the patch label after ENDBR32/ENDBR64 has the advantage that code does not need to differentiate whether the function has an initial ENDBR. Also, add 32-bit tests and test that .cfi_startproc is at the function entry. The line information has a general implementation and is tested by AArch64/patchable-function-entry-empty.mir Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D73760 (cherry picked from commit 8ff86fcf4c038c7156ed4f01e7ed35cae49489e2) Added: Modified: llvm/lib/Target/X86/X86MCInstLower.cpp llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll Removed: ################################################################################ diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 2fc9a2af01d7..7f49c6e861d4 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -2002,6 +2002,25 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) { 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/AArch64/patchable-function-entry-bti.ll b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll index 4b85664673fd..19386e94383d 100644 --- a/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll +++ b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll @@ -15,7 +15,8 @@ define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" { define void @f1() "patchable-function-entry"="1" "branch-target-enforcement" { ; CHECK-LABEL: f1: ; CHECK-NEXT: .Lfunc_begin1: -; CHECK: // %bb.0: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: hint #34 ; CHECK-NEXT: .Lpatch0: ; CHECK-NEXT: nop @@ -33,7 +34,8 @@ define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"=" ; CHECK-NEXT: nop ; CHECK-NEXT: f2_1: ; CHECK-NEXT: .Lfunc_begin2: -; CHECK: // %bb.0: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: // %bb.0: ; CHECK-NEXT: hint #34 ; CHECK-NEXT: nop ; CHECK-NEXT: ret diff --git a/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll b/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll index 49a36b2205ce..3def5a378458 100644 --- a/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll +++ b/llvm/test/CodeGen/X86/patchable-function-entry-ibt.ll @@ -1,26 +1,37 @@ -; RUN: llc -mtriple=x86_64 %s -o - | FileCheck --check-prefixes=CHECK %s +; RUN: llc -mtriple=i686 %s -o - | FileCheck --check-prefixes=CHECK,32 %s +; RUN: llc -mtriple=x86_64 %s -o - | FileCheck --check-prefixes=CHECK,64 %s ;; -fpatchable-function-entry=0 -fcf-protection=branch -define void @f0() "patchable-function-entry"="0" "branch-target-enforcement" { +define void @f0() "patchable-function-entry"="0" { ; CHECK-LABEL: f0: ; CHECK-NEXT: .Lfunc_begin0: -; CHECK: # %bb.0: -; CHECK-NEXT: endbr64 -; CHECK-NEXT: retq +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: # %bb.0: +; 32-NEXT: endbr32 +; 64-NEXT: endbr64 +; CHECK-NEXT: ret ; CHECK-NOT: .section __patchable_function_entries ret void } ;; -fpatchable-function-entry=1 -fcf-protection=branch +;; For M=0, place the label .Lpatch0 after the initial ENDBR. +;; .cfi_startproc should be placed at the function entry. define void @f1() "patchable-function-entry"="1" { ; CHECK-LABEL: f1: ; CHECK-NEXT: .Lfunc_begin1: -; CHECK: endbr64 +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: # %bb.0: +; 32-NEXT: endbr32 +; 64-NEXT: endbr64 +; CHECK-NEXT: .Lpatch0: ; CHECK-NEXT: nop -; CHECK-NEXT: retq +; CHECK-NEXT: ret ; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 -; CHECK-NEXT: .p2align 3 -; CHECK-NEXT: .quad .Lfunc_begin1 +; 32-NEXT: .p2align 2 +; 32-NEXT: .long .Lpatch0 +; 64-NEXT: .p2align 3 +; 64-NEXT: .quad .Lpatch0 ret void } @@ -31,15 +42,44 @@ define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"=" ; CHECK-NEXT: nop ; CHECK-NEXT: f2_1: ; CHECK-NEXT: .Lfunc_begin2: -; CHECK: # %bb.0: -; CHECK-NEXT: endbr64 +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: # %bb.0: +; 32-NEXT: endbr32 +; 64-NEXT: endbr64 ; CHECK-NEXT: nop -; CHECK-NEXT: retq +; CHECK-NEXT: ret ; CHECK: .Lfunc_end2: ; CHECK-NEXT: .size f2_1, .Lfunc_end2-f2_1 ; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 -; CHECK-NEXT: .p2align 3 -; CHECK-NEXT: .quad .Ltmp0 +; 32-NEXT: .p2align 2 +; 32-NEXT: .long .Ltmp0 +; 64-NEXT: .p2align 3 +; 64-NEXT: .quad .Ltmp0 + 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 i32 @llvm.eh.sjlj.setjmp(i8*) + +define internal void @f1i() "patchable-function-entry"="1" { +; CHECK-LABEL: f1i: +; CHECK-NEXT: .Lfunc_begin3: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: nop +; CHECK-NOT: .Lpatch0: +;; Another basic block has ENDBR, but it doesn't affect our decision to not create .Lpatch0 +; CHECK: endbr +; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 +; 32-NEXT: .p2align 2 +; 32-NEXT: .long .Lfunc_begin3 +; 64-NEXT: .p2align 3 +; 64-NEXT: .quad .Lfunc_begin3 +entry: + tail call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([5 x i8*]* @buf to i8*)) ret void } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits