move the 'pretty 16-byte vector' inferring code up to be shared
with return values, improving stuff that returns __m128 etc.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109731 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 064a974..7321ba1 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -717,6 +717,8 @@
   /// also be ComplexX87.
   void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi) const;
 
+  const llvm::Type *Get16ByteVectorType(QualType Ty) const;
+
   const llvm::Type *Get8ByteTypeAtOffset(const llvm::Type *IRType,
                                          unsigned IROffset, QualType SourceTy,
                                          unsigned SourceOffset) const;
@@ -1179,6 +1181,26 @@
   return ABIArgInfo::getIndirect(0);
 }
 
+/// Get16ByteVectorType - The ABI specifies that a value should be passed in an
+/// full vector XMM register.  Pick an LLVM IR type that will be passed as a
+/// vector register.
+const llvm::Type *X86_64ABIInfo::Get16ByteVectorType(QualType Ty) const {
+  // If the preferred type is a 16-byte vector, prefer to pass it.
+  if (const llvm::VectorType *VT =
+      dyn_cast<llvm::VectorType>(CGT.ConvertTypeRecursive(Ty))){
+    const llvm::Type *EltTy = VT->getElementType();
+    if (VT->getBitWidth() == 128 &&
+        (EltTy->isFloatTy() || EltTy->isDoubleTy() ||
+         EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) ||
+         EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) ||
+         EltTy->isIntegerTy(128)))
+      return VT;
+  }
+  
+  return llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2);
+}
+
+
 /// Get8ByteTypeAtOffset - The ABI specifies that a value should be passed in an
 /// 8-byte GPR.  This means that we either have a scalar or we are talking about
 /// the high or low part of an up-to-16-byte struct.  This routine picks the
@@ -1316,7 +1338,7 @@
     // SSEUP should always be preceeded by SSE, just widen.
   case SSEUp:
     assert(Lo == SSE && "Unexpected SSEUp classification.");
-    ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2);
+    ResType = Get16ByteVectorType(RetTy);
     break;
 
     // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
@@ -1423,19 +1445,7 @@
     // register.  This only happens when 128-bit vectors are passed. 
   case SSEUp:
     assert(Lo == SSE && "Unexpected SSEUp classification");
-    ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2);
-      
-    // If the preferred type is a 16-byte vector, prefer to pass it.
-    if (const llvm::VectorType *VT =
-          dyn_cast<llvm::VectorType>(CGT.ConvertTypeRecursive(Ty))){
-      const llvm::Type *EltTy = VT->getElementType();
-      if (VT->getBitWidth() == 128 &&
-          (EltTy->isFloatTy() || EltTy->isDoubleTy() ||
-           EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) ||
-           EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) ||
-           EltTy->isIntegerTy(128)))
-        ResType = VT;
-    }
+    ResType = Get16ByteVectorType(Ty);
     break;
   }
 
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index 7bff700..ed1c9f1 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -155,7 +155,7 @@
 typedef float v4f32 __attribute__((__vector_size__(16)));
 
 v4f32 f25(v4f32 X) {
-  // CHECK: define <2 x double> @f25(<4 x float> %X.coerce)
+  // CHECK: define <4 x float> @f25(<4 x float> %X.coerce)
   return X+X;
 }