1; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s -global-isel | FileCheck %s 2 3; Parameter with swiftself should be allocated to x20. 4; CHECK-LABEL: swiftself_param: 5; CHECK: mov x0, x20 6; CHECK-NEXT: ret 7define i8* @swiftself_param(i8* swiftself %addr0) { 8 ret i8 *%addr0 9} 10 11; Check that x20 is used to pass a swiftself argument. 12; CHECK-LABEL: call_swiftself: 13; CHECK: mov x20, x0 14; CHECK: bl {{_?}}swiftself_param 15; CHECK: ret 16define i8 *@call_swiftself(i8* %arg) { 17 %res = call i8 *@swiftself_param(i8* swiftself %arg) 18 ret i8 *%res 19} 20 21; Demonstrate that we do not need any movs when calling multiple functions 22; with swiftself argument. 23; CHECK-LABEL: swiftself_passthrough: 24; CHECK-NOT: mov{{.*}}x20 25; CHECK: bl {{_?}}swiftself_param 26; CHECK-NOT: mov{{.*}}x20 27; CHECK-NEXT: bl {{_?}}swiftself_param 28; CHECK: ret 29define void @swiftself_passthrough(i8* swiftself %addr0) { 30 call i8 *@swiftself_param(i8* swiftself %addr0) 31 call i8 *@swiftself_param(i8* swiftself %addr0) 32 ret void 33} 34 35; We can not use a tail call if the callee swiftself is not the same as the 36; caller one. 37; CHECK-LABEL: swiftself_notail: 38; CHECK: mov x20, x0 39; CHECK: bl {{_?}}swiftself_param 40; CHECK: ret 41define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind { 42 %res = tail call i8* @swiftself_param(i8* swiftself %addr1) 43 ret i8* %res 44} 45 46; We cannot pretend that 'x0' is alive across the thisreturn_attribute call as 47; we normally would. We marked the first parameter with swiftself which means it 48; will no longer be passed in x0. 49declare swiftcc i8* @thisreturn_attribute(i8* returned swiftself) 50; CHECK-LABEL: swiftself_nothisreturn: 51; CHECK-DAG: ldr x20, [x20] 52; CHECK-DAG: mov [[CSREG:x[1-9].*]], x8 53; CHECK: bl {{_?}}thisreturn_attribute 54; CHECK: str x0, {{\[}}[[CSREG]] 55; CHECK: ret 56define hidden swiftcc void @swiftself_nothisreturn(i8** noalias nocapture sret(i8*), i8** noalias nocapture readonly swiftself) { 57entry: 58 %2 = load i8*, i8** %1, align 8 59 %3 = tail call swiftcc i8* @thisreturn_attribute(i8* swiftself %2) 60 store i8* %3, i8** %0, align 8 61 ret void 62} 63 64; Check that x20 is used to pass a swiftself argument when the parameter is 65; only in the declaration's arguments. 66; CHECK-LABEL: _swiftself_not_on_call_params: 67; CHECK: mov x20, x0 68; CHECK: bl {{_?}}swiftself_param 69; CHECK: ret 70define i8 *@swiftself_not_on_call_params(i8* %arg) { 71 %res = call i8 *@swiftself_param(i8* %arg) 72 ret i8 *%res 73} 74