Commit 524b6abc authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r229408:

------------------------------------------------------------------------
r229408 | spatel | 2015-02-16 09:26:51 -0800 (Mon, 16 Feb 2015) | 10 lines

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

------------------------------------------------------------------------

llvm-svn: 229546
parent 943a8989
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -2134,19 +2134,15 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
  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)){
+22 −0
Original line number Diff line number Diff line
@@ -184,6 +184,28 @@ struct v4f32wrapper f27(struct v4f32wrapper X) {
  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;