]> granicus.if.org Git - clang/commitdiff
ignore structs that wrap vectors in IR, the abstraction shouldn't add penalty.
authorChris Lattner <sabre@nondot.org>
Thu, 29 Jul 2010 05:02:29 +0000 (05:02 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 29 Jul 2010 05:02:29 +0000 (05:02 +0000)
Before we'd compile the example into something like:

  %coerce.dive2 = getelementptr %struct.v4f32wrapper* %retval, i32 0, i32 0 ; <<4 x float>*> [#uses=1]
  %1 = bitcast <4 x float>* %coerce.dive2 to <2 x double>* ; <<2 x double>*> [#uses=1]
  %2 = load <2 x double>* %1, align 1             ; <<2 x double>> [#uses=1]
  ret <2 x double> %2

Now we produce:

  %coerce.dive2 = getelementptr %struct.v4f32wrapper* %retval, i32 0, i32 0 ; <<4 x float>*> [#uses=1]
  %0 = load <4 x float>* %coerce.dive2, align 1   ; <<4 x float>> [#uses=1]
  ret <4 x float> %0

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

lib/CodeGen/TargetInfo.cpp
test/CodeGen/x86_64-arguments.c

index 7321ba148caff73a547652715102e72f816dc432..e8e4c5c4622c75ea828f7e59a2ff74c77f585c4e 100644 (file)
@@ -1185,9 +1185,20 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const {
 /// 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 {
+  const llvm::Type *IRType = CGT.ConvertTypeRecursive(Ty);
+  
+  // Wrapper structs that just contain vectors are passed just like vectors,
+  // strip them off if present.
+  const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType);
+  while (STy && STy->getNumElements() == 1) {
+    IRType = STy->getElementType(0);
+    STy = dyn_cast<llvm::StructType>(IRType);
+  }
+  
+  
+  
   // 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))){
+  if (const llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){
     const llvm::Type *EltTy = VT->getElementType();
     if (VT->getBitWidth() == 128 &&
         (EltTy->isFloatTy() || EltTy->isDoubleTy() ||
index ed1c9f165a1330307e1da6b1abbcd3b0da223738..04447c12d9c1fa16e223221bf8ac63a3a29c3ebc 100644 (file)
@@ -168,3 +168,13 @@ struct foo26 f26(struct foo26 *P) {
   // CHECK: define %struct.foo26 @f26(%struct.foo26* %P)
   return *P;
 }
+
+
+struct v4f32wrapper {
+  v4f32 v;
+};
+
+struct v4f32wrapper f27(struct v4f32wrapper X) {
+  // CHECK: define <4 x float> @f27(<4 x float> %X.coerce)
+  return X;
+}
\ No newline at end of file