From 83b1bf3a27e9a93038f4508492acf8497c6101e7 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Mon, 2 Mar 2015 16:09:24 +0000 Subject: [PATCH] CodeGen: Fix passing of classes with only one AVX vector member in AVX registers isSingleElementStruct was a bit too tight in its definition of struct so we got a mismatch between classify() and the actual code generation. To make matters worse the code in GetByteVectorType still defaulted to <2 x double> if it encountered a type it didn't know, making this a silent miscompilation (PR22753). Completely remove the "preferred type" stuff from GetByteVectorType and make it fail an assertion if someone tries to use it with a type not suitable for a vector register. llvm-svn: 230971 --- clang/lib/CodeGen/TargetInfo.cpp | 19 ++++--------------- clang/test/CodeGenCXX/x86_64-arguments-avx.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 15 deletions(-) create mode 100644 clang/test/CodeGenCXX/x86_64-arguments-avx.cpp diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 7ee698b..31f4a43 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -238,7 +238,7 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { /// \return The field declaration for the single non-empty field, if /// it exists. static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { - const RecordType *RT = T->getAsStructureType(); + const RecordType *RT = T->getAs(); if (!RT) return nullptr; @@ -2210,20 +2210,9 @@ llvm::Type *X86_64ABIInfo::GetByteVectorType(QualType Ty) const { Ty = QualType(InnerTy, 0); 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)){ - llvm::Type *EltTy = VT->getElementType(); - unsigned BitWidth = VT->getBitWidth(); - if ((BitWidth >= 128 && BitWidth <= 256) && - (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); + assert(isa(IRType) && + "Trying to return a non-vector type in a vector register!"); + return IRType; } /// BitsContainNoUserData - Return true if the specified [start,end) bit range diff --git a/clang/test/CodeGenCXX/x86_64-arguments-avx.cpp b/clang/test/CodeGenCXX/x86_64-arguments-avx.cpp new file mode 100644 index 0000000..1b1c642 --- /dev/null +++ b/clang/test/CodeGenCXX/x86_64-arguments-avx.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s + +namespace test1 { +typedef double __m256d __attribute__((__vector_size__(32))); + +class PR22753 { +public: + __m256d data; +}; + +// CHECK: define <4 x double> @_ZN5test14testENS_7PR22753E(<4 x double> +PR22753 test(PR22753 x) { + return x; +} +} -- 2.7.4