mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
cbcd94df7b
Adjust the Win64 calling convention for Swift to pass self in R13, which is traditionally a CSR. This makes the behaviour similar to the SysV CC for Swift as well. This should improve the argument passing on Windows, although it comes at a high cost of ABI incompatibility. Fortunately in this case, there is no guarantee of ABI stability, and so we can make this incompatible change.
64 lines
2.0 KiB
LLVM
64 lines
2.0 KiB
LLVM
; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown-windows-msvc -o - %s | FileCheck --check-prefix=CHECK --check-prefix=OPT %s
|
|
; RUN: llc -O0 -verify-machineinstrs -mtriple=x86_64-unknown-windows-msvc -o - %s | FileCheck %s
|
|
|
|
; Parameter with swiftself should be allocated to r13.
|
|
; CHECK-LABEL: swiftself_param:
|
|
; CHECK: movq %r13, %rax
|
|
define i8 *@swiftself_param(i8* swiftself %addr0) {
|
|
ret i8 *%addr0
|
|
}
|
|
|
|
; Check that r13 is used to pass a swiftself argument.
|
|
; CHECK-LABEL: call_swiftself:
|
|
; CHECK: movq %rcx, %r13
|
|
; CHECK: callq swiftself_param
|
|
define i8 *@call_swiftself(i8* %arg) {
|
|
%res = call i8 *@swiftself_param(i8* swiftself %arg)
|
|
ret i8 *%res
|
|
}
|
|
|
|
; r13 should be saved by the callee even if used for swiftself
|
|
; CHECK-LABEL: swiftself_clobber:
|
|
; CHECK: pushq %r13
|
|
; ...
|
|
; CHECK: popq %r13
|
|
define i8 *@swiftself_clobber(i8* swiftself %addr0) {
|
|
call void asm sideeffect "nop", "~{r13}"()
|
|
ret i8 *%addr0
|
|
}
|
|
|
|
; Demonstrate that we do not need any movs when calling multiple functions
|
|
; with swiftself argument.
|
|
; CHECK-LABEL: swiftself_passthrough:
|
|
; OPT-NOT: mov{{.*}}r13
|
|
; OPT: callq swiftself_param
|
|
; OPT-NOT: mov{{.*}}r13
|
|
; OPT-NEXT: callq swiftself_param
|
|
define void @swiftself_passthrough(i8* swiftself %addr0) {
|
|
call i8 *@swiftself_param(i8* swiftself %addr0)
|
|
call i8 *@swiftself_param(i8* swiftself %addr0)
|
|
ret void
|
|
}
|
|
|
|
; We can use a tail call if the callee swiftself is the same as the caller one.
|
|
; This should also work with fast-isel.
|
|
; CHECK-LABEL: swiftself_tail:
|
|
; CHECK: jmp swiftself_param
|
|
; CHECK-NOT: ret
|
|
define i8* @swiftself_tail(i8* swiftself %addr0) {
|
|
call void asm sideeffect "", "~{r13}"()
|
|
%res = tail call i8* @swiftself_param(i8* swiftself %addr0)
|
|
ret i8* %res
|
|
}
|
|
|
|
; We can not use a tail call if the callee swiftself is not the same as the
|
|
; caller one.
|
|
; CHECK-LABEL: swiftself_notail:
|
|
; CHECK: movq %rcx, %r13
|
|
; CHECK: callq swiftself_param
|
|
; CHECK: retq
|
|
define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind {
|
|
%res = tail call i8* @swiftself_param(i8* swiftself %addr1)
|
|
ret i8* %res
|
|
}
|