Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp =================================================================== --- cfe/trunk/lib/CodeGen/TargetInfo.cpp +++ cfe/trunk/lib/CodeGen/TargetInfo.cpp @@ -2183,19 +2183,15 @@ 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(IRType); - while (STy && STy->getNumElements() == 1) { - IRType = STy->getElementType(0); - STy = dyn_cast(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(IRType)){ Index: cfe/trunk/test/CodeGen/x86_64-arguments.c =================================================================== --- cfe/trunk/test/CodeGen/x86_64-arguments.c +++ cfe/trunk/test/CodeGen/x86_64-arguments.c @@ -184,6 +184,28 @@ 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;