mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-03-02 07:16:29 +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);
|
return ABIArgInfo::getIndirect(Align);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// GetByteVectorType - The ABI specifies that a value should be passed in an
|
/// The ABI specifies that a value should be passed in a full vector XMM/YMM
|
||||||
/// full vector XMM/YMM register. Pick an LLVM IR type that will be passed as a
|
/// register. Pick an LLVM IR type that will be passed as a vector register.
|
||||||
/// vector register.
|
|
||||||
llvm::Type *X86_64ABIInfo::GetByteVectorType(QualType Ty) const {
|
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,
|
llvm::Type *IRType = CGT.ConvertType(Ty);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the preferred type is a 16-byte vector, prefer to pass it.
|
// If the preferred type is a 16-byte vector, prefer to pass it.
|
||||||
if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){
|
if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){
|
||||||
|
@ -184,6 +184,28 @@ struct v4f32wrapper f27(struct v4f32wrapper X) {
|
|||||||
return 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
|
// rdar://5711709
|
||||||
struct f28c {
|
struct f28c {
|
||||||
double x;
|
double x;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user