mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-03 03:11:27 +00:00
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: 229408
This commit is contained in:
parent
e7f4f86dff
commit
eb2af4e8b1
@ -2183,19 +2183,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)){
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user