1 ; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown-unknown -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT %s 2 ; RUN: llc -O0 -verify-machineinstrs -mtriple=x86_64-unknown-unknown -o - %s | FileCheck %s 3 4 ; Parameter with swiftself should be allocated to r13. 5 ; CHECK-LABEL: swiftself_param: 6 ; CHECK: movq %r13, %rax 7 define i8 *@swiftself_param(i8* swiftself %addr0) { 8 ret i8 *%addr0 9 } 10 11 ; Check that r13 is used to pass a swiftself argument. 12 ; CHECK-LABEL: call_swiftself: 13 ; CHECK: movq %rdi, %r13 14 ; CHECK: callq {{_?}}swiftself_param 15 define i8 *@call_swiftself(i8* %arg) { 16 %res = call i8 *@swiftself_param(i8* swiftself %arg) 17 ret i8 *%res 18 } 19 20 ; r13 should be saved by the callee even if used for swiftself 21 ; CHECK-LABEL: swiftself_clobber: 22 ; CHECK: pushq %r13 23 ; ... 24 ; CHECK: popq %r13 25 define i8 *@swiftself_clobber(i8* swiftself %addr0) { 26 call void asm sideeffect "nop", "~{r13}"() 27 ret i8 *%addr0 28 } 29 30 ; Demonstrate that we do not need any movs when calling multiple functions 31 ; with swiftself argument. 32 ; CHECK-LABEL: swiftself_passthrough: 33 ; OPT-NOT: mov{{.*}}r13 34 ; OPT: callq {{_?}}swiftself_param 35 ; OPT-NOT: mov{{.*}}r13 36 ; OPT-NEXT: callq {{_?}}swiftself_param 37 define void @swiftself_passthrough(i8* swiftself %addr0) { 38 call i8 *@swiftself_param(i8* swiftself %addr0) 39 call i8 *@swiftself_param(i8* swiftself %addr0) 40 ret void 41 } 42 43 ; We can use a tail call if the callee swiftself is the same as the caller one. 44 ; CHECK-LABEL: swiftself_tail: 45 ; OPT: jmp {{_?}}swiftself_param 46 ; OPT-NOT: ret 47 define i8* @swiftself_tail(i8* swiftself %addr0) { 48 call void asm sideeffect "", "~{r13}"() 49 %res = tail call i8* @swiftself_param(i8* swiftself %addr0) 50 ret i8* %res 51 } 52 53 ; We can not use a tail call if the callee swiftself is not the same as the 54 ; caller one. 55 ; CHECK-LABEL: swiftself_notail: 56 ; CHECK: movq %rdi, %r13 57 ; CHECK: callq {{_?}}swiftself_param 58 ; CHECK: retq 59 define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind { 60 %res = tail call i8* @swiftself_param(i8* swiftself %addr1) 61 ret i8* %res 62 } 63