r229408 - x86-64 ABI: unwrap single element structs / arrays of 256-bit vectors to pass and return in registers

Sanjay Patel spatel at rotateright.com
Mon Feb 16 09:26:52 PST 2015


Author: spatel
Date: Mon Feb 16 11:26:51 2015
New Revision: 229408

URL: http://llvm.org/viewvc/llvm-project?rev=229408&view=rev
Log:
x86-64 ABI: unwrap single element structs / arrays of 256-bit vectors to pass and return in registers

This is a patch for PR22563 ( http://llvm.org/bugs/show_bug.cgi?id=22563 ).

We were not correctly unwrapping a single 256-bit AVX vector that was defined as an array of 1 inside a struct.

We would generate a <4 x float> param/return value instead of <8 x float> and lose half of the vector.

Differential Revision: http://reviews.llvm.org/D7614

Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/test/CodeGen/x86_64-arguments.c

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=229408&r1=229407&r2=229408&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Mon Feb 16 11:26:51 2015
@@ -2183,19 +2183,15 @@ ABIArgInfo X86_64ABIInfo::getIndirectRes
   return ABIArgInfo::getIndirect(Align);
 }
 
-/// GetByteVectorType - The ABI specifies that a value should be passed in an
-/// full vector XMM/YMM register.  Pick an LLVM IR type that will be passed as a
-/// vector register.
+/// The ABI specifies that a value should be passed in a full vector XMM/YMM
+/// register. Pick an LLVM IR type that will be passed as a vector register.
 llvm::Type *X86_64ABIInfo::GetByteVectorType(QualType Ty) const {
-  llvm::Type *IRType = CGT.ConvertType(Ty);
+  // Wrapper structs/arrays that only contain vectors are passed just like
+  // vectors; strip them off if present.
+  if (const Type *InnerTy = isSingleElementStruct(Ty, getContext()))
+    Ty = QualType(InnerTy, 0);
 
-  // Wrapper structs that just contain vectors are passed just like vectors,
-  // strip them off if present.
-  llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType);
-  while (STy && STy->getNumElements() == 1) {
-    IRType = STy->getElementType(0);
-    STy = dyn_cast<llvm::StructType>(IRType);
-  }
+  llvm::Type *IRType = CGT.ConvertType(Ty);
 
   // If the preferred type is a 16-byte vector, prefer to pass it.
   if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){

Modified: cfe/trunk/test/CodeGen/x86_64-arguments.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86_64-arguments.c?rev=229408&r1=229407&r2=229408&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/x86_64-arguments.c (original)
+++ cfe/trunk/test/CodeGen/x86_64-arguments.c Mon Feb 16 11:26:51 2015
@@ -184,6 +184,28 @@ struct v4f32wrapper f27(struct v4f32wrap
   return X;
 }
 
+// PR22563 - We should unwrap simple structs and arrays to pass
+// and return them in the appropriate vector registers if possible.
+
+typedef float v8f32 __attribute__((__vector_size__(32)));
+struct v8f32wrapper {
+  v8f32 v;
+};
+
+struct v8f32wrapper f27a(struct v8f32wrapper X) {
+  // AVX-LABEL: define <8 x float> @f27a(<8 x float> %X.coerce)
+  return X;
+}
+
+struct v8f32wrapper_wrapper {
+  v8f32 v[1];
+};
+
+struct v8f32wrapper_wrapper f27b(struct v8f32wrapper_wrapper X) {
+  // AVX-LABEL: define <8 x float> @f27b(<8 x float> %X.coerce)
+  return X;
+}
+
 // rdar://5711709
 struct f28c {
   double x;





More information about the cfe-commits mailing list