[llvm] r267579 - Swift Calling Convention: use %RAX for sret.

Manman Ren via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 26 11:08:07 PDT 2016


Author: mren
Date: Tue Apr 26 13:08:06 2016
New Revision: 267579

URL: http://llvm.org/viewvc/llvm-project?rev=267579&view=rev
Log:
Swift Calling Convention: use %RAX for sret.

We don't need to copy the sret argument into %rax upon return.
rdar://25671494

Modified:
    llvm/trunk/lib/Target/X86/X86CallingConv.td
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/test/CodeGen/X86/swift-return.ll

Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=267579&r1=267578&r2=267579&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CallingConv.td (original)
+++ llvm/trunk/lib/Target/X86/X86CallingConv.td Tue Apr 26 13:08:06 2016
@@ -303,6 +303,10 @@ def CC_X86_64_C : CallingConv<[
   // A SwiftError is passed in R12.
   CCIfSwiftError<CCIfType<[i64], CCAssignToReg<[R12]>>>,
 
+  // For Swift Calling Convention, pass sret in %RAX.
+  CCIfCC<"CallingConv::Swift",
+    CCIfSRet<CCIfType<[i64], CCAssignToReg<[RAX]>>>>,
+
   // The first 6 integer arguments are passed in integer registers.
   CCIfType<[i32], CCAssignToReg<[EDI, ESI, EDX, ECX, R8D, R9D]>>,
   CCIfType<[i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>,

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=267579&r1=267578&r2=267579&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Tue Apr 26 13:08:06 2016
@@ -1121,11 +1121,14 @@ bool X86FastISel::X86SelectRet(const Ins
     RetRegs.push_back(VA.getLocReg());
   }
 
+  // Swift calling convention does not require we copy the sret argument
+  // into %rax/%eax for the return, and SRetReturnReg is not set for Swift.
+
   // All x86 ABIs require that for returning structs by value we copy
   // the sret argument into %rax/%eax (depending on ABI) for the return.
   // We saved the argument into a virtual register in the entry block,
   // so now we copy the value out and into %rax/%eax.
-  if (F.hasStructRetAttr()) {
+  if (F.hasStructRetAttr() && CC != CallingConv::Swift) {
     unsigned Reg = X86MFInfo->getSRetReturnReg();
     assert(Reg &&
            "SRetReturnReg should have been set in LowerFormalArguments()!");

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=267579&r1=267578&r2=267579&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Apr 26 13:08:06 2016
@@ -2082,6 +2082,9 @@ X86TargetLowering::LowerReturn(SDValue C
     RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
   }
 
+  // Swift calling convention does not require we copy the sret argument
+  // into %rax/%eax for the return, and SRetReturnReg is not set for Swift.
+
   // All x86 ABIs require that for returning structs by value we copy
   // the sret argument into %rax/%eax (depending on ABI) for the return.
   // We saved the argument into a virtual register in the entry block,
@@ -2610,6 +2613,11 @@ SDValue X86TargetLowering::LowerFormalAr
   }
 
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+    // Swift calling convention does not require we copy the sret argument
+    // into %rax/%eax for the return. We don't set SRetReturnReg for Swift.
+    if (CallConv == CallingConv::Swift)
+      continue;
+
     // All x86 ABIs require that for returning structs by value we copy the
     // sret argument into %rax/%eax (depending on ABI) for the return. Save
     // the argument into a virtual register so that we can access it from the

Modified: llvm/trunk/test/CodeGen/X86/swift-return.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/swift-return.ll?rev=267579&r1=267578&r2=267579&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/swift-return.ll (original)
+++ llvm/trunk/test/CodeGen/X86/swift-return.ll Tue Apr 26 13:08:06 2016
@@ -36,10 +36,9 @@ declare swiftcc { i16, i8 } @gen(i32)
 
 ; If we can't pass every return value in register, we will pass everything
 ; in memroy. The caller provides space for the return value and passes
-; the address in %rdi. The first input argument will be in %rsi.
+; the address in %rax. The first input argument will be in %rdi.
 ; CHECK-LABEL: test2:
-; CHECK: leaq (%rsp), %rdi
-; CHECK: movl %{{.*}}, %esi
+; CHECK: leaq (%rsp), %rax
 ; CHECK: callq gen2
 ; CHECK: movl (%rsp)
 ; CHECK-DAG: addl 4(%rsp)
@@ -47,8 +46,7 @@ declare swiftcc { i16, i8 } @gen(i32)
 ; CHECK-DAG: addl 12(%rsp)
 ; CHECK-DAG: addl 16(%rsp)
 ; CHECK-O0-LABEL: test2:
-; CHECK-O0-DAG: leaq (%rsp), %rdi
-; CHECK-O0-DAG: movl {{.*}}, %esi
+; CHECK-O0-DAG: leaq (%rsp), %rax
 ; CHECK-O0: callq gen2
 ; CHECK-O0-DAG: movl (%rsp)
 ; CHECK-O0-DAG: movl 4(%rsp)
@@ -80,22 +78,20 @@ entry:
   ret i32 %add3
 }
 
-; The address of the return value is passed in %rdi.
-; On return, %rax will contain the adddress that has been passed in by the caller in %rdi.
+; The address of the return value is passed in %rax.
+; On return, we don't keep the address in %rax.
 ; CHECK-LABEL: gen2:
-; CHECK: movl %esi, 16(%rdi)
-; CHECK: movl %esi, 12(%rdi)
-; CHECK: movl %esi, 8(%rdi)
-; CHECK: movl %esi, 4(%rdi)
-; CHECK: movl %esi, (%rdi)
-; CHECK: movq %rdi, %rax
+; CHECK: movl %edi, 16(%rax)
+; CHECK: movl %edi, 12(%rax)
+; CHECK: movl %edi, 8(%rax)
+; CHECK: movl %edi, 4(%rax)
+; CHECK: movl %edi, (%rax)
 ; CHECK-O0-LABEL: gen2:
-; CHECK-O0-DAG: movl %esi, 16(%rdi)
-; CHECK-O0-DAG: movl %esi, 12(%rdi)
-; CHECK-O0-DAG: movl %esi, 8(%rdi)
-; CHECK-O0-DAG: movl %esi, 4(%rdi)
-; CHECK-O0-DAG: movl %esi, (%rdi)
-; CHECK-O0-DAG: movq %rdi, %rax
+; CHECK-O0-DAG: movl %edi, 16(%rax)
+; CHECK-O0-DAG: movl %edi, 12(%rax)
+; CHECK-O0-DAG: movl %edi, 8(%rax)
+; CHECK-O0-DAG: movl %edi, 4(%rax)
+; CHECK-O0-DAG: movl %edi, (%rax)
 define swiftcc { i32, i32, i32, i32, i32 } @gen2(i32 %key) {
   %Y = insertvalue { i32, i32, i32, i32, i32 } undef, i32 %key, 0
   %Z = insertvalue { i32, i32, i32, i32, i32 } %Y, i32 %key, 1
@@ -199,3 +195,12 @@ define void @consume_i1_ret() {
 }
 
 declare swiftcc { i1, i1, i1, i1 } @produce_i1_ret()
+
+; CHECK-LABEL: foo:
+; CHECK: movq %rdi, (%rax)
+; CHECK-O0-LABEL: foo:
+; CHECK-O0: movq %rdi, (%rax)
+define swiftcc void @foo(i64* sret %agg.result, i64 %val) {
+  store i64 %val, i64* %agg.result
+  ret void
+}




More information about the llvm-commits mailing list