summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorArnold Schwaighofer <aschwaighofer@apple.com>2016-09-10 19:42:53 +0000
committerArnold Schwaighofer <aschwaighofer@apple.com>2016-09-10 19:42:53 +0000
commit6c57f4f56dbeea75afe22cd08332d415c2601f37 (patch)
tree45a4b85ad520d90f04f6fbdb6082bbeefd0bdecd /llvm
parentb1c174aa1c2a4a903b728625f646d075a861ece4 (diff)
downloadbcm5719-llvm-6c57f4f56dbeea75afe22cd08332d415c2601f37.tar.gz
bcm5719-llvm-6c57f4f56dbeea75afe22cd08332d415c2601f37.zip
It should also be legal to pass a swifterror parameter to a call as a swifterror
argument. rdar://28233388 llvm-svn: 281147
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/LangRef.rst9
-rw-r--r--llvm/lib/IR/Verifier.cpp13
-rw-r--r--llvm/test/CodeGen/X86/swifterror.ll68
3 files changed, 82 insertions, 8 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index b2ac11b5ee1..917a54622a8 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1126,10 +1126,11 @@ Currently, only the following parameter attributes are defined:
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
pointer-sized alloca. At the call site, the actual argument that corresponds
- to a ``swifterror`` parameter has to come from a ``swifterror`` alloca. A
- ``swifterror`` value (either the parameter or the alloca) can only be loaded
- and stored from, or used as a ``swifterror`` argument. This is not a valid
- attribute for return values and can only be applied to one parameter.
+ to a ``swifterror`` parameter has to come from a ``swifterror`` alloca or
+ the ``swifterror`` parameter of the caller. A ``swifterror`` value (either
+ the parameter or the alloca) can only be loaded and stored from, or used as
+ 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
``swifterror`` variables by associating them with a specific register at
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 6e9eb7476a1..ba7db85094e 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -2586,15 +2586,20 @@ void Verifier::verifyCallSite(CallSite CS) {
}
// 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)
if (CS.paramHasAttr(i+1, Attribute::SwiftError)) {
Value *SwiftErrorArg = CS.getArgument(i);
- auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets());
- Assert(AI, "swifterror argument should come from alloca", AI, I);
- if (AI)
+ if (auto AI = dyn_cast<AllocaInst>(SwiftErrorArg->stripInBoundsOffsets())) {
Assert(AI->isSwiftError(),
"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()) {
diff --git a/llvm/test/CodeGen/X86/swifterror.ll b/llvm/test/CodeGen/X86/swifterror.ll
index 21695cbc003..b1e82e54328 100644
--- a/llvm/test/CodeGen/X86/swifterror.ll
+++ b/llvm/test/CodeGen/X86/swifterror.ll
@@ -398,3 +398,71 @@ entry:
store i8 1, i8* %tmp
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
+}
OpenPOWER on IntegriCloud