1; RUN: llc -mtriple=aarch64 %s -o - | FileCheck --check-prefixes=CHECK,NOFSECT %s 2; RUN: llc -mtriple=aarch64 -function-sections %s -o - | FileCheck --check-prefixes=CHECK,FSECT %s 3; RUN: llc -mtriple=aarch64 -no-integrated-as %s -o - | FileCheck --check-prefix=NOLINK %s 4 5; NOLINK-NOT: "awo" 6; NOLINK-NOT: ,unique,0 7 8define i32 @f0() "patchable-function-entry"="0" { 9; CHECK-LABEL: f0: 10; CHECK-NEXT: .Lfunc_begin0: 11; CHECK-NOT: nop 12; CHECK: mov w0, wzr 13; CHECK-NOT: .section __patchable_function_entries 14 ret i32 0 15} 16 17define i32 @f1() "patchable-function-entry"="1" { 18; CHECK-LABEL: f1: 19; CHECK-NEXT: .Lfunc_begin1: 20; CHECK: nop 21; CHECK-NEXT: mov w0, wzr 22; CHECK: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 23; CHECK-NEXT: .p2align 3 24; CHECK-NEXT: .xword .Lfunc_begin1 25 ret i32 0 26} 27 28;; Without -function-sections, f2 is in the same text section as f1. 29;; They share the __patchable_function_entries section. 30;; With -function-sections, f1 and f2 are in different text sections. 31;; Use separate __patchable_function_entries. 32define void @f2() "patchable-function-entry"="2" { 33; CHECK-LABEL: f2: 34; CHECK-NEXT: .Lfunc_begin2: 35; CHECK-COUNT-2: nop 36; CHECK-NEXT: ret 37; NOFSECT: .section __patchable_function_entries,"awo",@progbits,f1,unique,0 38; FSECT: .section __patchable_function_entries,"awo",@progbits,f2,unique,1 39; CHECK-NEXT: .p2align 3 40; CHECK-NEXT: .xword .Lfunc_begin2 41 ret void 42} 43 44$f3 = comdat any 45define void @f3() "patchable-function-entry"="3" comdat { 46; CHECK-LABEL: f3: 47; CHECK-NEXT: .Lfunc_begin3: 48; CHECK-COUNT-3: nop 49; CHECK-NEXT: ret 50; NOFSECT: .section __patchable_function_entries,"aGwo",@progbits,f3,comdat,f3,unique,1 51; FSECT: .section __patchable_function_entries,"aGwo",@progbits,f3,comdat,f3,unique,2 52; CHECK-NEXT: .p2align 3 53; CHECK-NEXT: .xword .Lfunc_begin3 54 ret void 55} 56 57$f5 = comdat any 58define void @f5() "patchable-function-entry"="5" comdat { 59; CHECK-LABEL: f5: 60; CHECK-NEXT: .Lfunc_begin4: 61; CHECK-COUNT-5: nop 62; CHECK-NEXT: sub sp, sp, #16 63; NOFSECT .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5,unique,2 64; FSECT: .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5,unique,3 65; CHECK: .p2align 3 66; CHECK-NEXT: .xword .Lfunc_begin4 67 %frame = alloca i8, i32 16 68 ret void 69} 70 71;; -fpatchable-function-entry=3,2 72;; "patchable-function-prefix" emits data before the function entry label. 73define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" { 74; CHECK-LABEL: .type f3_2,@function 75; CHECK-NEXT: .Ltmp1: // @f3_2 76; CHECK-NEXT: nop 77; CHECK-NEXT: nop 78; CHECK-NEXT: f3_2: 79; CHECK: // %bb.0: 80; CHECK-NEXT: nop 81; CHECK-NEXT: ret 82;; .size does not include the prefix. 83; CHECK: .Lfunc_end5: 84; CHECK-NEXT: .size f3_2, .Lfunc_end5-f3_2 85; NOFSECT .section __patchable_function_entries,"awo",@progbits,f1,unique,0 86; FSECT: .section __patchable_function_entries,"awo",@progbits,f3_2,unique,4 87; CHECK: .p2align 3 88; CHECK-NEXT: .xword .Ltmp1 89 ret void 90} 91 92;; When prefix data is used, arbitrarily place NOPs after prefix data. 93define void @prefix() "patchable-function-entry"="0" "patchable-function-prefix"="1" prefix i32 1 { 94; CHECK-LABEL: .type prefix,@function 95; CHECK-NEXT: .word 1 // @prefix 96; CHECK: .Ltmp2: 97; CHECK: nop 98; CHECK-NEXT: prefix: 99;; Emit a __patchable_function_entries entry even if "patchable-function-entry" is 0. 100; NOFSECT .section __patchable_function_entries,"awo",@progbits,prefix,unique,0 101; FSECT: .section __patchable_function_entries,"awo",@progbits,prefix,unique,5 102; CHECK: .p2align 3 103; CHECK-NEXT: .xword .Ltmp2 104 ret void 105} 106