]> granicus.if.org Git - clang/commitdiff
x86-32 Darwin ABI: Handle direct return of vectors.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 1 Apr 2009 06:13:08 +0000 (06:13 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 1 Apr 2009 06:13:08 +0000 (06:13 +0000)
 - Current return-arguments-32 status is: 8 out of 1000 failures (-7)

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68192 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
test/CodeGen/x86_32-arguments.c

index 291e476f0bd719e9f67d0147f9f71d0cdd9558f7..58e448949e70411d6bada75c7a5995f5a69d9aa9 100644 (file)
@@ -278,6 +278,28 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
                                             ASTContext &Context) const {
   if (RetTy->isVoidType()) {
     return ABIArgInfo::getIgnore();
+  } else if (const VectorType *VT = RetTy->getAsVectorType()) {
+    // On Darwin, some vectors are returned in registers.
+    if (IsDarwin) {
+      uint64_t Size = Context.getTypeSize(RetTy);
+
+      // 128-bit vectors are a special case; they are returned in
+      // registers and we need to make sure to pick a type the LLVM
+      // backend will like.
+      if (Size == 128)
+        return ABIArgInfo::getCoerce(llvm::VectorType::get(llvm::Type::Int64Ty, 
+                                                           2));
+
+      // Always return in register if it fits in a general purpose
+      // register, or if it is 64 bits and has a single element.
+      if ((Size == 8 || Size == 16 || Size == 32) ||
+          (Size == 64 && VT->getNumElements() == 1))
+        return ABIArgInfo::getCoerce(llvm::IntegerType::get(Size));
+        
+      return ABIArgInfo::getIndirect(0);
+    }
+
+    return ABIArgInfo::getDirect();
   } else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
     // Outside of Darwin, structs and unions are always indirect.
     if (!IsDarwin && !RetTy->isAnyComplexType())
index 933489518627601f47a22b4d7042ae00054c04e2..58637d52532290f363fa92b86d24cd272f34b3dd 100644 (file)
@@ -71,5 +71,19 @@ struct s10 {
   float f;
 } f10(void) {}
 
-// RUN: true
+// Small vectors and 1 x {i64,double} are returned in registers...
+
+// RUN: grep 'i32 @f11()' %t &&
+// RUN: grep -F 'void @f12(<2 x i32>* noalias sret %agg.result)' %t &&
+// RUN: grep 'i64 @f13()' %t &&
+// RUN: grep 'i64 @f14()' %t &&
+typedef short T11 __attribute__ ((vector_size (4)));
+T11 f11(void) {}
+typedef int T12 __attribute__ ((vector_size (8)));
+T12 f12(void) {}
+typedef long long T13 __attribute__ ((vector_size (8)));
+T13 f13(void) {}
+typedef double T14 __attribute__ ((vector_size (8)));
+T14 f14(void) {}
 
+// RUN: true