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