Author: Benjamin Maxwell
Date: 2026-10-22T10:18:09+01:00
New Revision: 1a12b033bc0e525695319bfa0d96e77b844305ad

URL: 
https://github.com/llvm/llvm-project/commit/1a12b033bc0e525695319bfa0d96e77b844305ad
DIFF: 
https://github.com/llvm/llvm-project/commit/1a12b033bc0e525695319bfa0d96e77b844305ad.diff

LOG: [CIR] Use `llvm::ElementCount` to hold `cir::VectorType` size (#231906)

A separate scalability flag is a design issue inherited from MLIR's
VectorType. It makes dropping/ignoring scalability an easy mistake to
make in common transforms and lowerings.

This patch aligns ClangIR with LLVM and uses `ElementCount` to hold the
vector size. This makes it simple to propagate the entire size (element
count and scalability) and forces users to query the size they expect:

- `.getFixedValue()`
  - Asserts the size is fixed and converts it to an integer
- `.getKnownMinValue()`
  - Allowed for fixed/scalable vectors
  - Returns the element count at vscale=1

A few small bugs/missed verifier checks have been handled with this
patch and are now tested:

- Don't fold scalable splats into fixed-vector-only constants
- Verify vectors are not scalable for fixed-vector-only operations
- Preserve scalable `TypeSize` values in CIRDataLayout and lowering

Assisted-by: Codex

Added: 
    

Modified: 
    clang/include/clang/CIR/Dialect/IR/CIROps.td
    clang/include/clang/CIR/Dialect/IR/CIRTypes.h
    clang/include/clang/CIR/Dialect/IR/CIRTypes.td
    clang/lib/CIR/CodeGen/CIRGenBuilder.h
    clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
    clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
    clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
    clang/lib/CIR/CodeGen/CIRGenExpr.cpp
    clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
    clang/lib/CIR/CodeGen/CIRGenTypes.cpp
    clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
    clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
    clang/lib/CIR/Dialect/IR/CIRDialect.cpp
    clang/lib/CIR/Dialect/IR/CIRTypes.cpp
    clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
    clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
    clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
    clang/test/CIR/IR/invalid-vector.cir
    clang/test/CIR/Lowering/not.cir
    clang/test/CIR/Transforms/vector-splat.cir
    clang/unittests/CIR/PointerLikeTest.cpp
    clang/unittests/CIR/VectorTypeABIAlignTest.cpp
    llvm/include/llvm/Support/TypeSize.h

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4dde0a667ac5a1..a56ed5141322eb 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -6708,7 +6708,7 @@ def CIR_MatrixExtractRowOp : CIR_Op<"matrix.extract_row", 
[
     "type of 'result' matches vector type with same element type of 'matrix' "
     "and size equals to num columns",
     "matrix", "result",
-    "cir::VectorType::get("
+    "cir::VectorType::getFixed("
       "mlir::cast<cir::MatrixType>($_self).getElementType(),"
       "mlir::cast<cir::MatrixType>($_self).getNumColumns()"
     ")">

diff  --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
index 19f86e83954367..ded2921c608c6f 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h
@@ -26,6 +26,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/TypeSize.h"
 
 namespace llvm {
 struct fltSemantics;

diff  --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td 
b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
index 366a4669c3a56f..2534f110b71d5c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td
@@ -478,7 +478,7 @@ def CIR_ArrayType : CIR_Type<"Array", "array", [
 }
 
 
//===----------------------------------------------------------------------===//
-// VectorType (fixed size)
+// VectorType
 
//===----------------------------------------------------------------------===//
 
 def CIR_VectorType : CIR_Type<"Vector", "vector", [
@@ -488,8 +488,9 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [
   let summary = "CIR vector type";
   let description = [{
     The `!cir.vector` type represents a one-dimensional vector.
-    It takes three parameters: the element type, the number of elements and the
-    scalability flag (optional, defaults to `false`).
+    It takes two parameters: the element type and an element count, which
+    records both the known minimum number of elements and whether the vector is
+    scalable.
 
     Syntax:
 
@@ -524,20 +525,34 @@ def CIR_VectorType : CIR_Type<"Vector", "vector", [
 
   let parameters = (ins
     CIR_VectorElementType:$element_type,
-    "uint64_t":$size,
-    OptionalParameter<"bool">:$is_scalable
+    "llvm::ElementCount":$size
   );
 
   let builders = [
     TypeBuilderWithInferredContext<(ins
-      "mlir::Type":$element_type, "uint64_t":$size, CArg<"bool",
-      "false">:$is_scalable
+      "mlir::Type":$element_type, "llvm::ElementCount":$size
     ), [{
-        return $_get(element_type.getContext(), element_type, size, 
is_scalable);
+        return $_get(element_type.getContext(), element_type, size);
     }]>,
   ];
 
   let extraClassDeclaration = [{
+    /// Return the size of a fixed-width vector.
+    uint64_t getFixedSize() const { return getSize().getFixedValue(); }
+
+    /// Return whether this vector is scalable.
+    bool isScalable() const { return getSize().isScalable(); }
+
+    /// Return a fixed-width vector with the given element type and size.
+    static VectorType getFixed(mlir::Type elementType, uint64_t size) {
+      return get(elementType, llvm::ElementCount::getFixed(size));
+    }
+
+    /// Return a scalable vector with the given element type and minimum size.
+    static VectorType getScalable(mlir::Type elementType, uint64_t size) {
+      return get(elementType, llvm::ElementCount::getScalable(size));
+    }
+
     /// The width of the integer a vector of `!cir.bool` is stored as: one bit
     /// per element, at least a byte.
     uint64_t getBoolStorageWidth() const;

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h 
b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
index b9cc67e394accf..e60e3092b699f3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h
+++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h
@@ -803,7 +803,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
                    llvm::ArrayRef<mlir::Attribute> maskAttrs) {
     auto vecType = mlir::cast<cir::VectorType>(vec1.getType());
     auto resultTy =
-        cir::VectorType::get(vecType.getElementType(), maskAttrs.size());
+        cir::VectorType::getFixed(vecType.getElementType(), maskAttrs.size());
     return cir::VecShuffleOp::create(*this, loc, resultTy, vec1, vec2,
                                      getArrayAttr(maskAttrs));
   }

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
index a94139cff20ffb..21a86114420e19 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp
@@ -1174,7 +1174,7 @@ decodeFixedType(CIRGenFunction &cgf,
   case IITDescriptor::Vector: {
     mlir::Type elementType = decodeFixedType(cgf, infos, overloadTys, context);
     unsigned numElements = descriptor.VectorWidth.getFixedValue();
-    return cir::VectorType::get(elementType, numElements);
+    return cir::VectorType::getFixed(elementType, numElements);
   }
   case IITDescriptor::Pointer: {
     mlir::Builder builder(context);

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index 30438d5288608a..1dbb6c2c3defc8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -96,11 +96,11 @@ static cir::VectorType getFloatNeonType(CIRGenFunction &cgf,
   int isQuad = intTypeFlags.isQuad();
   switch (intTypeFlags.getEltType()) {
   case NeonTypeFlags::Int16:
-    return cir::VectorType::get(cgf.fP16Ty, (4 << isQuad));
+    return cir::VectorType::getFixed(cgf.fP16Ty, (4 << isQuad));
   case NeonTypeFlags::Int32:
-    return cir::VectorType::get(cgf.floatTy, (2 << isQuad));
+    return cir::VectorType::getFixed(cgf.floatTy, (2 << isQuad));
   case NeonTypeFlags::Int64:
-    return cir::VectorType::get(cgf.doubleTy, (1 << isQuad));
+    return cir::VectorType::getFixed(cgf.doubleTy, (1 << isQuad));
   default:
     llvm_unreachable("Type can't be converted to floating-point!");
   }
@@ -210,7 +210,7 @@ static mlir::Value emitNeonCall(CIRGenModule &cgm, 
CIRGenBuilderTy &builder,
 static cir::VectorType getNeonPairwiseWidenInputType(cir::VectorType resType,
                                                      bool usgn) {
   mlir::Type elemTy = resType.getElementType();
-  uint64_t resLanes = resType.getSize();
+  uint64_t resLanes = resType.getFixedSize();
   auto intTy = mlir::dyn_cast<cir::IntType>(elemTy);
   assert(intTy && "vpaddl result type must be an integer vector");
 
@@ -220,7 +220,7 @@ static cir::VectorType 
getNeonPairwiseWidenInputType(cir::VectorType resType,
 
   unsigned argWidth = resWidth / 2;
   unsigned argLanes = resLanes * 2;
-  cir::VectorType result = cir::VectorType::get(
+  cir::VectorType result = cir::VectorType::getFixed(
       cir::IntType::get(resType.getContext(), argWidth, /* is_signed */ !usgn),
       argLanes);
   return result;
@@ -256,7 +256,7 @@ deriveNeonSISDIntrinsicOperandTypes(CIRGenFunction &cgf, 
unsigned modifier,
   auto wrapAsVector = [&](mlir::Type ty) -> cir::VectorType {
     unsigned bits = cgf.cgm.getDataLayout().getTypeSizeInBits(ty);
     unsigned elts = vectorSize ? vectorSize / bits : 1;
-    return cir::VectorType::get(ty, elts);
+    return cir::VectorType::getFixed(ty, elts);
   };
 
   // Determine the vectorized data type.
@@ -632,7 +632,7 @@ emitAArch64CompareBuiltinExpr(CIRGenFunction &cgf, 
CIRGenBuilderTy &builder,
 
   bool scalarCmp = !isa<cir::VectorType>(src.getType());
   if (!scalarCmp) {
-    assert(!cast<cir::VectorType>(retTy).getIsScalable() &&
+    assert(!cast<cir::VectorType>(retTy).isScalable() &&
            "This is only intended for fixed-width vectors");
     // Vector types are cast to i8 vectors. Recover original type.
     src = builder.createBitcast(src, retTy);
@@ -661,46 +661,46 @@ static cir::VectorType getNeonType(CIRGenFunction *cgf, 
NeonTypeFlags typeFlags,
   switch (typeFlags.getEltType()) {
   case NeonTypeFlags::Int8:
   case NeonTypeFlags::Poly8:
-    return cir::VectorType::get(typeFlags.isUnsigned() ? cgf->uInt8Ty
-                                                       : cgf->sInt8Ty,
-                                v1Ty ? 1 : (8 << isQuad));
+    return cir::VectorType::getFixed(typeFlags.isUnsigned() ? cgf->uInt8Ty
+                                                            : cgf->sInt8Ty,
+                                     v1Ty ? 1 : (8 << isQuad));
   case NeonTypeFlags::MFloat8:
-    return cir::VectorType::get(cgf->uInt8Ty, v1Ty ? 1 : (8 << isQuad));
+    return cir::VectorType::getFixed(cgf->uInt8Ty, v1Ty ? 1 : (8 << isQuad));
   case NeonTypeFlags::Int16:
   case NeonTypeFlags::Poly16:
-    return cir::VectorType::get(typeFlags.isUnsigned() ? cgf->uInt16Ty
-                                                       : cgf->sInt16Ty,
-                                v1Ty ? 1 : (4 << isQuad));
+    return cir::VectorType::getFixed(typeFlags.isUnsigned() ? cgf->uInt16Ty
+                                                            : cgf->sInt16Ty,
+                                     v1Ty ? 1 : (4 << isQuad));
   case NeonTypeFlags::BFloat16:
     if (allowBFloatArgsAndRet)
-      return cir::VectorType::get(cgf->getCIRGenModule().bFloat16Ty,
-                                  v1Ty ? 1 : (4 << isQuad));
-    return cir::VectorType::get(cgf->uInt16Ty, v1Ty ? 1 : (4 << isQuad));
+      return cir::VectorType::getFixed(cgf->getCIRGenModule().bFloat16Ty,
+                                       v1Ty ? 1 : (4 << isQuad));
+    return cir::VectorType::getFixed(cgf->uInt16Ty, v1Ty ? 1 : (4 << isQuad));
   case NeonTypeFlags::Float16:
     if (hasLegalHalfType)
-      return cir::VectorType::get(cgf->getCIRGenModule().fP16Ty,
-                                  v1Ty ? 1 : (4 << isQuad));
-    return cir::VectorType::get(cgf->uInt16Ty, v1Ty ? 1 : (4 << isQuad));
+      return cir::VectorType::getFixed(cgf->getCIRGenModule().fP16Ty,
+                                       v1Ty ? 1 : (4 << isQuad));
+    return cir::VectorType::getFixed(cgf->uInt16Ty, v1Ty ? 1 : (4 << isQuad));
   case NeonTypeFlags::Int32:
-    return cir::VectorType::get(typeFlags.isUnsigned() ? cgf->uInt32Ty
-                                                       : cgf->sInt32Ty,
-                                v1Ty ? 1 : (2 << isQuad));
+    return cir::VectorType::getFixed(typeFlags.isUnsigned() ? cgf->uInt32Ty
+                                                            : cgf->sInt32Ty,
+                                     v1Ty ? 1 : (2 << isQuad));
   case NeonTypeFlags::Int64:
   case NeonTypeFlags::Poly64:
-    return cir::VectorType::get(typeFlags.isUnsigned() ? cgf->uInt64Ty
-                                                       : cgf->sInt64Ty,
-                                v1Ty ? 1 : (1 << isQuad));
+    return cir::VectorType::getFixed(typeFlags.isUnsigned() ? cgf->uInt64Ty
+                                                            : cgf->sInt64Ty,
+                                     v1Ty ? 1 : (1 << isQuad));
   case NeonTypeFlags::Poly128:
     // FIXME: i128 and f128 doesn't get fully support in Clang and llvm.
     // There is a lot of i128 and f128 API missing.
     // so we use v16i8 to represent poly128 and get pattern matched.
-    return cir::VectorType::get(cgf->uInt8Ty, 16);
+    return cir::VectorType::getFixed(cgf->uInt8Ty, 16);
   case NeonTypeFlags::Float32:
-    return cir::VectorType::get(cgf->getCIRGenModule().floatTy,
-                                v1Ty ? 1 : (2 << isQuad));
+    return cir::VectorType::getFixed(cgf->getCIRGenModule().floatTy,
+                                     v1Ty ? 1 : (2 << isQuad));
   case NeonTypeFlags::Float64:
-    return cir::VectorType::get(cgf->getCIRGenModule().doubleTy,
-                                v1Ty ? 1 : (1 << isQuad));
+    return cir::VectorType::getFixed(cgf->getCIRGenModule().doubleTy,
+                                     v1Ty ? 1 : (1 << isQuad));
   }
   llvm_unreachable("Unknown vector element type!");
 }
@@ -906,7 +906,7 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   case NEON::BI__builtin_neon_splat_laneq_v:
   case NEON::BI__builtin_neon_splatq_lane_v:
   case NEON::BI__builtin_neon_splatq_laneq_v: {
-    uint64_t numElements = vTy.getSize();
+    uint64_t numElements = vTy.getFixedSize();
     if (builtinID == NEON::BI__builtin_neon_splatq_lane_v)
       numElements *= 2;
     if (builtinID == NEON::BI__builtin_neon_splat_laneq_v)
@@ -926,7 +926,7 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   case NEON::BI__builtin_neon_vaddq_v: {
     unsigned numBytes = (builtinID == NEON::BI__builtin_neon_vaddq_v) ? 16 : 8;
     cir::VectorType byteTy =
-        cir::VectorType::get(cgf.getBuilder().getUInt8Ty(), numBytes);
+        cir::VectorType::getFixed(cgf.getBuilder().getUInt8Ty(), numBytes);
     ops[0] = cgf.getBuilder().createBitcast(ops[0], byteTy);
     ops[1] = cgf.getBuilder().createBitcast(ops[1], byteTy);
     mlir::Value result = cgf.getBuilder().createXor(loc, ops[0], ops[1]);
@@ -1144,8 +1144,8 @@ static mlir::Value emitCommonNeonBuiltinExpr(
   case NEON::BI__builtin_neon_vcvtx_f32_v: {
     llvm::StringRef llvmIntrName = getLLVMIntrNameNoPrefix(
         static_cast<llvm::Intrinsic::ID>(llvmIntrinsic));
-    auto v2f64 = cir::VectorType::get(cgf.cgm.doubleTy, 2);
-    auto v2f32 = cir::VectorType::get(cgf.cgm.floatTy, 2);
+    auto v2f64 = cir::VectorType::getFixed(cgf.cgm.doubleTy, 2);
+    auto v2f32 = cir::VectorType::getFixed(cgf.cgm.floatTy, 2);
     return emitNeonCall(cgf.getCIRGenModule(), cgf.getBuilder(),
                         /*argTypes=*/{v2f64}, ops, llvmIntrName,
                         /*funcResTy=*/v2f32, loc);
@@ -1511,8 +1511,7 @@ mlir::Value 
CIRGenFunction::emitSVEPredicateCast(mlir::Value pred,
 
   // TODO: Handle "aarch64.svcount" once we get round to supporting SME.
 
-  auto retTy = cir::VectorType::get(builder.getUIntNTy(1), minNumElts,
-                                    /*is_scalable=*/true);
+  auto retTy = cir::VectorType::getScalable(builder.getUIntNTy(1), minNumElts);
   if (pred.getType() == retTy)
     return pred;
 
@@ -1585,33 +1584,33 @@ cir::VectorType CIRGenFunction::getSVEType(const 
SVETypeFlags &typeFlags) {
     llvm_unreachable("Invalid SVETypeFlag!");
 
   case SVETypeFlags::EltTyInt8:
-    return cir::VectorType::get(builder.getUInt8Ty(), 16, true);
+    return cir::VectorType::getScalable(builder.getUInt8Ty(), 16);
   case SVETypeFlags::EltTyInt16:
-    return cir::VectorType::get(builder.getUInt16Ty(), 8, true);
+    return cir::VectorType::getScalable(builder.getUInt16Ty(), 8);
   case SVETypeFlags::EltTyInt32:
-    return cir::VectorType::get(builder.getUInt32Ty(), 4, true);
+    return cir::VectorType::getScalable(builder.getUInt32Ty(), 4);
   case SVETypeFlags::EltTyInt64:
-    return cir::VectorType::get(builder.getUInt64Ty(), 2, true);
+    return cir::VectorType::getScalable(builder.getUInt64Ty(), 2);
 
   case SVETypeFlags::EltTyMFloat8:
-    return cir::VectorType::get(builder.getUInt8Ty(), 16, true);
+    return cir::VectorType::getScalable(builder.getUInt8Ty(), 16);
   case SVETypeFlags::EltTyFloat16:
-    return cir::VectorType::get(builder.getFp16Ty(), 8, true);
+    return cir::VectorType::getScalable(builder.getFp16Ty(), 8);
   case SVETypeFlags::EltTyBFloat16:
-    return cir::VectorType::get(builder.getBF16Type(), 8, true);
+    return cir::VectorType::getScalable(builder.getBF16Type(), 8);
   case SVETypeFlags::EltTyFloat32:
-    return cir::VectorType::get(builder.getF32Type(), 4, true);
+    return cir::VectorType::getScalable(builder.getF32Type(), 4);
   case SVETypeFlags::EltTyFloat64:
-    return cir::VectorType::get(builder.getDoubleTy(), 2, true);
+    return cir::VectorType::getScalable(builder.getDoubleTy(), 2);
 
   case SVETypeFlags::EltTyBool8:
-    return cir::VectorType::get(builder.getUIntNTy(1), 16, true);
+    return cir::VectorType::getScalable(builder.getUIntNTy(1), 16);
   case SVETypeFlags::EltTyBool16:
-    return cir::VectorType::get(builder.getUIntNTy(1), 8, true);
+    return cir::VectorType::getScalable(builder.getUIntNTy(1), 8);
   case SVETypeFlags::EltTyBool32:
-    return cir::VectorType::get(builder.getUIntNTy(1), 4, true);
+    return cir::VectorType::getScalable(builder.getUIntNTy(1), 4);
   case SVETypeFlags::EltTyBool64:
-    return cir::VectorType::get(builder.getUIntNTy(1), 2, true);
+    return cir::VectorType::getScalable(builder.getUIntNTy(1), 2);
   }
 }
 
@@ -1622,7 +1621,7 @@ static cir::VectorType 
getSVEVectorForElementType(CIRGenModule &cgm,
                                                   mlir::Type eltTy) {
   unsigned numElts =
       sveBitsPerBlock / cgm.getDataLayout().getTypeSizeInBits(eltTy);
-  return cir::VectorType::get(eltTy, numElts, /*is_scalable=*/true);
+  return cir::VectorType::getScalable(eltTy, numElts);
 }
 
 
//===----------------------------------------------------------------------===//
@@ -2815,7 +2814,8 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
                                          std::nullopt, halfTy, loc);
   }
   case NEON::BI__builtin_neon_vaddq_p128: {
-    cir::VectorType byteTy = cir::VectorType::get(builder.getUInt8Ty(), 16);
+    cir::VectorType byteTy =
+        cir::VectorType::getFixed(builder.getUInt8Ty(), 16);
     ops[0] = builder.createBitcast(ops[0], byteTy);
     ops[1] = builder.createBitcast(ops[1], byteTy);
     mlir::Value result = builder.createXor(loc, ops[0], ops[1]);
@@ -3147,14 +3147,14 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
                      getContext().BuiltinInfo.getName(builtinID));
     return mlir::Value{};
   case NEON::BI__builtin_neon_vcvt_f16_f32: {
-    auto v4f32 = cir::VectorType::get(cgm.floatTy, 4);
-    auto v4f16 = cir::VectorType::get(cgm.fP16Ty, 4);
+    auto v4f32 = cir::VectorType::getFixed(cgm.floatTy, 4);
+    auto v4f16 = cir::VectorType::getFixed(cgm.fP16Ty, 4);
     return builder.createFloatingCast(builder.createBitcast(ops[0], v4f32),
                                       v4f16);
   }
   case NEON::BI__builtin_neon_vcvt_f32_f16: {
-    auto v4f32 = cir::VectorType::get(cgm.floatTy, 4);
-    auto v4f16 = cir::VectorType::get(cgm.fP16Ty, 4);
+    auto v4f32 = cir::VectorType::getFixed(cgm.floatTy, 4);
+    auto v4f16 = cir::VectorType::getFixed(cgm.fP16Ty, 4);
     return builder.createFloatingCast(builder.createBitcast(ops[0], v4f16),
                                       v4f32);
   }
@@ -3201,12 +3201,13 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     // For vfmaq_lane, the lane source operand is the non-quad vector, so it 
has
     // half as many lanes as the quad result vector. For vfma_lane, it has the
     // same shape as the result vector.
-    cir::VectorType sourceTy = cir::VectorType::get(
+    cir::VectorType sourceTy = cir::VectorType::getFixed(
         ty.getElementType(), builtinID == NEON::BI__builtin_neon_vfmaq_lane_v
-                                 ? ty.getSize() / 2
-                                 : ty.getSize());
+                                 ? ty.getFixedSize() / 2
+                                 : ty.getFixedSize());
     mlir::Value laneSource = builder.createBitcast(ops[2], sourceTy);
-    laneSource = emitNeonSplat(builder, loc, laneSource, ops[3], ty.getSize());
+    laneSource =
+        emitNeonSplat(builder, loc, laneSource, ops[3], ty.getFixedSize());
 
     llvm::SmallVector<mlir::Value> fmaOps = {multiplicand, laneSource, addend};
     return emitNeonCallToOp<cir::FMAOp>(cgm, builder, {ty, ty, ty}, fmaOps,
@@ -3219,7 +3220,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
       mlir::Value multiplicand = builder.createBitcast(ops[1], cgm.doubleTy);
       // The laneq source operand is float64x2_t, so the source vector has two
       // double lanes.
-      cir::VectorType sourceTy = cir::VectorType::get(cgm.doubleTy, 2);
+      cir::VectorType sourceTy = cir::VectorType::getFixed(cgm.doubleTy, 2);
       mlir::Value laneSource = builder.createBitcast(ops[2], sourceTy);
       laneSource = builder.createExtractElement(
           loc, laneSource,
@@ -3239,9 +3240,10 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     // The laneq source operand is the quad vector, so it has twice as many
     // lanes as the non-quad result vector.
     cir::VectorType sourceTy =
-        cir::VectorType::get(ty.getElementType(), ty.getSize() * 2);
+        cir::VectorType::getFixed(ty.getElementType(), ty.getFixedSize() * 2);
     mlir::Value laneSource = builder.createBitcast(ops[2], sourceTy);
-    laneSource = emitNeonSplat(builder, loc, laneSource, ops[3], ty.getSize());
+    laneSource =
+        emitNeonSplat(builder, loc, laneSource, ops[3], ty.getFixedSize());
 
     llvm::SmallVector<mlir::Value> fmaOps = {laneSource, multiplicand, addend};
     return emitNeonCallToOp<cir::FMAOp>(cgm, builder, {ty, ty, ty}, fmaOps,
@@ -3251,7 +3253,8 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     mlir::Value addend = builder.createBitcast(ops[0], ty);
     mlir::Value multiplicand = builder.createBitcast(ops[1], ty);
     mlir::Value laneSource = builder.createBitcast(ops[2], ty);
-    laneSource = emitNeonSplat(builder, loc, laneSource, ops[3], ty.getSize());
+    laneSource =
+        emitNeonSplat(builder, loc, laneSource, ops[3], ty.getFixedSize());
 
     llvm::SmallVector<mlir::Value> fmaOps = {laneSource, multiplicand, addend};
     return emitNeonCallToOp<cir::FMAOp>(cgm, builder, {ty, ty, ty}, fmaOps,
@@ -3482,14 +3485,14 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
         this, NeonTypeFlags(NeonTypeFlags::Float64, false, type.isQuad()));
     return builder.createCast(loc, cir::CastKind::int_to_float, ops[0], ty);
   case NEON::BI__builtin_neon_vcvt_f64_f32: {
-    auto v2f32 = cir::VectorType::get(cgm.floatTy, 2);
-    auto v2f64 = cir::VectorType::get(cgm.doubleTy, 2);
+    auto v2f32 = cir::VectorType::getFixed(cgm.floatTy, 2);
+    auto v2f64 = cir::VectorType::getFixed(cgm.doubleTy, 2);
     return builder.createFloatingCast(builder.createBitcast(ops[0], v2f32),
                                       v2f64);
   }
   case NEON::BI__builtin_neon_vcvt_f32_f64: {
-    auto v2f32 = cir::VectorType::get(cgm.floatTy, 2);
-    auto v2f64 = cir::VectorType::get(cgm.doubleTy, 2);
+    auto v2f32 = cir::VectorType::getFixed(cgm.floatTy, 2);
+    auto v2f64 = cir::VectorType::getFixed(cgm.doubleTy, 2);
     return builder.createFloatingCast(builder.createBitcast(ops[0], v2f64),
                                       v2f32);
   }
@@ -3843,7 +3846,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
 
     for (unsigned vi = 0; vi != 2; ++vi) {
       llvm::SmallVector<int64_t, 16> indices;
-      for (unsigned i = 0, e = ty.getSize(); i != e; i += 2) {
+      for (unsigned i = 0, e = ty.getFixedSize(); i != e; i += 2) {
         indices.push_back(i + vi);
         indices.push_back(i + e + vi);
       }
@@ -3864,7 +3867,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     mlir::Value sv;
     for (unsigned vi = 0; vi != 2; ++vi) {
       llvm::SmallVector<int64_t, 16> indices;
-      for (unsigned i = 0, e = ty.getSize(); i != e; ++i) {
+      for (unsigned i = 0, e = ty.getFixedSize(); i != e; ++i) {
         indices.push_back(2 * i + vi);
       }
       cir::ConstantOp idx = builder.getConstInt(loc, builder.getSInt32Ty(), 
vi);
@@ -3884,7 +3887,7 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
     mlir::Value sv;
     for (unsigned vi = 0; vi != 2; ++vi) {
       llvm::SmallVector<int64_t, 16> indices;
-      for (unsigned i = 0, e = ty.getSize(); i != e; i += 2) {
+      for (unsigned i = 0, e = ty.getFixedSize(); i != e; i += 2) {
         indices.push_back((i + vi * e) >> 1);
         indices.push_back(((i + vi * e) >> 1) + e);
       }

diff  --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index c4bd6b687c8f57..35d1b67563df62 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -69,7 +69,7 @@ static mlir::Value emitVectorFCmp(CIRGenFunction &cgf, const 
CallExpr &expr,
 
 static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, mlir::Location 
loc,
                                    mlir::Value mask, unsigned numElems) {
-  auto maskTy = cir::VectorType::get(
+  auto maskTy = cir::VectorType::getFixed(
       builder.getSIntNTy(1), cast<cir::IntType>(mask.getType()).getWidth());
   mlir::Value maskVec = builder.createBitcast(mask, maskTy);
 
@@ -184,7 +184,7 @@ static mlir::Value emitX86CompressStore(CIRGenBuilderTy 
&builder,
                                         ArrayRef<mlir::Value> ops) {
   auto resultTy = cast<cir::VectorType>(ops[1].getType());
   mlir::Value maskValue =
-      getMaskVecValue(builder, loc, ops[2], resultTy.getSize());
+      getMaskVecValue(builder, loc, ops[2], resultTy.getFixedSize());
 
   return builder.emitIntrinsicCallOp(
       loc, "masked.compressstore", cir::VoidType::get(builder.getContext()),
@@ -206,7 +206,7 @@ static cir::VecShuffleOp emitPshufWord(CIRGenBuilderTy 
&builder,
   uint32_t imm = CIRGenFunction::getZExtIntValueFromConstOp(immediate);
 
   auto vecTy = cast<cir::VectorType>(vec.getType());
-  unsigned numElts = vecTy.getSize();
+  unsigned numElts = vecTy.getFixedSize();
 
   unsigned firstHalfStart = isLow ? 0 : 4;
   unsigned secondHalfStart = 4 - firstHalfStart;
@@ -234,7 +234,7 @@ computeFullLaneShuffleMask(CIRGenFunction &cgf, const 
mlir::Value vec,
                            uint32_t imm, const bool isShufP,
                            llvm::SmallVectorImpl<int64_t> &outIndices) {
   auto vecTy = cast<cir::VectorType>(vec.getType());
-  unsigned numElts = vecTy.getSize();
+  unsigned numElts = vecTy.getFixedSize();
   unsigned numLanes = cgf.cgm.getDataLayout().getTypeSizeInBits(vecTy) / 128;
   unsigned numLaneElts = numElts / numLanes;
 
@@ -286,8 +286,9 @@ static mlir::Value emitX86CompressExpand(CIRGenBuilderTy 
&builder,
                                          mlir::Value inputVector,
                                          const std::string &id) {
   auto resultTy = cast<cir::VectorType>(mask.getType());
-  mlir::Value maskValue = getMaskVecValue(
-      builder, loc, inputVector, cast<cir::VectorType>(resultTy).getSize());
+  mlir::Value maskValue =
+      getMaskVecValue(builder, loc, inputVector,
+                      cast<cir::VectorType>(resultTy).getFixedSize());
   return builder.emitIntrinsicCallOp(loc, id, resultTy,
                                      mlir::ValueRange{source, mask, 
maskValue});
 }
@@ -297,7 +298,8 @@ emitEncodeKey(mlir::MLIRContext *context, CIRGenBuilderTy 
&builder,
               const mlir::Location &location, mlir::ValueRange inputOperands,
               mlir::Value outputOperand, std::uint8_t vecOutputCount,
               const std::string &intrinsicName, std::uint8_t numResults) {
-  cir::VectorType resVector = cir::VectorType::get(builder.getUInt64Ty(), 2);
+  cir::VectorType resVector =
+      cir::VectorType::getFixed(builder.getUInt64Ty(), 2);
   llvm::SmallVector<mlir::Type> members{builder.getUInt32Ty()};
   llvm::append_range(members,
                      llvm::SmallVector<mlir::Type>(vecOutputCount, resVector));
@@ -328,7 +330,7 @@ static mlir::Value emitX86Select(CIRGenBuilderTy &builder, 
mlir::Location loc,
     return op0;
 
   mask = getMaskVecValue(builder, loc, mask,
-                         cast<cir::VectorType>(op0.getType()).getSize());
+                         cast<cir::VectorType>(op0.getType()).getFixedSize());
 
   return cir::VecTernaryOp::create(builder, loc, mask, op0, op1);
 }
@@ -341,7 +343,7 @@ static mlir::Value getMaskZeroBitAsBool(CIRGenBuilderTy 
&builder,
   assert(intTy && "mask must be an integer type");
   unsigned width = intTy.getWidth();
 
-  auto maskVecTy = cir::VectorType::get(builder.getSIntNTy(1), width);
+  auto maskVecTy = cir::VectorType::getFixed(builder.getSIntNTy(1), width);
   mlir::Value maskVec = builder.createBitcast(mask, maskVecTy);
 
   // Extract bit 0 from the mask vector
@@ -478,14 +480,14 @@ emitX86MaskedCompare(CIRGenBuilderTy &builder, unsigned 
cc, bool isSigned,
                      ArrayRef<mlir::Value> ops, mlir::Location loc) {
   assert((ops.size() == 2 || ops.size() == 4) &&
          "Unexpected number of arguments");
-  unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+  unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
   mlir::Value cmp;
   if (cc == 3) {
     cmp = builder.getNullValue(
-        cir::VectorType::get(builder.getSIntNTy(1), numElts), loc);
+        cir::VectorType::getFixed(builder.getSIntNTy(1), numElts), loc);
   } else if (cc == 7) {
     cir::VectorType resultTy =
-        cir::VectorType::get(builder.getSIntNTy(1), numElts);
+        cir::VectorType::getFixed(builder.getSIntNTy(1), numElts);
     llvm::APInt allOnes = llvm::APInt::getAllOnes(1);
     cmp = cir::VecSplatOp::create(
         builder, loc, resultTy,
@@ -515,7 +517,7 @@ emitX86MaskedCompare(CIRGenBuilderTy &builder, unsigned cc, 
bool isSigned,
       break;
     }
 
-    auto resultTy = cir::VectorType::get(builder.getSIntNTy(1), numElts);
+    auto resultTy = cir::VectorType::getFixed(builder.getSIntNTy(1), numElts);
     cmp = cir::VecCmpOp::create(builder, loc, resultTy, pred, ops[0], ops[1]);
   }
 
@@ -540,7 +542,7 @@ static std::optional<mlir::Value> 
emitX86SExtMask(CIRGenBuilderTy &builder,
                                                   mlir::Value op,
                                                   mlir::Type dstTy,
                                                   mlir::Location loc) {
-  unsigned numberOfElements = cast<cir::VectorType>(dstTy).getSize();
+  unsigned numberOfElements = cast<cir::VectorType>(dstTy).getFixedSize();
   mlir::Value mask = getMaskVecValue(builder, loc, op, numberOfElements);
 
   return builder.createCast(loc, cir::CastKind::integral, mask, dstTy);
@@ -549,7 +551,7 @@ static std::optional<mlir::Value> 
emitX86SExtMask(CIRGenBuilderTy &builder,
 static mlir::Value emitVecInsert(CIRGenBuilderTy &builder, mlir::Location loc,
                                  mlir::Value vec, mlir::Value value,
                                  mlir::Value indexOp) {
-  unsigned numElts = cast<cir::VectorType>(vec.getType()).getSize();
+  unsigned numElts = cast<cir::VectorType>(vec.getType()).getFixedSize();
 
   uint64_t index =
       indexOp.getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
@@ -572,7 +574,7 @@ static mlir::Value emitX86FunnelShift(CIRGenBuilderTy 
&builder,
   // so we only care about the lowest log2 bits anyway.
   if (amt.getType() != op0Ty) {
     auto vecTy = mlir::cast<cir::VectorType>(op0Ty);
-    uint64_t numElems = vecTy.getSize();
+    uint64_t numElems = vecTy.getFixedSize();
 
     auto amtTy = mlir::cast<cir::IntType>(amt.getType());
     auto vecElemTy = mlir::cast<cir::IntType>(vecTy.getElementType());
@@ -586,8 +588,8 @@ static mlir::Value emitX86FunnelShift(CIRGenBuilderTy 
&builder,
     cir::IntType unsignedVecElemType = 
builder.getUIntNTy(vecElemTy.getWidth());
     amt = builder.createIntCast(amt, unsignedVecElemType);
     amt = cir::VecSplatOp::create(
-        builder, location, cir::VectorType::get(unsignedVecElemType, numElems),
-        amt);
+        builder, location,
+        cir::VectorType::getFixed(unsignedVecElemType, numElems), amt);
   }
 
   const StringRef intrinsicName = isRight ? "fshr" : "fshl";
@@ -599,8 +601,8 @@ static mlir::Value emitX86Muldq(CIRGenBuilderTy &builder, 
mlir::Location loc,
                                 bool isSigned,
                                 SmallVectorImpl<mlir::Value> &ops,
                                 unsigned opTypePrimitiveSizeInBits) {
-  mlir::Type ty = cir::VectorType::get(builder.getSInt64Ty(),
-                                       opTypePrimitiveSizeInBits / 64);
+  mlir::Type ty = cir::VectorType::getFixed(builder.getSInt64Ty(),
+                                            opTypePrimitiveSizeInBits / 64);
   mlir::Value lhs = builder.createBitcast(loc, ops[0], ty);
   mlir::Value rhs = builder.createBitcast(loc, ops[1], ty);
   if (isSigned) {
@@ -647,18 +649,18 @@ static mlir::Value 
emitX86CvtF16ToFloatExpr(CIRGenBuilderTy &builder,
     }
   }
 
-  unsigned numElts = cast<cir::VectorType>(dstTy).getSize();
+  unsigned numElts = cast<cir::VectorType>(dstTy).getFixedSize();
   mlir::Value src = ops[0];
 
   // Extract the subvector
-  if (numElts != cast<cir::VectorType>(src.getType()).getSize()) {
+  if (numElts != cast<cir::VectorType>(src.getType()).getFixedSize()) {
     assert(numElts == 4 && "Unexpected vector size");
     src = builder.createVecShuffle(loc, src, {0, 1, 2, 3});
   }
 
   // Bitcast from vXi16 to vXf16.
-  cir::VectorType halfTy =
-      cir::VectorType::get(cir::FP16Type::get(builder.getContext()), numElts);
+  cir::VectorType halfTy = cir::VectorType::getFixed(
+      cir::FP16Type::get(builder.getContext()), numElts);
 
   src = builder.createCast(cir::CastKind::bitcast, src, halfTy);
 
@@ -728,7 +730,7 @@ static mlir::Value emitX86vpcom(CIRGenBuilderTy &builder, 
mlir::Location loc,
 static mlir::Value emitX86Fpclass(CIRGenBuilderTy &builder, mlir::Location loc,
                                   unsigned builtinID,
                                   SmallVectorImpl<mlir::Value> &ops) {
-  unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+  unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
   mlir::Value maskIn = ops[2];
   ops.erase(ops.begin() + 2);
 
@@ -774,7 +776,7 @@ static mlir::Value emitX86Fpclass(CIRGenBuilderTy &builder, 
mlir::Location loc,
     break;
   }
 
-  auto cmpResultTy = cir::VectorType::get(builder.getSIntNTy(1), numElts);
+  auto cmpResultTy = cir::VectorType::getFixed(builder.getSIntNTy(1), numElts);
   mlir::Value fpclass =
       builder.emitIntrinsicCallOp(loc, intrinsicName, cmpResultTy, ops);
   return emitX86MaskedCompareResult(builder, fpclass, numElts, maskIn, loc);
@@ -903,8 +905,8 @@ static mlir::Value emitX86MaskedLoad(CIRGenBuilderTy 
&builder,
                                      mlir::Location loc) {
   mlir::Type ty = ops[1].getType();
   mlir::Value ptr = ops[0];
-  mlir::Value maskVec = getMaskVecValue(builder, loc, ops[2],
-                                        cast<cir::VectorType>(ty).getSize());
+  mlir::Value maskVec = getMaskVecValue(
+      builder, loc, ops[2], cast<cir::VectorType>(ty).getFixedSize());
 
   return builder.createMaskedLoad(loc, ty, ptr, alignment, maskVec, ops[1]);
 }
@@ -913,7 +915,7 @@ static mlir::Value emitX86VPerm2f128(CIRGenBuilderTy 
&builder,
                                      mlir::Location loc,
                                      llvm::SmallVector<mlir::Value> ops) {
   auto inputType = cast<cir::VectorType>(ops[0].getType());
-  assert(!inputType.getIsScalable() &&
+  assert(!inputType.isScalable() &&
          "This is only intended for fixed-width vectors");
 
   const uint8_t imm = CIRGenFunction::getZExtIntValueFromConstOp(ops[2]);
@@ -927,7 +929,7 @@ static mlir::Value emitX86VPerm2f128(CIRGenBuilderTy 
&builder,
   llvm::SmallVector<mlir::Attribute, 64> mask;
 
   cir::IntType i32Ty = builder.getSInt32Ty();
-  const unsigned numElts = inputType.getSize();
+  const unsigned numElts = inputType.getFixedSize();
   // We must evaluated each lane(128 bits) separetely
   for (auto lane : llvm::seq(0, 2)) {
     bool isZeroBit = imm & (1 << ((lane * 4) + 3)),
@@ -958,7 +960,7 @@ static mlir::Value emitX86PackedByteShift(CIRGenBuilderTy 
&builder,
                                           llvm::ArrayRef<mlir::Value> ops,
                                           llvm::Boolean isLeftShift) {
   auto byteVecType = cast<cir::VectorType>(ops[0].getType());
-  assert(!byteVecType.getIsScalable() &&
+  assert(!byteVecType.isScalable() &&
          "This is only intended for fixed-width vectors");
 
   unsigned shiftVal = CIRGenFunction::getZExtIntValueFromConstOp(ops[1]) & 
0xFF;
@@ -970,7 +972,7 @@ static mlir::Value emitX86PackedByteShift(CIRGenBuilderTy 
&builder,
   if (shiftVal >= 16)
     return zeroVector;
 
-  uint64_t numElts = byteVecType.getSize();
+  uint64_t numElts = byteVecType.getFixedSize();
   assert(numElts % 16 == 0 && "Expected a multiple of 16");
 
   llvm::SmallVector<int64_t, 64> shuffleMask;
@@ -1285,7 +1287,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_vec_ext_v16hi:
   case X86::BI__builtin_ia32_vec_ext_v8si:
   case X86::BI__builtin_ia32_vec_ext_v4di: {
-    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
 
     uint64_t index = getZExtIntValueFromConstOp(ops[1]);
     index &= numElts - 1;
@@ -1774,8 +1776,8 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
 
     mlir::Location loc = getLoc(expr->getExprLoc());
     unsigned minElts =
-        std::min(cast<cir::VectorType>(ops[0].getType()).getSize(),
-                 cast<cir::VectorType>(ops[2].getType()).getSize());
+        std::min(cast<cir::VectorType>(ops[0].getType()).getFixedSize(),
+                 cast<cir::VectorType>(ops[2].getType()).getFixedSize());
     ops[3] = getMaskVecValue(builder, loc, ops[3], minElts);
     return builder.emitIntrinsicCallOp(loc, intrinsicName,
                                        convertType(expr->getType()), ops);
@@ -1884,8 +1886,8 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
 
     mlir::Location loc = getLoc(expr->getExprLoc());
     unsigned minElts =
-        std::min(cast<cir::VectorType>(ops[2].getType()).getSize(),
-                 cast<cir::VectorType>(ops[3].getType()).getSize());
+        std::min(cast<cir::VectorType>(ops[2].getType()).getFixedSize(),
+                 cast<cir::VectorType>(ops[3].getType()).getFixedSize());
     ops[1] = getMaskVecValue(builder, loc, ops[1], minElts);
 
     return builder.emitIntrinsicCallOp(loc, intrinsicName,
@@ -1909,8 +1911,9 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_extracti64x2_512_mask: {
     mlir::Location loc = getLoc(expr->getExprLoc());
     cir::VectorType dstTy = 
cast<cir::VectorType>(convertType(expr->getType()));
-    unsigned numElts = dstTy.getSize();
-    unsigned srcNumElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = dstTy.getFixedSize();
+    unsigned srcNumElts =
+        cast<cir::VectorType>(ops[0].getType()).getFixedSize();
     unsigned subVectors = srcNumElts / numElts;
     assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 
subvectors");
     unsigned index =
@@ -1947,8 +1950,10 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_inserti64x2_256:
   case X86::BI__builtin_ia32_insertf64x2_512:
   case X86::BI__builtin_ia32_inserti64x2_512: {
-    unsigned dstNumElts = cast<cir::VectorType>(ops[0].getType()).getSize();
-    unsigned srcNumElts = cast<cir::VectorType>(ops[1].getType()).getSize();
+    unsigned dstNumElts =
+        cast<cir::VectorType>(ops[0].getType()).getFixedSize();
+    unsigned srcNumElts =
+        cast<cir::VectorType>(ops[1].getType()).getFixedSize();
     unsigned subVectors = dstNumElts / srcNumElts;
     assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 
subvectors");
     assert(dstNumElts <= 16);
@@ -1990,7 +1995,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_pblendd128:
   case X86::BI__builtin_ia32_pblendd256: {
     uint32_t imm = getZExtIntValueFromConstOp(ops[2]);
-    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
 
     llvm::SmallVector<mlir::Attribute, 16> indices;
     // If there are more than 8 elements, the immediate is used twice so make
@@ -2049,7 +2054,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_permdf512: {
     unsigned imm =
         ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
-    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
 
     // These intrinsics operate on 256-bit lanes of four 64-bit elements.
     int64_t Indices[8];
@@ -2066,7 +2071,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_palignr512: {
     uint32_t shiftVal = getZExtIntValueFromConstOp(ops[2]) & 0xff;
 
-    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
     assert(numElts % 16 == 0);
 
     // If palignr is shifting the pair of vectors more than the size of two
@@ -2104,7 +2109,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_alignq128:
   case X86::BI__builtin_ia32_alignq256:
   case X86::BI__builtin_ia32_alignq512: {
-    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
     unsigned shiftVal =
         ops[2].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue() &
         0xff;
@@ -2134,7 +2139,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
     unsigned imm =
         ops[2].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
 
-    unsigned numElems = cast<cir::VectorType>(src1.getType()).getSize();
+    unsigned numElems = cast<cir::VectorType>(src1.getType()).getFixedSize();
     unsigned totalBits = getContext().getTypeSize(expr->getArg(0)->getType());
     unsigned numLanes = totalBits == 512 ? 4 : 2;
     unsigned numElemsPerLane = numElems / numLanes;
@@ -2656,7 +2661,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
   case X86::BI__builtin_ia32_vp2intersect_d_512:
   case X86::BI__builtin_ia32_vp2intersect_d_256:
   case X86::BI__builtin_ia32_vp2intersect_d_128: {
-    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
+    unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getFixedSize();
     mlir::Location loc = getLoc(expr->getExprLoc());
     StringRef intrinsicName;
 
@@ -2683,7 +2688,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
       break;
     }
 
-    auto resVector = cir::VectorType::get(builder.getSIntNTy(1), numElts);
+    auto resVector = cir::VectorType::getFixed(builder.getSIntNTy(1), numElts);
 
     mlir::Type resMembers[] = {resVector, resVector};
     cir::StructType resRecord = cir::StructType::get(
@@ -2797,7 +2802,7 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, 
const CallExpr *expr) {
     cir::VectorType resTy = 
cast<cir::VectorType>(convertType(expr->getType()));
 
     cir::VectorType inputTy = cast<cir::VectorType>(ops[0].getType());
-    unsigned numElts = inputTy.getSize();
+    unsigned numElts = inputTy.getFixedSize();
 
     mlir::Value mask = getMaskVecValue(builder, loc, ops[2], numElts);
 

diff  --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index dfd6fa725e77fe..a8181c8c6a5b40 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -351,7 +351,7 @@ void 
CIRGenFunction::emitStoreThroughExtVectorComponentLValue(RValue src,
   mlir::Value vec = builder.createLoad(loc, dstAddr, dst.isVolatile());
   if (const auto *vecTy = dst.getType()->getAs<clang::VectorType>()) {
     unsigned numSrcElts = vecTy->getNumElements();
-    unsigned numDstElts = cast<cir::VectorType>(vec.getType()).getSize();
+    unsigned numDstElts = cast<cir::VectorType>(vec.getType()).getFixedSize();
     if (numDstElts == numSrcElts) {
       // Use shuffle vector is the src and destination are the same number of
       // elements and restore the vector mask since it is on the side it will 
be

diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 886d42d4b2f977..eef3a4e479ba8f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1625,10 +1625,10 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
     mlir::Type dstTy = cgf.convertType(e->getType());
 
     unsigned numElementsSrc = isa<cir::VectorType>(srcTy)
-                                  ? cast<cir::VectorType>(srcTy).getSize()
+                                  ? cast<cir::VectorType>(srcTy).getFixedSize()
                                   : 0;
     unsigned numElementsDst = isa<cir::VectorType>(dstTy)
-                                  ? cast<cir::VectorType>(dstTy).getSize()
+                                  ? cast<cir::VectorType>(dstTy).getFixedSize()
                                   : 0;
 
     // Use bit vector expansion for ext_vector_type boolean vectors.
@@ -1653,7 +1653,7 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
     if (numElementsSrc != 3 && numElementsDst == 3) {
       mlir::Location loc = cgf.getLoc(e->getExprLoc());
       auto dstElemTy = cast<cir::VectorType>(dstTy).getElementType();
-      auto dstVec4Ty = cir::VectorType::get(dstElemTy, 4);
+      auto dstVec4Ty = cir::VectorType::getFixed(dstElemTy, 4);
       src = createCastsForTypeOfSameSize(src, dstVec4Ty);
       src = convertVec3AndVec4(builder, loc, src, 3);
       return src;
@@ -2989,7 +2989,7 @@ mlir::Value
 ScalarExprEmitter::emitVectorInitWithSubvectors(mlir::Location loc,
                                                 cir::VectorType vectorType,
                                                 ArrayRef<mlir::Value> inits) {
-  const unsigned resElts = vectorType.getSize();
+  const unsigned resElts = vectorType.getFixedSize();
   mlir::Value result =
       builder.getConstant(loc, cir::PoisonAttr::get(vectorType));
   unsigned curIdx = 0;
@@ -3000,7 +3000,7 @@ 
ScalarExprEmitter::emitVectorInitWithSubvectors(mlir::Location loc,
       continue;
     }
 
-    const unsigned initElts = initType.getSize();
+    const unsigned initElts = initType.getFixedSize();
     assert(curIdx + initElts <= resElts &&
            "Sema should reject excess elements");
     SmallVector<int64_t, 16> mask(resElts, -1);
@@ -3055,11 +3055,12 @@ mlir::Value 
ScalarExprEmitter::VisitInitListExpr(InitListExpr *e) {
                                           vectorType, elements);
 
     // Zero-initialize any remaining values.
-    if (numInitElements < vectorType.getSize()) {
+    const uint64_t vectorSize = vectorType.getFixedSize();
+    if (numInitElements < vectorSize) {
       const mlir::Value zeroValue = cgf.getBuilder().getNullValue(
           vectorType.getElementType(), cgf.getLoc(e->getSourceRange()));
-      std::fill_n(std::back_inserter(elements),
-                  vectorType.getSize() - numInitElements, zeroValue);
+      std::fill_n(std::back_inserter(elements), vectorSize - numInitElements,
+                  zeroValue);
     }
 
     return cir::VecCreateOp::create(cgf.getBuilder(),
@@ -3274,7 +3275,7 @@ mlir::Value 
ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
     return builder.getConstantInt(loc, cgf.cgm.sizeTy, alignment);
   } else if (e->getKind() == UETT_VectorElements) {
     auto vecTy = cast<cir::VectorType>(convertType(e->getTypeOfArgument()));
-    if (vecTy.getIsScalable()) {
+    if (vecTy.isScalable()) {
       cgf.getCIRGenModule().errorNYI(
           e->getSourceRange(),
           "VisitUnaryExprOrTypeTraitExpr: sizeOf scalable vector");
@@ -3284,7 +3285,7 @@ mlir::Value 
ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
     }
 
     return builder.getConstant(
-        loc, cir::IntAttr::get(cgf.cgm.sizeTy, vecTy.getSize()));
+        loc, cir::IntAttr::get(cgf.cgm.sizeTy, vecTy.getFixedSize()));
   }
 
   // The result type is size_t (target-dependent width); use it so the IntAttr

diff  --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 6e564288447676..f07d2948cb1b23 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -379,56 +379,43 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
 
     // SVE types
     case BuiltinType::SveInt8:
-      resultType =
-          cir::VectorType::get(builder.getSInt8Ty(), 16, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getSInt8Ty(), 16);
       break;
     case BuiltinType::SveUint8:
-      resultType =
-          cir::VectorType::get(builder.getUInt8Ty(), 16, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getUInt8Ty(), 16);
       break;
     case BuiltinType::SveInt16:
-      resultType =
-          cir::VectorType::get(builder.getSInt16Ty(), 8, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getSInt16Ty(), 8);
       break;
     case BuiltinType::SveUint16:
-      resultType =
-          cir::VectorType::get(builder.getUInt16Ty(), 8, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getUInt16Ty(), 8);
       break;
     case BuiltinType::SveFloat16:
-      resultType = cir::VectorType::get(builder.getFp16Ty(), 8,
-                                        /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getFp16Ty(), 8);
       break;
     case BuiltinType::SveBFloat16:
-      resultType = cir::VectorType::get(builder.getBfloat16Ty(), 8,
-                                        /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getBfloat16Ty(), 8);
       break;
     case BuiltinType::SveInt32:
-      resultType =
-          cir::VectorType::get(builder.getSInt32Ty(), 4, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getSInt32Ty(), 4);
       break;
     case BuiltinType::SveUint32:
-      resultType =
-          cir::VectorType::get(builder.getUInt32Ty(), 4, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getUInt32Ty(), 4);
       break;
     case BuiltinType::SveFloat32:
-      resultType = cir::VectorType::get(builder.getSingleTy(), 4,
-                                        /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getSingleTy(), 4);
       break;
     case BuiltinType::SveInt64:
-      resultType =
-          cir::VectorType::get(builder.getSInt64Ty(), 2, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getSInt64Ty(), 2);
       break;
     case BuiltinType::SveUint64:
-      resultType =
-          cir::VectorType::get(builder.getUInt64Ty(), 2, /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getUInt64Ty(), 2);
       break;
     case BuiltinType::SveFloat64:
-      resultType = cir::VectorType::get(builder.getDoubleTy(), 2,
-                                        /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getDoubleTy(), 2);
       break;
     case BuiltinType::SveBool:
-      resultType = cir::VectorType::get(builder.getUIntNTy(1), 16,
-                                        /*is_scalable=*/true);
+      resultType = cir::VectorType::getScalable(builder.getUIntNTy(1), 16);
       break;
 
     // Unsigned integral types.
@@ -509,7 +496,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
 #define AMDGPU_OPAQUE_PTR_TYPE(Name, Id, SingletonId, Width, Align, AS)        
\
   case BuiltinType::Id: {                                                      
\
     if (BuiltinType::Id == BuiltinType::AMDGPUTexture) {                       
\
-      resultType = cir::VectorType::get(builder.getSInt32Ty(), 8);             
\
+      resultType = cir::VectorType::getFixed(builder.getSInt32Ty(), 8);        
\
     } else {                                                                   
\
       resultType = builder.getPointerTo(                                       
\
           cgm.voidTy,                                                          
\
@@ -603,7 +590,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
   case Type::Vector: {
     const VectorType *vec = cast<VectorType>(ty);
     const mlir::Type elemTy = convertType(vec->getElementType());
-    resultType = cir::VectorType::get(elemTy, vec->getNumElements());
+    resultType = cir::VectorType::getFixed(elemTy, vec->getNumElements());
     break;
   }
 

diff  --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp 
b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
index e1c57c07cceceb..023ac73178152a 100644
--- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
@@ -912,7 +912,10 @@ 
cir::ConstVectorAttr::verify(function_ref<InFlightDiagnostic()> emitError,
 
   const auto vecType = mlir::cast<cir::VectorType>(type);
 
-  if (vecType.getSize() != elts.size())
+  if (vecType.isScalable())
+    return emitError() << "scalable vector constants are not supported";
+
+  if (vecType.getFixedSize() != elts.size())
     return emitError()
            << "number of constant elements should match vector size";
 

diff  --git a/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
index 5ce0c8f8e7a2c6..2347edcfee161d 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDataLayout.cpp
@@ -56,5 +56,5 @@ llvm::TypeSize CIRDataLayout::getTypeSizeInBits(mlir::Type 
ty) const {
   assert(!cir::MissingFeatures::addressSpace());
 
   // This is calling mlir::DataLayout::getTypeSizeInBits().
-  return llvm::TypeSize::getFixed(layout.getTypeSizeInBits(ty));
+  return layout.getTypeSizeInBits(ty);
 }

diff  --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index c569a9bc899ff4..2d69135f440458 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -4242,10 +4242,13 @@ LogicalResult cir::VecCreateOp::verify() {
   // vector, and that the type of all the arguments matches the type of the
   // elements in the vector.
   const cir::VectorType vecTy = getType();
-  if (getElements().size() != vecTy.getSize()) {
+  if (vecTy.isScalable())
+    return emitOpError() << "scalable vectors are not supported";
+
+  if (getElements().size() != vecTy.getFixedSize()) {
     return emitOpError() << "operand count of " << getElements().size()
                          << " doesn't match vector type " << vecTy
-                         << " element count of " << vecTy.getSize();
+                         << " element count of " << vecTy.getFixedSize();
   }
 
   const mlir::Type elementType = vecTy.getElementType();
@@ -4482,9 +4485,13 @@ OpFoldResult cir::VecShuffleOp::fold(FoldAdaptor 
adaptor) {
 }
 
 LogicalResult cir::VecShuffleOp::verify() {
+  if (getVec1().getType().isScalable() || getVec2().getType().isScalable() ||
+      getResult().getType().isScalable())
+    return emitOpError() << "scalable vectors are not supported";
+
   // The number of elements in the indices array must match the number of
   // elements in the result type.
-  if (getIndices().size() != getResult().getType().getSize()) {
+  if (getIndices().size() != getResult().getType().getFixedSize()) {
     return emitOpError() << ": the number of elements in " << getIndices()
                          << " and " << getResult().getType() << " don't match";
   }
@@ -4497,8 +4504,8 @@ LogicalResult cir::VecShuffleOp::verify() {
                          << " and " << getResult().getType() << " don't match";
   }
 
-  const uint64_t maxValidIndex =
-      getVec1().getType().getSize() + getVec2().getType().getSize() - 1;
+  const uint64_t maxValidIndex = getVec1().getType().getFixedSize() +
+                                 getVec2().getType().getFixedSize() - 1;
   if (llvm::any_of(
           getIndices().getAsRange<cir::IntAttr>(), [&](cir::IntAttr idxAttr) {
             return idxAttr.getSInt() != -1 && idxAttr.getUInt() > 
maxValidIndex;

diff  --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp 
b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
index ecdd5fd8584d0b..fee0344028c993 100644
--- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp
@@ -1501,32 +1501,34 @@ llvm::TypeSize cir::VectorType::getTypeSizeInBits(
     ::mlir::DataLayoutEntryListRef params) const {
   // Clang packs a fixed-length bool vector one bit per element and rounds the
   // vector's size up to a power of two of at least a byte.
-  if (mlir::isa<cir::BoolType>(getElementType()) && !getIsScalable()) {
+  if (mlir::isa<cir::BoolType>(getElementType()) && getSize().isFixed()) {
     assert(!cir::MissingFeatures::hlsl());
     return llvm::TypeSize::getFixed(llvm::PowerOf2Ceil(getBoolStorageWidth()));
   }
-  return llvm::TypeSize::getFixed(
-      getSize() * dataLayout.getTypeSizeInBits(getElementType()));
+
+  llvm::TypeSize elementSize = dataLayout.getTypeSizeInBits(getElementType());
+  return llvm::TypeSize::get(
+      getSize().getKnownMinValue() * elementSize.getFixedValue(), 
isScalable());
 }
 
 uint64_t cir::VectorType::getBoolStorageWidth() const {
   assert(mlir::isa<cir::BoolType>(getElementType()) &&
          "only a bool vector is stored as an integer");
-  return std::max<uint64_t>(getSize(), 8);
+  return std::max<uint64_t>(getFixedSize(), 8);
 }
 
 uint64_t
 cir::VectorType::getABIAlignment(const ::mlir::DataLayout &dataLayout,
                                  ::mlir::DataLayoutEntryListRef params) const {
   // This hook answers in bytes, not bits.
-  return llvm::PowerOf2Ceil(
-      llvm::divideCeil(dataLayout.getTypeSizeInBits(*this), 8u));
+  return llvm::PowerOf2Ceil(llvm::divideCeil(
+      dataLayout.getTypeSizeInBits(*this).getKnownMinValue(), uint64_t{8}));
 }
 
 mlir::LogicalResult cir::VectorType::verify(
     llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
-    mlir::Type elementType, uint64_t size, bool scalable) {
-  if (size == 0)
+    mlir::Type elementType, llvm::ElementCount size) {
+  if (size.isZero())
     return emitError() << "the number of vector elements must be non-zero";
   return success();
 }
@@ -1537,7 +1539,7 @@ mlir::Type cir::VectorType::parse(::mlir::AsmParser 
&odsParser) {
   mlir::Builder odsBuilder(odsParser.getContext());
   mlir::FailureOr<::mlir::Type> elementType;
   mlir::FailureOr<uint64_t> size;
-  bool isScalabe = false;
+  bool isScalable = false;
 
   // Parse literal '<'
   if (odsParser.parseLess())
@@ -1545,7 +1547,7 @@ mlir::Type cir::VectorType::parse(::mlir::AsmParser 
&odsParser) {
 
   // Parse literal '[', if present, and set the scalability flag accordingly
   if (odsParser.parseOptionalLSquare().succeeded())
-    isScalabe = true;
+    isScalable = true;
 
   // Parse variable 'size'
   size = mlir::FieldParser<uint64_t>::parse(odsParser);
@@ -1558,7 +1560,7 @@ mlir::Type cir::VectorType::parse(::mlir::AsmParser 
&odsParser) {
 
   // Parse literal ']', which is expected when dealing with scalable
   // dim sizes
-  if (isScalabe && odsParser.parseRSquare().failed()) {
+  if (isScalable && odsParser.parseRSquare().failed()) {
     odsParser.emitError(odsParser.getCurrentLocation(),
                         "missing closing `]` for scalable dim size");
     return {};
@@ -1580,19 +1582,19 @@ mlir::Type cir::VectorType::parse(::mlir::AsmParser 
&odsParser) {
   // Parse literal '>'
   if (odsParser.parseGreater())
     return {};
-  return odsParser.getChecked<VectorType>(odsLoc, odsParser.getContext(),
-                                          mlir::Type((*elementType)),
-                                          uint64_t((*size)), isScalabe);
+  return odsParser.getChecked<VectorType>(
+      odsLoc, odsParser.getContext(), mlir::Type((*elementType)),
+      llvm::ElementCount::get(*size, isScalable));
 }
 
 void cir::VectorType::print(mlir::AsmPrinter &odsPrinter) const {
   mlir::Builder odsBuilder(getContext());
   odsPrinter << "<";
-  if (this->getIsScalable())
+  if (isScalable())
     odsPrinter << "[";
 
-  odsPrinter.printStrippedAttrOrType(getSize());
-  if (this->getIsScalable())
+  odsPrinter.printStrippedAttrOrType(getSize().getKnownMinValue());
+  if (isScalable())
     odsPrinter << "]";
   odsPrinter << ' ' << "x";
   odsPrinter << ' ';

diff  --git a/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp 
b/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
index 9d569be7b80cb0..fe358ba9b273d6 100644
--- a/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CIRSimplify.cpp
@@ -375,9 +375,9 @@ struct SimplifyVecSplat : public 
OpRewritePattern<VecSplatOp> {
     // we can simplify it here too.
     assert(!MissingFeatures::matrixType());
     auto resultType = 
mlir::dyn_cast<cir::VectorType>(op.getResult().getType());
-    if (!resultType)
+    if (!resultType || resultType.isScalable())
       return mlir::failure();
-    SmallVector<mlir::Attribute, 16> elements(resultType.getSize(), value);
+    SmallVector<mlir::Attribute, 16> elements(resultType.getFixedSize(), 
value);
     auto constVecAttr = cir::ConstVectorAttr::get(
         resultType, mlir::ArrayAttr::get(getContext(), elements));
 

diff  --git a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp 
b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
index a978d3a899c2a8..ddf60a1547f965 100644
--- a/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/CallConvLoweringPass.cpp
@@ -203,7 +203,7 @@ static bool isSupportedType(mlir::Type ty, const DataLayout 
&dl) {
   if (auto vecTy = dyn_cast<cir::VectorType>(ty)) {
     // A scalable vector has no size the SysV eightbyte rules can read, and
     // x86_64 has no calling convention for one.
-    if (vecTy.getIsScalable())
+    if (vecTy.isScalable())
       return false;
     // mapCIRType maps a bool as a one-bit integer, so a bool vector is sized
     // one bit per element, as clang packs it.  Vectors of a _BitInt whose
@@ -319,8 +319,8 @@ static mlir::Type abiTypeToCIR(const llvm::abi::Type *ty, 
MLIRContext *ctx) {
         mlir::Type elemCIR = abiTypeToCIR(vecTy->getElementType(), ctx);
         if (!elemCIR)
           return nullptr;
-        return cir::VectorType::get(elemCIR,
-                                    vecTy->getNumElements().getFixedValue());
+        return cir::VectorType::getFixed(
+            elemCIR, vecTy->getNumElements().getFixedValue());
       })
       .Case([&](const llvm::abi::RecordType *recTy) -> mlir::Type {
         SmallVector<mlir::Type> fieldTypes;
@@ -346,8 +346,8 @@ static mlir::Type unwrapLongDoubleVectorElement(mlir::Type 
ty) {
   if (auto vecTy = dyn_cast<cir::VectorType>(ty)) {
     if (auto longDoubleTy =
             dyn_cast<cir::LongDoubleType>(vecTy.getElementType()))
-      return cir::VectorType::get(longDoubleTy.getUnderlying(), 
vecTy.getSize(),
-                                  vecTy.getIsScalable());
+      return cir::VectorType::get(longDoubleTy.getUnderlying(),
+                                  vecTy.getSize());
   }
   return ty;
 }
@@ -407,8 +407,7 @@ static const llvm::abi::Type *mapCIRType(mlir::Type type,
         // always fixed here.
         return tb.getVectorType(
             mapCIRType(vecTy.getElementType(), typeMapper, dl, modOp),
-            llvm::ElementCount::getFixed(vecTy.getSize()),
-            llvm::Align(dl.getTypeABIAlignment(type)));
+            vecTy.getSize(), llvm::Align(dl.getTypeABIAlignment(type)));
       })
       .Case([&](cir::ArrayType arrTy) {
         const llvm::abi::Type *elemAbi =

diff  --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 719ec9ac184ff6..6b6b932346382c 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -182,15 +182,17 @@ static mlir::Value 
emitFromMemory(mlir::ConversionPatternRewriter &rewriter,
   // Convert the `iN` back to boolean vectors
   if (auto vecTy = mlir::dyn_cast<cir::VectorType>(op.getType())) {
     if (mlir::isa<cir::BoolType>(vecTy.getElementType())) {
+      if (vecTy.isScalable())
+        return value;
       auto rawIntTy = mlir::cast<mlir::IntegerType>(value.getType());
-      auto paddedVecTy =
-          cir::VectorType::get(vecTy.getElementType(), rawIntTy.getWidth());
+      auto paddedVecTy = cir::VectorType::getFixed(vecTy.getElementType(),
+                                                   rawIntTy.getWidth());
       mlir::Type mlirVecTy = converter.convertType(paddedVecTy);
       // Bitcast iP --> <P x i1>.
       auto v = mlir::LLVM::BitcastOp::create(rewriter, value.getLoc(),
                                              mlirVecTy, value);
       // Shuffle <P x i1> --> <N x i1> (N is the actual bit size).
-      return emitBoolVecConversion(rewriter, v, vecTy.getSize());
+      return emitBoolVecConversion(rewriter, v, vecTy.getFixedSize());
     }
   }
 
@@ -225,9 +227,10 @@ static mlir::Value 
emitToMemory(mlir::ConversionPatternRewriter &rewriter,
   if (auto vecTy = mlir::dyn_cast<cir::VectorType>(origType)) {
     if (mlir::isa<cir::BoolType>(vecTy.getElementType())) {
       mlir::Type resultTy;
-      if (vecTy.getIsScalable())
-        resultTy = mlir::VectorType::get(
-            vecTy.getSize(), vecTy.getElementType(), vecTy.getIsScalable());
+      if (vecTy.isScalable())
+        resultTy =
+            mlir::VectorType::get(vecTy.getSize().getKnownMinValue(),
+                                  vecTy.getElementType(), vecTy.isScalable());
       else {
         resultTy = mlir::IntegerType::get(origType.getContext(),
                                           vecTy.getBoolStorageWidth());
@@ -3716,13 +3719,11 @@ mlir::LogicalResult 
CIRToLLVMNotOpLowering::matchAndRewrite(
   if (mlir::isa<cir::IntType>(elementType)) {
     mlir::Value minusOne;
     if (isVector) {
-      const uint64_t numElements =
-          mlir::cast<cir::VectorType>(op.getType()).getSize();
       const unsigned eltWidth =
           mlir::cast<cir::IntType>(elementType).getWidth();
-      SmallVector<APInt> values(numElements, APInt::getAllOnes(eltWidth));
-      mlir::DenseIntElementsAttr denseVec = mlir::DenseIntElementsAttr::get(
-          mlir::cast<mlir::ShapedType>(llvmType), values);
+      mlir::DenseElementsAttr denseVec =
+          mlir::DenseElementsAttr::get(mlir::cast<mlir::ShapedType>(llvmType),
+                                       {APInt::getAllOnes(eltWidth)});
       minusOne =
           mlir::LLVM::ConstantOp::create(rewriter, loc, llvmType, denseVec);
     } else {
@@ -3738,10 +3739,8 @@ mlir::LogicalResult 
CIRToLLVMNotOpLowering::matchAndRewrite(
   if (mlir::isa<cir::BoolType>(elementType)) {
     mlir::Value one;
     if (isVector) {
-      const uint64_t numElements =
-          mlir::cast<cir::VectorType>(op.getType()).getSize();
-      SmallVector<bool> values(numElements, true);
-      mlir::DenseIntElementsAttr denseVec = rewriter.getBoolVectorAttr(values);
+      mlir::DenseElementsAttr denseVec = mlir::DenseElementsAttr::get(
+          mlir::cast<mlir::ShapedType>(llvmType), {APInt(1, 1)});
       one = mlir::LLVM::ConstantOp::create(rewriter, loc, llvmType, denseVec);
     } else {
       one = mlir::LLVM::ConstantOp::create(rewriter, loc, llvmType, 1);
@@ -4371,7 +4370,8 @@ static void prepareTypeConverter(mlir::LLVMTypeConverter 
&converter,
     const mlir::Type ty = converter.convertType(type.getElementType());
     if (!ty)
       return {};
-    return mlir::VectorType::get(type.getSize(), ty, {type.getIsScalable()});
+    return mlir::VectorType::get(type.getSize().getKnownMinValue(), ty,
+                                 {type.isScalable()});
   });
   converter.addConversion([&](cir::MatrixType type) -> mlir::Type {
     const uint64_t size = type.getNumRows() * type.getNumColumns();
@@ -5423,10 +5423,11 @@ mlir::LogicalResult 
CIRToLLVMVecCreateOpLowering::matchAndRewrite(
   const mlir::Type llvmTy = typeConverter->convertType(vecTy);
   const mlir::Location loc = op.getLoc();
   mlir::Value result = mlir::LLVM::PoisonOp::create(rewriter, loc, llvmTy);
-  assert(vecTy.getSize() == op.getElements().size() &&
+  const uint64_t vectorSize = vecTy.getFixedSize();
+  assert(vectorSize == op.getElements().size() &&
          "cir.vec.create op count doesn't match vector type elements count");
 
-  for (uint64_t i = 0; i < vecTy.getSize(); ++i) {
+  for (uint64_t i = 0; i < vectorSize; ++i) {
     const mlir::Value indexValue =
         mlir::LLVM::ConstantOp::create(rewriter, loc, rewriter.getI64Type(), 
i);
     result = mlir::LLVM::InsertElementOp::create(
@@ -5518,8 +5519,9 @@ mlir::LogicalResult 
CIRToLLVMVecCmpOpLowering::matchAndRewrite(
         adaptor.getLhs(), adaptor.getRhs());
   } else if (mlir::isa<cir::FPTypeInterface>(elementType)) {
     if (cir::FenvAttr fenv = op.getFenvAttr()) {
-      auto i1VecTy = mlir::VectorType::get(op.getLhs().getType().getSize(),
-                                           rewriter.getI1Type());
+      llvm::ElementCount size = op.getLhs().getType().getSize();
+      auto i1VecTy = mlir::VectorType::get(
+          size.getKnownMinValue(), rewriter.getI1Type(), {size.isScalable()});
       bitResult = createConstrainedFCmpCall(rewriter, op.getLoc(),
                                             adaptor.getLhs(), adaptor.getRhs(),
                                             op.getKind(), fenv, i1VecTy)
@@ -5632,7 +5634,7 @@ mlir::LogicalResult 
CIRToLLVMVecShuffleDynamicOpLowering::matchAndRewrite(
       getTypeConverter()->convertType(op.getIndices().getType());
   mlir::Type llvmIndexType = getTypeConverter()->convertType(
       op.getIndices().getType().getElementType());
-  uint64_t numElements = op.getVec().getType().getSize();
+  uint64_t numElements = op.getVec().getType().getFixedSize();
 
   uint64_t maskBits = llvm::NextPowerOf2(numElements - 1) - 1;
   mlir::Value maskValue = mlir::LLVM::ConstantOp::create(

diff  --git a/clang/test/CIR/IR/invalid-vector.cir 
b/clang/test/CIR/IR/invalid-vector.cir
index 6152ca4a7a9481..3af3d494c5fd55 100644
--- a/clang/test/CIR/IR/invalid-vector.cir
+++ b/clang/test/CIR/IR/invalid-vector.cir
@@ -11,6 +11,45 @@ cir.global external @vec_b = #cir.zero : !cir.vector<4 x 
!cir.array<!s32i x 10>>
 
 // -----
 
+!s32i = !cir.int<s, 32>
+
+module {
+  cir.func @scalable_vector_constant() {
+    // expected-error @below {{scalable vector constants are not supported}}
+    %0 = cir.const #cir.const_vector<[#cir.int<1> : !s32i, #cir.int<2> : 
!s32i]> : !cir.vector<[2] x !s32i>
+    cir.return
+  }
+}
+
+// -----
+
+!s32i = !cir.int<s, 32>
+
+module {
+  cir.func @scalable_vector_create() {
+    %0 = cir.const #cir.int<1> : !s32i
+    %1 = cir.const #cir.int<2> : !s32i
+    // expected-error @below {{scalable vectors are not supported}}
+    %2 = cir.vec.create(%0, %1 : !s32i, !s32i) : !cir.vector<[2] x !s32i>
+    cir.return
+  }
+}
+
+// -----
+
+!s32i = !cir.int<s, 32>
+
+module {
+  cir.func @scalable_vector_shuffle(%arg0: !cir.vector<[2] x !s32i>,
+                                    %arg1: !cir.vector<[2] x !s32i>) {
+    // expected-error @below {{scalable vectors are not supported}}
+    %0 = cir.vec.shuffle(%arg0, %arg1 : !cir.vector<[2] x !s32i>) [#cir.int<0> 
: !s32i, #cir.int<1> : !s32i] : !cir.vector<[2] x !s32i>
+    cir.return
+  }
+}
+
+// -----
+
 cir.func @invalid_scalable_vec_syntax() {
   // expected-error@+2 {{missing closing `]` for scalable dim size}}
   // expected-error @below {{expected ']'}}

diff  --git a/clang/test/CIR/Lowering/not.cir b/clang/test/CIR/Lowering/not.cir
index d93f33cd84ba4b..adf8431ccd4278 100644
--- a/clang/test/CIR/Lowering/not.cir
+++ b/clang/test/CIR/Lowering/not.cir
@@ -2,6 +2,7 @@
 // RUN: cir-translate %s -cir-to-llvmir --target x86_64-unknown-linux-gnu 
--disable-cc-lowering  | FileCheck %s -check-prefix=LLVM
 
 !s128i = !cir.int<s, 128>
+!s32i = !cir.int<s, 32>
 !u128i = !cir.int<u, 128>
 
 module attributes { cir.triple = "x86_64-unknown-linux-gnu" } {
@@ -30,4 +31,17 @@ cir.func @unsigned(%arg: !u128i) -> !u128i {
 // LLVM: define i128 @unsigned(i128 %[[ARG:.*]])
 // LLVM: %[[INVERT:.*]] = xor i128 %[[ARG]], -1 
 // LLVM: ret i128 %[[INVERT]]
+
+cir.func @scalable_vector(%arg: !cir.vector<[4] x !s32i>) -> !cir.vector<[4] x 
!s32i> {
+  %inverted = cir.not %arg : !cir.vector<[4] x !s32i>
+  cir.return %inverted : !cir.vector<[4] x !s32i>
+}
+// MLIR: llvm.func @scalable_vector(%[[ARG:.*]]: vector<[4]xi32>) -> 
vector<[4]xi32>
+// MLIR: %[[NEG_ONE:.*]] = llvm.mlir.constant(dense<-1> : vector<[4]xi32>) : 
vector<[4]xi32>
+// MLIR: %[[INVERT:.*]] = llvm.xor %[[ARG]], %[[NEG_ONE]] : vector<[4]xi32>
+// MLIR: llvm.return %[[INVERT]] : vector<[4]xi32>
+
+// LLVM: define <vscale x 4 x i32> @scalable_vector(<vscale x 4 x i32> 
%[[ARG:.*]])
+// LLVM: %[[INVERT:.*]] = xor <vscale x 4 x i32> %[[ARG]], splat (i32 -1)
+// LLVM: ret <vscale x 4 x i32> %[[INVERT]]
 }

diff  --git a/clang/test/CIR/Transforms/vector-splat.cir 
b/clang/test/CIR/Transforms/vector-splat.cir
index 9b2b39d7f862e3..d444e2143d95dc 100644
--- a/clang/test/CIR/Transforms/vector-splat.cir
+++ b/clang/test/CIR/Transforms/vector-splat.cir
@@ -13,4 +13,15 @@ module  {
   // CHECK-NEXT: %0 = cir.const #cir.const_vector<[#cir.int<3> : !s32i, 
#cir.int<3> : !s32i,
   // CHECK-SAME: #cir.int<3> : !s32i, #cir.int<3> : !s32i]> : !cir.vector<4 x 
!s32i>
   // CHECK-NEXT: cir.return %0 : !cir.vector<4 x !s32i>
+
+  cir.func @do_not_fold_scalable_splat() -> !cir.vector<[4] x !s32i> {
+    %v = cir.const #cir.int<3> : !s32i
+    %vec = cir.vec.splat %v : !s32i, !cir.vector<[4] x !s32i>
+    cir.return %vec : !cir.vector<[4] x !s32i>
+  }
+
+  // CHECK-LABEL: cir.func @do_not_fold_scalable_splat
+  // CHECK: %[[VALUE:.*]] = cir.const #cir.int<3> : !s32i
+  // CHECK-NEXT: %[[VEC:.*]] = cir.vec.splat %[[VALUE]] : !s32i, 
!cir.vector<[4] x !s32i>
+  // CHECK-NEXT: cir.return %[[VEC]] : !cir.vector<[4] x !s32i>
 }

diff  --git a/clang/unittests/CIR/PointerLikeTest.cpp 
b/clang/unittests/CIR/PointerLikeTest.cpp
index 13569b3931d69f..01707738a4c00a 100644
--- a/clang/unittests/CIR/PointerLikeTest.cpp
+++ b/clang/unittests/CIR/PointerLikeTest.cpp
@@ -341,7 +341,7 @@ TEST_F(CIROpenACCPointerLikeTest, testPointerToFunction) {
 
 TEST_F(CIROpenACCPointerLikeTest, testPointerToVector) {
   mlir::Type i32Ty = cir::IntType::get(&context, 32, true);
-  mlir::Type vecTy = cir::VectorType::get(i32Ty, 4);
+  mlir::Type vecTy = cir::VectorType::getFixed(i32Ty, 4);
   testNonScalarType(vecTy);
 }
 

diff  --git a/clang/unittests/CIR/VectorTypeABIAlignTest.cpp 
b/clang/unittests/CIR/VectorTypeABIAlignTest.cpp
index cb36d2333494b1..798ea2153ad62d 100644
--- a/clang/unittests/CIR/VectorTypeABIAlignTest.cpp
+++ b/clang/unittests/CIR/VectorTypeABIAlignTest.cpp
@@ -28,7 +28,7 @@ class VectorTypeABIAlignTest : public ::testing::Test {
   MLIRContext context;
 
   uint64_t abiAlign(mlir::Type elementType, uint64_t size) {
-    cir::VectorType ty = cir::VectorType::get(elementType, size);
+    cir::VectorType ty = cir::VectorType::getFixed(elementType, size);
     OpBuilder builder(&context);
     auto module = ModuleOp::create(builder.getUnknownLoc());
     mlir::DataLayout dl(module);

diff  --git a/llvm/include/llvm/Support/TypeSize.h 
b/llvm/include/llvm/Support/TypeSize.h
index 5a34c7daeb02f5..b9db5d5205dcd0 100644
--- a/llvm/include/llvm/Support/TypeSize.h
+++ b/llvm/include/llvm/Support/TypeSize.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_SUPPORT_TYPESIZE_H
 #define LLVM_SUPPORT_TYPESIZE_H
 
+#include "llvm/ADT/Hashing.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MathExtras.h"
@@ -322,6 +323,10 @@ class ElementCount
   }
 };
 
+inline hash_code hash_value(const ElementCount &EC) {
+  return hash_combine(EC.getKnownMinValue(), EC.isScalable());
+}
+
 // Stores the size of a type. If the type is of fixed size, it will represent
 // the exact size. If the type is a scalable vector, it will represent the 
known
 // minimum size.


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to