From 0f408f5242522cbede304472e17931357c1b573d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 29 Jul 2010 04:56:46 +0000 Subject: [PATCH] move the 'pretty 16-byte vector' inferring code up to be shared with return values, improving stuff that returns __m128 etc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109731 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TargetInfo.cpp | 38 +++++++++++++++++++++------------ test/CodeGen/x86_64-arguments.c | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 064a97484d..7321ba148c 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -717,6 +717,8 @@ class X86_64ABIInfo : public ABIInfo { /// also be ComplexX87. void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi) const; + const llvm::Type *Get16ByteVectorType(QualType Ty) const; + const llvm::Type *Get8ByteTypeAtOffset(const llvm::Type *IRType, unsigned IROffset, QualType SourceTy, unsigned SourceOffset) const; @@ -1179,6 +1181,26 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const { return ABIArgInfo::getIndirect(0); } +/// Get16ByteVectorType - The ABI specifies that a value should be passed in an +/// full vector XMM register. Pick an LLVM IR type that will be passed as a +/// vector register. +const llvm::Type *X86_64ABIInfo::Get16ByteVectorType(QualType Ty) const { + // If the preferred type is a 16-byte vector, prefer to pass it. + if (const llvm::VectorType *VT = + dyn_cast(CGT.ConvertTypeRecursive(Ty))){ + const llvm::Type *EltTy = VT->getElementType(); + if (VT->getBitWidth() == 128 && + (EltTy->isFloatTy() || EltTy->isDoubleTy() || + EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) || + EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) || + EltTy->isIntegerTy(128))) + return VT; + } + + return llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2); +} + + /// Get8ByteTypeAtOffset - The ABI specifies that a value should be passed in an /// 8-byte GPR. This means that we either have a scalar or we are talking about /// the high or low part of an up-to-16-byte struct. This routine picks the @@ -1316,7 +1338,7 @@ classifyReturnType(QualType RetTy) const { // SSEUP should always be preceeded by SSE, just widen. case SSEUp: assert(Lo == SSE && "Unexpected SSEUp classification."); - ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2); + ResType = Get16ByteVectorType(RetTy); break; // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is @@ -1423,19 +1445,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt, // register. This only happens when 128-bit vectors are passed. case SSEUp: assert(Lo == SSE && "Unexpected SSEUp classification"); - ResType = llvm::VectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2); - - // If the preferred type is a 16-byte vector, prefer to pass it. - if (const llvm::VectorType *VT = - dyn_cast(CGT.ConvertTypeRecursive(Ty))){ - const llvm::Type *EltTy = VT->getElementType(); - if (VT->getBitWidth() == 128 && - (EltTy->isFloatTy() || EltTy->isDoubleTy() || - EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) || - EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) || - EltTy->isIntegerTy(128))) - ResType = VT; - } + ResType = Get16ByteVectorType(Ty); break; } diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index 7bff70088a..ed1c9f165a 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -155,7 +155,7 @@ struct f23S f24(struct f23S *X, struct f24s *P2) { typedef float v4f32 __attribute__((__vector_size__(16))); v4f32 f25(v4f32 X) { - // CHECK: define <2 x double> @f25(<4 x float> %X.coerce) + // CHECK: define <4 x float> @f25(<4 x float> %X.coerce) return X+X; } -- 2.40.0