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 -no-integrated-as %s -o - | FileCheck --check-prefix=NOLINK %s 4 5;; GNU as < 2.35 did not support section flag 'o'. 6; NOLINK-NOT: "awo" 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{{$}} 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; CHECK: .section __patchable_function_entries,"awo",@progbits,f2{{$}} 38; CHECK-NEXT: .p2align 3 39; CHECK-NEXT: .xword .Lfunc_begin2 40 ret void 41} 42 43$f3 = comdat any 44define void @f3() "patchable-function-entry"="3" comdat { 45; CHECK-LABEL: f3: 46; CHECK-NEXT: .Lfunc_begin3: 47; CHECK-COUNT-3: nop 48; CHECK-NEXT: ret 49; CHECK: .section __patchable_function_entries,"aGwo",@progbits,f3,comdat,f3{{$}} 50; CHECK-NEXT: .p2align 3 51; CHECK-NEXT: .xword .Lfunc_begin3 52 ret void 53} 54 55$f5 = comdat any 56define void @f5() "patchable-function-entry"="5" comdat { 57; CHECK-LABEL: f5: 58; CHECK-NEXT: .Lfunc_begin4: 59; CHECK-COUNT-5: nop 60; CHECK-NEXT: sub sp, sp, #16 61; CHECK: .section __patchable_function_entries,"aGwo",@progbits,f5,comdat,f5{{$}} 62; CHECK: .p2align 3 63; CHECK-NEXT: .xword .Lfunc_begin4 64 %frame = alloca i8, i32 16 65 ret void 66} 67 68;; -fpatchable-function-entry=3,2 69;; "patchable-function-prefix" emits data before the function entry label. 70define void @f3_2() "patchable-function-entry"="1" "patchable-function-prefix"="2" { 71; CHECK-LABEL: .type f3_2,@function 72; CHECK-NEXT: .Ltmp1: // @f3_2 73; CHECK-NEXT: nop 74; CHECK-NEXT: nop 75; CHECK-NEXT: f3_2: 76; CHECK: // %bb.0: 77; CHECK-NEXT: nop 78; CHECK-NEXT: ret 79;; .size does not include the prefix. 80; CHECK: .Lfunc_end5: 81; CHECK-NEXT: .size f3_2, .Lfunc_end5-f3_2 82; CHECK: .section __patchable_function_entries,"awo",@progbits,f3_2{{$}} 83; CHECK: .p2align 3 84; CHECK-NEXT: .xword .Ltmp1 85 ret void 86} 87 88;; When prefix data is used, arbitrarily place NOPs after prefix data. 89define void @prefix() "patchable-function-entry"="0" "patchable-function-prefix"="1" prefix i32 1 { 90; CHECK-LABEL: .type prefix,@function 91; CHECK-NEXT: .word 1 // @prefix 92; CHECK: .Ltmp2: 93; CHECK: nop 94; CHECK-NEXT: prefix: 95;; Emit a __patchable_function_entries entry even if "patchable-function-entry" is 0. 96; CHECK: .section __patchable_function_entries,"awo",@progbits,prefix{{$}} 97; CHECK: .p2align 3 98; CHECK-NEXT: .xword .Ltmp2 99 ret void 100} 101