r230971 - CodeGen: Fix passing of classes with only one AVX vector member in AVX registers

Benjamin Kramer benny.kra at googlemail.com
Mon Mar 2 08:09:24 PST 2015


Author: d0k
Date: Mon Mar  2 10:09:24 2015
New Revision: 230971

URL: http://llvm.org/viewvc/llvm-project?rev=230971&view=rev
Log:
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.

Added:
    cfe/trunk/test/CodeGenCXX/x86_64-arguments-avx.cpp
Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=230971&r1=230970&r2=230971&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Mon Mar  2 10:09:24 2015
@@ -238,7 +238,7 @@ static bool isEmptyRecord(ASTContext &Co
 /// \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<RecordType>();
   if (!RT)
     return nullptr;
 
@@ -2210,20 +2210,9 @@ llvm::Type *X86_64ABIInfo::GetByteVector
     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<llvm::VectorType>(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<llvm::VectorType>(IRType) &&
+         "Trying to return a non-vector type in a vector register!");
+  return IRType;
 }
 
 /// BitsContainNoUserData - Return true if the specified [start,end) bit range

Added: cfe/trunk/test/CodeGenCXX/x86_64-arguments-avx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/x86_64-arguments-avx.cpp?rev=230971&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/x86_64-arguments-avx.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/x86_64-arguments-avx.cpp Mon Mar  2 10:09:24 2015
@@ -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;
+}
+}





More information about the cfe-commits mailing list