mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[ARM/AArch ISel] SwiftCC: First parameters that are marked swiftself are not 'this returns'
We mark X0 as preserved by a call that passes the returned parameter. x0 = ... fun(x0) // no implicit def of x0 This no longer is valid if we pass the parameter in a different register then the returned value as is the case with a swiftself parameter (passed in x20). x20 = ... fun(x20) // there should be an implict def of x8 rdar://30425845 llvm-svn: 294527
This commit is contained in:
parent
31a9f40bfd
commit
133aefc634
@ -3156,7 +3156,8 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
|
||||
}
|
||||
|
||||
if (VA.isRegLoc()) {
|
||||
if (realArgIdx == 0 && Flags.isReturned() && Outs[0].VT == MVT::i64) {
|
||||
if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
|
||||
Outs[0].VT == MVT::i64) {
|
||||
assert(VA.getLocVT() == MVT::i64 &&
|
||||
"unexpected calling convention register assignment");
|
||||
assert(!Ins.empty() && Ins[0].VT == MVT::i64 &&
|
||||
|
@ -1826,7 +1826,8 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
StackPtr, MemOpChains, Flags);
|
||||
}
|
||||
} else if (VA.isRegLoc()) {
|
||||
if (realArgIdx == 0 && Flags.isReturned() && Outs[0].VT == MVT::i32) {
|
||||
if (realArgIdx == 0 && Flags.isReturned() && !Flags.isSwiftSelf() &&
|
||||
Outs[0].VT == MVT::i32) {
|
||||
assert(VA.getLocVT() == MVT::i32 &&
|
||||
"unexpected calling convention register assignment");
|
||||
assert(!Ins.empty() && Ins[0].VT == MVT::i32 &&
|
||||
|
@ -65,3 +65,21 @@ define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind {
|
||||
%res = tail call i8* @swiftself_param(i8* swiftself %addr1)
|
||||
ret i8* %res
|
||||
}
|
||||
|
||||
; We cannot pretend that 'x0' is alive across the thisreturn_attribute call as
|
||||
; we normally would. We marked the first parameter with swiftself which means it
|
||||
; will no longer be passed in x0.
|
||||
declare swiftcc i8* @thisreturn_attribute(i8* returned swiftself)
|
||||
; OPT-LABEL: swiftself_nothisreturn:
|
||||
; OPT-DAG: ldr x20, [x20]
|
||||
; OPT-DAG: mov [[CSREG:x[1-9].*]], x8
|
||||
; OPT: bl {{_?}}thisreturn_attribute
|
||||
; OPT: str x0, {{\[}}[[CSREG]]
|
||||
; OPT: ret
|
||||
define hidden swiftcc void @swiftself_nothisreturn(i8** noalias nocapture sret, i8** noalias nocapture readonly swiftself) {
|
||||
entry:
|
||||
%2 = load i8*, i8** %1, align 8
|
||||
%3 = tail call swiftcc i8* @thisreturn_attribute(i8* swiftself %2)
|
||||
store i8* %3, i8** %0, align 8
|
||||
ret void
|
||||
}
|
||||
|
@ -63,3 +63,20 @@ define i8* @swiftself_notail(i8* swiftself %addr0, i8* %addr1) nounwind "no-fram
|
||||
%res = tail call i8* @swiftself_param(i8* swiftself %addr1)
|
||||
ret i8* %res
|
||||
}
|
||||
|
||||
; We cannot pretend that 'r0' is alive across the thisreturn_attribute call as
|
||||
; we normally would. We marked the first parameter with swiftself which means it
|
||||
; will no longer be passed in r0.
|
||||
declare swiftcc i8* @thisreturn_attribute(i8* returned swiftself)
|
||||
; OPT-LABEL: swiftself_nothisreturn:
|
||||
; OPT-DAG: mov [[CSREG:r[1-9].*]], r0
|
||||
; OPT-DAG: ldr r10, [r10]
|
||||
; OPT: bl {{_?}}thisreturn_attribute
|
||||
; OPT: str r0, {{\[}}[[CSREG]]
|
||||
define hidden swiftcc void @swiftself_nothisreturn(i8** noalias nocapture sret, i8** noalias nocapture readonly swiftself) {
|
||||
entry:
|
||||
%2 = load i8*, i8** %1, align 8
|
||||
%3 = tail call swiftcc i8* @thisreturn_attribute(i8* swiftself %2)
|
||||
store i8* %3, i8** %0, align 8
|
||||
ret void
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user