diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -44,6 +44,7 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include "llvm/Support/TrailingObjects.h"
 #include "llvm/Support/type_traits.h"
@@ -1651,10 +1652,12 @@
     /// target-specific vector type such as for AltiVec or Neon.
     unsigned VecKind : 3;
 
-    /// The number of elements in the vector.
-    unsigned NumElements : 29 - NumTypeBits;
+    unsigned ManyElements : 1;
+    /// Encoded number of elements in the vector.
+    /// If ManyElements is set, the count is 2 ** EncodedNumElements.
+    unsigned EncodedNumElements : 8;
 
-    enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 };
+    enum { ManyElementsThreshold = 1 << 8 };
   };
 
   class AttributedTypeBitfields {
@@ -3247,10 +3250,15 @@
 
 public:
   QualType getElementType() const { return ElementType; }
-  unsigned getNumElements() const { return VectorTypeBits.NumElements; }
+  unsigned getNumElements() const {
+    return VectorTypeBits.ManyElements
+               ? (1 << VectorTypeBits.EncodedNumElements)
+               : VectorTypeBits.EncodedNumElements;
+  }
 
-  static bool isVectorSizeTooLarge(unsigned NumElements) {
-    return NumElements > VectorTypeBitfields::MaxNumElements;
+  static bool isVectorSizeValid(unsigned NumElements) {
+    return NumElements < VectorTypeBitfields::ManyElementsThreshold ||
+           llvm::isPowerOf2_32(NumElements);
   }
 
   bool isSugared() const { return false; }
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2865,10 +2865,12 @@
   "'callback' argument at position %0 references unavailable implicit 'this'">;
 def err_init_method_bad_return_type : Error<
   "init methods must return an object pointer type, not %0">;
-def err_attribute_invalid_size : Error<
+def err_attribute_noninteger_size : Error<
   "vector size not an integral multiple of component size">;
 def err_attribute_zero_size : Error<"zero vector size">;
 def err_attribute_size_too_large : Error<"vector size too large">;
+def err_attribute_invalid_size : Error<
+   "vector size exceeds 256 and is not a power of two">;
 def err_typecheck_vector_not_convertable_implict_truncation : Error<
    "cannot convert between %select{scalar|vector}0 type %1 and vector type"
    " %2 as implicit conversion would cause truncation">;
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -290,7 +290,15 @@
                        QualType canonType, VectorKind vecKind)
     : Type(tc, canonType, vecType->getDependence()), ElementType(vecType) {
   VectorTypeBits.VecKind = vecKind;
-  VectorTypeBits.NumElements = nElements;
+  if (nElements < VectorTypeBitfields::ManyElementsThreshold) {
+    VectorTypeBits.ManyElements = false;
+    VectorTypeBits.EncodedNumElements = nElements;
+  } else {
+    assert(llvm::isPowerOf2_32(nElements));
+    VectorTypeBits.ManyElements = true;
+    VectorTypeBits.EncodedNumElements = llvm::Log2_32(nElements);
+  }
+  assert(getNumElements() == nElements);
 }
 
 /// getArrayElementTypeNoTypeQual - If this is an array type, return the
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -21,6 +21,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
@@ -2436,7 +2437,12 @@
     return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc,
                                                VectorType::GenericVector);
 
-  unsigned VectorSize = static_cast<unsigned>(VecSize.getZExtValue() * 8);
+  if (!VecSize.isIntN(32)) {
+    Diag(AttrLoc, diag::err_attribute_size_too_large)
+        << SizeExpr->getSourceRange();
+    return QualType();
+  }
+  unsigned VectorSize = VecSize.getZExtValue() * 8;
   unsigned TypeSize = static_cast<unsigned>(Context.getTypeSize(CurType));
 
   if (VectorSize == 0) {
@@ -2446,13 +2452,13 @@
 
   // vecSize is specified in bytes - convert to bits.
   if (VectorSize % TypeSize) {
-    Diag(AttrLoc, diag::err_attribute_invalid_size)
+    Diag(AttrLoc, diag::err_attribute_noninteger_size)
         << SizeExpr->getSourceRange();
     return QualType();
   }
 
-  if (VectorType::isVectorSizeTooLarge(VectorSize / TypeSize)) {
-    Diag(AttrLoc, diag::err_attribute_size_too_large)
+  if (!VectorType::isVectorSizeValid(VectorSize / TypeSize)) {
+    Diag(AttrLoc, diag::err_attribute_invalid_size)
         << SizeExpr->getSourceRange();
     return QualType();
   }
@@ -2491,6 +2497,11 @@
 
     // Unlike gcc's vector_size attribute, the size is specified as the
     // number of elements, not the number of bytes.
+    if (!vecSize.isIntN(32)) {
+      Diag(AttrLoc, diag::err_attribute_size_too_large)
+          << ArraySize->getSourceRange();
+      return QualType();
+    }
     unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue());
 
     if (vectorSize == 0) {
@@ -2499,8 +2510,8 @@
       return QualType();
     }
 
-    if (VectorType::isVectorSizeTooLarge(vectorSize)) {
-      Diag(AttrLoc, diag::err_attribute_size_too_large)
+    if (!VectorType::isVectorSizeValid(vectorSize)) {
+      Diag(AttrLoc, diag::err_attribute_invalid_size)
         << ArraySize->getSourceRange();
       return QualType();
     }
diff --git a/clang/test/Sema/types.c b/clang/test/Sema/types.c
--- a/clang/test/Sema/types.c
+++ b/clang/test/Sema/types.c
@@ -70,8 +70,18 @@
 }
 
 // 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}}
+char __attribute__ ((vector_size(255))) v1;
+char __attribute__ ((vector_size(256))) v2;
+char __attribute__ ((vector_size(257))) v3; // expected-error {{vector size exceeds 256 and is not a power of two}}
+char __attribute__ ((vector_size(512))) v4;
+char __attribute__ ((vector_size(0x10000000))) v5;
+char __attribute__ ((vector_size(0x100000000))) v6; // expected-error {{vector size too large}}
+typedef int __attribute__ ((ext_vector_type(255))) e1;
+typedef int __attribute__ ((ext_vector_type(256))) e2;
+typedef int __attribute__ ((ext_vector_type(257))) e3; // expected-error {{vector size exceeds 256 and is not a power of two}}
+typedef int __attribute__ ((ext_vector_type(512))) e4;
+typedef int __attribute__ ((ext_vector_type(0x10000000))) e5;
+typedef int __attribute__ ((ext_vector_type(0x100000000))) e6; // expected-error {{vector size too large}}
 
 // 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
--- a/clang/test/SemaCXX/vector.cpp
+++ b/clang/test/SemaCXX/vector.cpp
@@ -343,7 +343,7 @@
 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(10000))) type2; // #2
   typedef T __attribute__((vector_size(3))) type3; // #3
 };
 
@@ -352,25 +352,27 @@
   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;
-  // 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;
+  const TemplateVectorType<int, 33>::type BadSize = {};
+  const TemplateVectorType<int, 320>::type SmallNonPower = {};
+  const TemplateVectorType<int, 8192>::type LargePower = {};
+  // expected-error@#1 {{vector size exceeds 256 and is not a power of two}}
+  // expected-note@+1 {{in instantiation of template class 'Templates::TemplateVectorType<int, 10000>' requested here}}
+  const TemplateVectorType<int, 10000>::type LargeNonPower = {};
   // 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@#2 {{not a power of two}}
   // expected-error@#3 {{vector size not an integral multiple of component size}}
   // expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, int>' requested here}}
   const PR15730<8, int>::type PR15730_1 = {};
-  // expected-error@#2 {{vector size too large}}
+  // expected-error@#2 {{not a power of two}}
   // expected-note@+1 {{in instantiation of template class 'Templates::PR15730<8, char>' requested here}}
   const PR15730<8, char>::type2 PR15730_2 = {};
 }