[llvm] r281147 - It should also be legal to pass a swifterror parameter to a call as a swifterror

Arnold Schwaighofer via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 10 12:42:53 PDT 2016


Author: arnolds
Date: Sat Sep 10 14:42:53 2016
New Revision: 281147

URL: http://llvm.org/viewvc/llvm-project?rev=281147&view=rev
Log:
It should also be legal to pass a swifterror parameter to a call as a swifterror
argument.

rdar://28233388

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/test/CodeGen/X86/swifterror.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=281147&r1=281146&r2=281147&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Sat Sep 10 14:42:53 2016
@@ -1126,10 +1126,11 @@ Currently, only the following parameter
     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

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=281147&r1=281146&r2=281147&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Sat Sep 10 14:42:53 2016
@@ -2586,15 +2586,20 @@ void Verifier::verifyCallSite(CallSite C
   }
 
   // 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()) {

Modified: llvm/trunk/test/CodeGen/X86/swifterror.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/swifterror.ll?rev=281147&r1=281146&r2=281147&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/swifterror.ll (original)
+++ llvm/trunk/test/CodeGen/X86/swifterror.ll Sat Sep 10 14:42:53 2016
@@ -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
+}




More information about the llvm-commits mailing list