1; RUN: llc -mtriple=i686 %s -o - | FileCheck --check-prefixes=CHECK,32 %s 2; RUN: llc -mtriple=x86_64 %s -o - | FileCheck --check-prefixes=CHECK,64 %s 3 4;; -fpatchable-function-entry=0 -fcf-protection=branch 5define void @f0() "patchable-function-entry"="0" { 6; CHECK-LABEL: f0: 7; CHECK-NEXT: .Lfunc_begin0: 8; CHECK-NEXT: .cfi_startproc 9; CHECK-NEXT: # %bb.0: 10; 32-NEXT: endbr32 11; 64-NEXT: endbr64 12; CHECK-NEXT: ret 13; CHECK-NOT: .section __patchable_function_entries 14 ret void 15} 16 17;; -fpatchable-function-entry=1 -fcf-protection=branch 18;; For M=0, place the label .Lpatch0 after the initial ENDBR. 19;; .cfi_startproc should be placed at the function entry. 20define void @f1() "patchable-function-entry"="1" { 21; CHECK-LABEL: f1: 22; CHECK-NEXT: .Lfunc_begin1: 23; CHECK-NEXT: .cfi_startproc 24; CHECK-NEXT: # %bb.0: 25; 32-NEXT: endbr32 26; 64-NEXT: endbr64 27; CHECK-NEXT: .Lpatch0: 28; CHECK-NEXT: nop 29; CHECK-NEXT: ret 30; CHECK: .section __patchable_function_entries,"awo",@progbits,f1{{$}} 31; 32-NEXT: .p2align 2 32; 32-NEXT: .long .Lpatch0 33; 64-NEXT: .p2align 3 34; 64-NEXT: .quad .Lpatch0 35 ret void 36} 37 38;; -fpatchable-function-entry=2,1 -fcf-protection=branch 39define void @f2_1() "patchable-function-entry"="1" "patchable-function-prefix"="1" { 40; CHECK-LABEL: .type f2_1,@function 41; CHECK-NEXT: .Ltmp0: 42; CHECK-NEXT: nop 43; CHECK-NEXT: f2_1: 44; CHECK-NEXT: .Lfunc_begin2: 45; CHECK-NEXT: .cfi_startproc 46; CHECK-NEXT: # %bb.0: 47; 32-NEXT: endbr32 48; 64-NEXT: endbr64 49; CHECK-NEXT: nop 50; CHECK-NEXT: ret 51; CHECK: .Lfunc_end2: 52; CHECK-NEXT: .size f2_1, .Lfunc_end2-f2_1 53; CHECK: .section __patchable_function_entries,"awo",@progbits,f2_1{{$}} 54; 32-NEXT: .p2align 2 55; 32-NEXT: .long .Ltmp0 56; 64-NEXT: .p2align 3 57; 64-NEXT: .quad .Ltmp0 58 ret void 59} 60 61;; -fpatchable-function-entry=1 -fcf-protection=branch 62;; For M=0, don't create .Lpatch0 if the initial instruction is not ENDBR, 63;; even if other basic blocks may have ENDBR. 64@buf = internal global [5 x i8*] zeroinitializer 65declare i32 @llvm.eh.sjlj.setjmp(i8*) 66 67define internal void @f1i() "patchable-function-entry"="1" { 68; CHECK-LABEL: f1i: 69; CHECK-NEXT: .Lfunc_begin3: 70; CHECK-NEXT: .cfi_startproc 71; CHECK-NEXT: # %bb.0: 72; CHECK-NEXT: nop 73; CHECK-NOT: .Lpatch0: 74;; Another basic block has ENDBR, but it doesn't affect our decision to not create .Lpatch0 75; CHECK: endbr 76; CHECK: .section __patchable_function_entries,"awo",@progbits,f1i{{$}} 77; 32-NEXT: .p2align 2 78; 32-NEXT: .long .Lfunc_begin3 79; 64-NEXT: .p2align 3 80; 64-NEXT: .quad .Lfunc_begin3 81entry: 82 tail call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([5 x i8*]* @buf to i8*)) 83 ret void 84} 85 86!llvm.module.flags = !{!0} 87 88!0 = !{i32 4, !"cf-protection-branch", i32 1} 89