1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

It should also be legal to pass a swifterror parameter to a call as a swifterror

argument.

rdar://28233388

llvm-svn: 281147
This commit is contained in:
Arnold Schwaighofer 2016-09-10 19:42:53 +00:00
parent 4bbe59f1bf
commit 7d4fb4b444
3 changed files with 82 additions and 8 deletions

View File

@ -1126,10 +1126,11 @@ Currently, only the following parameter attributes are defined:
This attribute is motivated to model and optimize Swift error handling. It This attribute is motivated to model and optimize Swift error handling. It
can be applied to a parameter with pointer to pointer type or a can be applied to a parameter with pointer to pointer type or a
pointer-sized alloca. At the call site, the actual argument that corresponds pointer-sized alloca. At the call site, the actual argument that corresponds
to a ``swifterror`` parameter has to come from a ``swifterror`` alloca. A to a ``swifterror`` parameter has to come from a ``swifterror`` alloca or
``swifterror`` value (either the parameter or the alloca) can only be loaded the ``swifterror`` parameter of the caller. A ``swifterror`` value (either
and stored from, or used as a ``swifterror`` argument. This is not a valid the parameter or the alloca) can only be loaded and stored from, or used as
attribute for return values and can only be applied to one parameter. a ``swifterror`` argument. This is not a valid attribute for return values
and can only be applied to one parameter.
These constraints allow the calling convention to optimize access to These constraints allow the calling convention to optimize access to
``swifterror`` variables by associating them with a specific register at ``swifterror`` variables by associating them with a specific register at

View File

@ -2586,15 +2586,20 @@ void Verifier::verifyCallSite(CallSite CS) {
} }
// For each argument of the callsite, if it has the swifterror argument, // For each argument of the callsite, if it has the swifterror argument,
// make sure the underlying alloca has swifterror as well. // make sure the underlying alloca/parameter it comes from has a swifterror as
// well.
for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i)
if (CS.paramHasAttr(i+1, Attribute::SwiftError)) { if (CS.paramHasAttr(i+1, Attribute::SwiftError)) {
Value *SwiftErrorArg = CS.getArgument(i); Value *SwiftErrorArg = CS.getArgument(i);
auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets()); if (auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets())) {
Assert(AI, "swifterror argument should come from alloca", AI, I);
if (AI)
Assert(AI->isSwiftError(), Assert(AI->isSwiftError(),
"swifterror argument for call has mismatched alloca", AI, I); "swifterror argument for call has mismatched alloca", AI, I);
continue;
}
auto ArgI = dyn_cast<Argument>(SwiftErrorArg);
Assert(ArgI, "swifterror argument should come from an alloca or parameter", SwiftErrorArg, I);
Assert(ArgI->hasSwiftErrorAttr(),
"swifterror argument for call has mismatched parameter", ArgI, I);
} }
if (FTy->isVarArg()) { if (FTy->isVarArg()) {

View File

@ -398,3 +398,71 @@ entry:
store i8 1, i8* %tmp store i8 1, i8* %tmp
ret float 1.0 ret float 1.0
} }
declare swiftcc float @moo(%swift_error** swifterror)
; Test parameter forwarding.
define swiftcc float @forward_swifterror(%swift_error** swifterror %error_ptr_ref) {
; CHECK-APPLE-LABEL: forward_swifterror:
; CHECK-APPLE: pushq %rax
; CHECK-APPLE: callq _moo
; CHECK-APPLE: popq %rax
; CHECK-APPLE: retq
; CHECK-O0-LABEL: forward_swifterror:
; CHECK-O0: subq $24, %rsp
; CHECK-O0: movq %r12, %rcx
; CHECK-O0: movq %rcx, 16(%rsp)
; CHECK-O0: movq %rax, 8(%rsp)
; CHECK-O0: callq _moo
; CHECK-O0: addq $24, %rsp
; CHECK-O0: retq
entry:
%call = call swiftcc float @moo(%swift_error** swifterror %error_ptr_ref)
ret float %call
}
define swiftcc float @conditionally_forward_swifterror(%swift_error** swifterror %error_ptr_ref, i32 %cc) {
; CHECK-APPLE-LABEL: conditionally_forward_swifterror:
; CHECK-APPLE: pushq %rax
; CHECK-APPLE: testl %edi, %edi
; CHECK-APPLE: je
; CHECK-APPLE: callq _moo
; CHECK-APPLE: popq %rax
; CHECK-APPLE: retq
; CHECK-APPLE: xorps %xmm0, %xmm0
; CHECK-APPLE: popq %rax
; CHECK-APPLE: retq
; CHECK-O0-LABEL: conditionally_forward_swifterror:
; CHECK-O0: subq $24, %rsp
; CHECK-O0: movq %r12, %rcx
; CHECK-O0: cmpl $0, %edi
; CHECK-O0: movq %rax, 16(%rsp)
; CHECK-O0: movq %r12, 8(%rsp)
; CHECK-O0: movq %rcx, (%rsp)
; CHECK-O0: je
; CHECK-O0: movq 8(%rsp), %r12
; CHECK-O0: callq _moo
; CHECK-O0: addq $24, %rsp
; CHECK-O0: retq
; CHECK-O0: xorps %xmm0, %xmm0
; CHECK-O0: movq 8(%rsp), %r12
; CHECK-O0: addq $24, %rsp
; CHECK-O0: retq
entry:
%cond = icmp ne i32 %cc, 0
br i1 %cond, label %gen_error, label %normal
gen_error:
%call = call swiftcc float @moo(%swift_error** swifterror %error_ptr_ref)
ret float %call
normal:
ret float 0.0
}