[clang] 88fbadd - [AST] clang::VectorType supports any size (that fits in unsigned)

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 3 08:30:50 PDT 2020


Author: Sam McCall
Date: 2020-04-03T17:30:31+02:00
New Revision: 88fbadd0f5d50ea1d310fb63da6da15b82a9be05

URL: https://github.com/llvm/llvm-project/commit/88fbadd0f5d50ea1d310fb63da6da15b82a9be05
DIFF: https://github.com/llvm/llvm-project/commit/88fbadd0f5d50ea1d310fb63da6da15b82a9be05.diff

LOG: [AST] clang::VectorType supports any size (that fits in unsigned)

Summary:
This matches llvm::VectorType.
It moves the size from the type bitfield into VectorType, increasing size by 8
bytes (including padding of 4). This is OK as we don't expect to create terribly
many of these types.

c.f. D77313 which enables large power-of-two sizes without growing VectorType.

Reviewers: efriedma, hokein

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77335

Added: 
    

Modified: 
    clang/include/clang/AST/Type.h
    clang/lib/Sema/SemaType.cpp
    clang/test/Sema/types.c
    clang/test/SemaCXX/vector.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 5d2c035ea0fe..f78d9d7670a7 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1650,11 +1650,8 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
     /// The kind of vector, either a generic vector type or some
     /// target-specific vector type such as for AltiVec or Neon.
     unsigned VecKind : 3;
-
     /// The number of elements in the vector.
-    unsigned NumElements : 29 - NumTypeBits;
-
-    enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
+    uint32_t NumElements;
   };
 
   class AttributedTypeBitfields {
@@ -3249,10 +3246,6 @@ class VectorType : public Type, public llvm::FoldingSetNode {
   QualType getElementType() const { return ElementType; }
   unsigned getNumElements() const { return VectorTypeBits.NumElements; }
 
-  static bool isVectorSizeTooLarge(unsigned NumElements) {
-    return NumElements > VectorTypeBitfields::MaxNumElements;
-  }
-
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index e128ebf31270..49a5dcbe0c79 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2436,28 +2436,34 @@ QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr,
     return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc,
                                                VectorType::GenericVector);
 
-  unsigned VectorSize = static_cast<unsigned>(VecSize.getZExtValue() * 8);
+  // vecSize is specified in bytes - convert to bits.
+  if (!VecSize.isIntN(61)) {
+    // Bit size will overflow uint64.
+    Diag(AttrLoc, diag::err_attribute_size_too_large)
+        << SizeExpr->getSourceRange();
+    return QualType();
+  }
+  uint64_t VectorSizeBits = VecSize.getZExtValue() * 8;
   unsigned TypeSize = static_cast<unsigned>(Context.getTypeSize(CurType));
 
-  if (VectorSize == 0) {
+  if (VectorSizeBits == 0) {
     Diag(AttrLoc, diag::err_attribute_zero_size) << SizeExpr->getSourceRange();
     return QualType();
   }
 
-  // vecSize is specified in bytes - convert to bits.
-  if (VectorSize % TypeSize) {
+  if (VectorSizeBits % TypeSize) {
     Diag(AttrLoc, diag::err_attribute_invalid_size)
         << SizeExpr->getSourceRange();
     return QualType();
   }
 
-  if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) {
+  if (VectorSizeBits / TypeSize > std::numeric_limits<uint32_t>::max()) {
     Diag(AttrLoc, diag::err_attribute_size_too_large)
         << SizeExpr->getSourceRange();
     return QualType();
   }
 
-  return Context.getVectorType(CurType, VectorSize / TypeSize,
+  return Context.getVectorType(CurType, VectorSizeBits / TypeSize,
                                VectorType::GenericVector);
 }
 
@@ -2489,6 +2495,11 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize,
       return QualType();
     }
 
+    if (!vecSize.isIntN(32)) {
+      Diag(AttrLoc, diag::err_attribute_size_too_large)
+          << ArraySize->getSourceRange();
+      return QualType();
+    }
     // Unlike gcc's vector_size attribute, the size is specified as the
     // number of elements, not the number of bytes.
     unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
@@ -2499,12 +2510,6 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize,
       return QualType();
     }
 
-    if (VectorType::isVectorSizeTooLarge(vectorSize)) {
-      Diag(AttrLoc, diag::err_attribute_size_too_large)
-        << ArraySize->getSourceRange();
-      return QualType();
-    }
-
     return Context.getExtVectorType(T, vectorSize);
   }
 

diff  --git a/clang/test/Sema/types.c b/clang/test/Sema/types.c
index 8869b3427dc5..177e5fbd9704 100644
--- a/clang/test/Sema/types.c
+++ b/clang/test/Sema/types.c
@@ -69,9 +69,15 @@ void test2(int i) {
   char c = (char __attribute__((may_alias))) i;
 }
 
-// vector size too large
-int __attribute__ ((vector_size(8192))) x1; // expected-error {{vector size too large}}
-typedef int __attribute__ ((ext_vector_type(8192))) x2; // expected-error {{vector size too large}}
+// vector size
+int __attribute__((vector_size(123456))) v1;
+int __attribute__((vector_size(0x1000000000))) v2;         // expected-error {{vector size too large}}
+int __attribute__((vector_size((__int128_t)1 << 100))) v3; // expected-error {{vector size too large}}
+int __attribute__((vector_size(0))) v4;                    // expected-error {{zero vector size}}
+typedef int __attribute__((ext_vector_type(123456))) e1;
+typedef int __attribute__((ext_vector_type(0x100000000))) e2;      // expected-error {{vector size too large}}
+typedef int __attribute__((vector_size((__int128_t)1 << 100))) e3; // expected-error {{vector size too large}}
+typedef int __attribute__((ext_vector_type(0))) e4;                // expected-error {{zero vector size}}
 
 // no support for vector enum type
 enum { e_2 } x3 __attribute__((vector_size(64))); // expected-error {{invalid vector element type}}

diff  --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp
index cabc525771c3..caa840596d7d 100644
--- a/clang/test/SemaCXX/vector.cpp
+++ b/clang/test/SemaCXX/vector.cpp
@@ -335,7 +335,7 @@ const int &reference_to_vec_element = vi4(1).x;
 typedef bool bad __attribute__((__vector_size__(16)));  // expected-error {{invalid vector element type 'bool'}}
 
 namespace Templates {
-template <typename Elt, unsigned Size>
+template <typename Elt, unsigned long long Size>
 struct TemplateVectorType {
   typedef Elt __attribute__((__vector_size__(Size))) type; // #1
 };
@@ -343,7 +343,7 @@ struct TemplateVectorType {
 template <int N, typename T>
 struct PR15730 {
   typedef T __attribute__((vector_size(N * sizeof(T)))) type;
-  typedef T __attribute__((vector_size(8192))) type2; // #2
+  typedef T __attribute__((vector_size(0x1000000000))) type2; // #2
   typedef T __attribute__((vector_size(3))) type3; // #3
 };
 
@@ -352,19 +352,20 @@ void Init() {
   const TemplateVectorType<int, 32>::type Works2 = {};
   // expected-error@#1 {{invalid vector element type 'bool'}}
   // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType<bool, 32>' requested here}}
-  const TemplateVectorType<bool, 32>::type NoBool;
+  const TemplateVectorType<bool, 32>::type NoBool = {};
   // expected-error@#1 {{invalid vector element type 'int __attribute__((ext_vector_type(4)))' (vector of 4 'int' values)}}
   // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType<int __attribute__((ext_vector_type(4))), 32>' requested here}}
-  const TemplateVectorType<vi4, 32>::type NoComplex;
+  const TemplateVectorType<vi4, 32>::type NoComplex = {};
   // expected-error@#1 {{vector size not an integral multiple of component size}}
   // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 33>' requested here}}
-  const TemplateVectorType<int, 33>::type BadSize;
+  const TemplateVectorType<int, 33>::type BadSize = {};
+  const TemplateVectorType<int, 3200>::type Large = {};
   // expected-error@#1 {{vector size too large}}
-  // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 8192>' requested here}}
-  const TemplateVectorType<int, 8192>::type TooLarge;
+  // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 68719476736>' requested here}}
+  const TemplateVectorType<int, 0x1000000000>::type TooLarge = {};
   // expected-error@#1 {{zero vector size}}
   // expected-note at +1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 0>' requested here}}
-  const TemplateVectorType<int, 0>::type Zero;
+  const TemplateVectorType<int, 0>::type Zero = {};
 
   // expected-error@#2 {{vector size too large}}
   // expected-error@#3 {{vector size not an integral multiple of component size}}


        


More information about the cfe-commits mailing list