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@+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@+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@+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@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 8192>' requested here}} - const TemplateVectorType<int, 8192>::type TooLarge; + // expected-note@+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@+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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits