[clang] 1a12b03 - [CIR] Use `llvm::ElementCount` to hold `cir::VectorType` size (#231906)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 22 02:18:15 PDT 2026
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 at +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.
More information about the cfe-commits
mailing list