From: Daniel Dunbar Date: Sun, 22 Feb 2009 04:48:22 +0000 (+0000) Subject: x86_64 ABI: Pass 32-bit vectors as Integer to match gcc. We don't care X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e28099bf301ad8b0b77cb11f94caad3c38d97dda;p=clang x86_64 ABI: Pass 32-bit vectors as Integer to match gcc. We don't care about these much but <2 x i16> shows up in the gcc test suite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65264 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 0e2bd606eb..71ef679f18 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -497,6 +497,10 @@ void X86_64ABIInfo::classify(QualType Ty, // class for Class pairs with appropriate constructor methods for // the various situations. + // FIXME: Some of the split computations are wrong; unaligned + // vectors shouldn't be passed in registers for example, so there is + // no chance they can straddle an eightbyte. Verify & simplify. + Lo = Hi = NoClass; Class &Current = OffsetBase < 64 ? Lo : Hi; @@ -523,7 +527,18 @@ void X86_64ABIInfo::classify(QualType Ty, Current = Integer; } else if (const VectorType *VT = Ty->getAsVectorType()) { uint64_t Size = Context.getTypeSize(VT); - if (Size == 64) { + if (Size == 32) { + // gcc passes all <4 x char>, <2 x short>, <1 x int>, <1 x + // float> as integer. + Current = Integer; + + // If this type crosses an eightbyte boundary, it should be + // split. + uint64_t EB_Real = (OffsetBase) / 64; + uint64_t EB_Imag = (OffsetBase + Size - 1) / 64; + if (EB_Real != EB_Imag) + Hi = Lo; + } else if (Size == 64) { // gcc passes <1 x double> in memory. :( if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double)) return;