[clang] [llvm] [LLVMABI] Add support for SVE types in the LLVM ABI library (PR #221375)
Paul Walker via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 10 05:11:09 PDT 2026
================
@@ -209,28 +211,100 @@ class ArrayType : public Type {
static bool classof(const Type *T) { return T->getKind() == TypeKind::Array; }
};
+/// Distinguishes the vector flavors that ABIs have to treat differently.
+/// Scalability is not part of the kind. It is tracked by the vector's
+/// ElementCount, because some flavors have both a scalable and a
+/// fixed-length spelling.
+enum class VectorKind {
+ /// A plain vector, such as a Neon vector or a GCC vector_size vector.
+ Generic,
+
+ /// An AArch64 SVE data vector, such as svint32_t. Data vectors are
+ /// passed in Z registers. Tuples of these vectors use TupleType.
+ SVEData,
+
+ /// An AArch64 SVE predicate vector, such as svbool_t. These are passed
+ /// in P registers. Sizeless predicates have one-bit elements; the
+ /// fixed-length arm_sve_vector_bits form keeps unsigned char (i8)
+ /// elements, matching the Clang AST. Both use this kind. Tuples of
+ /// these vectors use TupleType.
+ SVEPredicate,
+
+ /// The AArch64 __SVCount_t type. It is opaque rather than a real vector,
+ /// but it occupies a predicate register, so it is given the same shape as
+ /// svbool_t.
+ SVECount,
+};
+
class VectorType : public Type {
private:
const Type *ElementType;
ElementCount NumElements;
+ VectorKind VecKind;
+
+ static TypeSize computeSizeInBits(const Type *ElementType,
+ ElementCount NumElements) {
+ return TypeSize(ElementType->getSizeInBits().getFixedValue() *
+ NumElements.getKnownMinValue(),
+ NumElements.isScalable());
+ }
public:
- VectorType(const Type *ElementType, ElementCount NumElements, Align ABIAlign)
- : Type(TypeKind::Vector,
- TypeSize(ElementType->getSizeInBits().getFixedValue() *
- NumElements.getKnownMinValue(),
- NumElements.isScalable()),
+ VectorType(const Type *ElementType, ElementCount NumElements, Align ABIAlign,
+ VectorKind VecKind = VectorKind::Generic)
+ : Type(TypeKind::Vector, computeSizeInBits(ElementType, NumElements),
ABIAlign),
- ElementType(ElementType), NumElements(NumElements) {}
+ ElementType(ElementType), NumElements(NumElements), VecKind(VecKind) {}
const Type *getElementType() const { return ElementType; }
ElementCount getNumElements() const { return NumElements; }
+ VectorKind getVectorKind() const { return VecKind; }
+
+ bool isScalable() const { return NumElements.isScalable(); }
+
+ bool isSVEData() const { return VecKind == VectorKind::SVEData; }
+ bool isSVEPredicate() const { return VecKind == VectorKind::SVEPredicate; }
+ bool isSVECount() const { return VecKind == VectorKind::SVECount; }
+
+ /// Returns true for any of the AArch64 SVE flavors.
+ bool isSVEType() const { return VecKind != VectorKind::Generic; }
+
static bool classof(const Type *T) {
return T->getKind() == TypeKind::Vector;
}
};
+/// A homogeneous tuple of 2, 3, or 4 identical vectors, such as the
+/// AArch64 SVE types svint32x3_t and svboolx2_t.
+///
+/// The contained vector describes one register-shaped member. Size and
+/// alignment of the tuple cover the whole group: size is NumVectors times
+/// the vector size, and alignment matches the contained vector.
+class TupleType : public Type {
+private:
+ const VectorType *Vec;
+ unsigned NumVectors;
+
+ static TypeSize computeSizeInBits(const VectorType *Vec,
+ unsigned NumVectors) {
+ TypeSize VecSize = Vec->getSizeInBits();
+ return TypeSize(VecSize.getKnownMinValue() * NumVectors,
+ VecSize.isScalable());
----------------
paulwalker-arm wrote:
```suggestion
return Vec->getSizeInBits() * NumVectors;
```
Although given the simplicity perhaps the computeSizeInBits helper is unnecessary?
https://github.com/llvm/llvm-project/pull/221375
More information about the cfe-commits
mailing list