https://github.com/kito-cheng updated https://github.com/llvm/llvm-project/pull/237845
>From 4bcd25547374f73a1b042f2454f941435f3f5feb Mon Sep 17 00:00:00 2001 From: Kito Cheng <[email protected]> Date: Tue, 13 Oct 2026 12:38:30 +0800 Subject: [PATCH 1/3] [Clang][RISCV] Record the LMUL in RVV fixed-length data vector kinds A riscv_rvv_vector_bits typedef of a data type keeps only the element type and count, and later stages re-derive the LMUL from VLEN. That breaks once typedefs may be shorter than VLEN * LMUL. Split VectorKind::RVVFixedLengthData into RVVFixedLengthData_MF8 to _M8 and read the LMUL from the kind. VecKind grows to 5 bits. This patch prepares to let a riscv_rvv_vector_bits typedef be shorter than VLEN * LMUL. It only records the LMUL and does not change any behavior. Assisted-by: Claude --- clang/include/clang/AST/TypeBase.h | 95 ++++++++++++++++++- clang/lib/AST/ASTContext.cpp | 8 +- clang/lib/AST/ItaniumMangle.cpp | 32 +++---- clang/lib/AST/JSONNodeDumper.cpp | 14 ++- clang/lib/AST/TextNodeDumper.cpp | 11 ++- clang/lib/AST/TypePrinter.cpp | 16 +++- clang/lib/CodeGen/Targets/RISCV.cpp | 79 +++++++++++---- clang/lib/Sema/SemaExpr.cpp | 4 +- clang/lib/Sema/SemaRISCV.cpp | 2 +- clang/lib/Sema/SemaType.cpp | 10 +- ...t-dump-riscv-rvv-fixed-length-data-types.c | 40 ++++++++ 11 files changed, 258 insertions(+), 53 deletions(-) create mode 100644 clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index 6373794bb69f54..09b381b512d0d4 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -2133,7 +2133,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. LLVM_PREFERRED_TYPE(VectorKind) - unsigned VecKind : 4; + unsigned VecKind : 5; /// The number of elements in the vector. uint32_t NumElements; }; @@ -4255,7 +4255,13 @@ enum class VectorKind { SveFixedLengthPredicate, /// is RISC-V RVV fixed-length data vector - RVVFixedLengthData, + RVVFixedLengthData_MF8, + RVVFixedLengthData_MF4, + RVVFixedLengthData_MF2, + RVVFixedLengthData_M1, + RVVFixedLengthData_M2, + RVVFixedLengthData_M4, + RVVFixedLengthData_M8, /// is RISC-V RVV fixed-length mask vector RVVFixedLengthMask, @@ -4265,6 +4271,91 @@ enum class VectorKind { RVVFixedLengthMask_4 }; +/// True if \p VK is one of the RVV fixed-length data vector kinds, i.e. a +/// riscv_rvv_vector_bits typedef of a data (non-mask) RVV type. +inline bool isRVVFixedLengthDataVectorKind(VectorKind VK) { + switch (VK) { + case VectorKind::RVVFixedLengthData_MF8: + case VectorKind::RVVFixedLengthData_MF4: + case VectorKind::RVVFixedLengthData_MF2: + case VectorKind::RVVFixedLengthData_M1: + case VectorKind::RVVFixedLengthData_M2: + case VectorKind::RVVFixedLengthData_M4: + case VectorKind::RVVFixedLengthData_M8: + return true; + default: + return false; + } +} + +/// Return log2 of the LMUL recorded in an RVV fixed-length data vector kind: +/// MF8 -> -3, MF4 -> -2, MF2 -> -1, M1 -> 0, M2 -> 1, M4 -> 2, M8 -> 3. +inline int getRVVFixedLengthDataLMulLog2(VectorKind VK) { + switch (VK) { + case VectorKind::RVVFixedLengthData_MF8: + return -3; + case VectorKind::RVVFixedLengthData_MF4: + return -2; + case VectorKind::RVVFixedLengthData_MF2: + return -1; + case VectorKind::RVVFixedLengthData_M1: + return 0; + case VectorKind::RVVFixedLengthData_M2: + return 1; + case VectorKind::RVVFixedLengthData_M4: + return 2; + case VectorKind::RVVFixedLengthData_M8: + return 3; + default: + llvm_unreachable("not an RVV fixed-length data vector kind"); + } +} + +/// Return the LMUL of an RVV fixed-length data vector kind as a string: +/// "mf8" .. "m8" if \p MF is true, "1/8" .. "8" otherwise. +inline StringRef getRVVFixedLengthDataLMulString(VectorKind VK, bool MF) { + switch (VK) { + case VectorKind::RVVFixedLengthData_MF8: + return MF ? "mf8" : "1/8"; + case VectorKind::RVVFixedLengthData_MF4: + return MF ? "mf4" : "1/4"; + case VectorKind::RVVFixedLengthData_MF2: + return MF ? "mf2" : "1/2"; + case VectorKind::RVVFixedLengthData_M1: + return MF ? "m1" : "1"; + case VectorKind::RVVFixedLengthData_M2: + return MF ? "m2" : "2"; + case VectorKind::RVVFixedLengthData_M4: + return MF ? "m4" : "4"; + case VectorKind::RVVFixedLengthData_M8: + return MF ? "m8" : "8"; + default: + llvm_unreachable("not an RVV fixed-length data vector kind"); + } +} + +/// Inverse of getRVVFixedLengthDataLMulLog2(). +inline VectorKind getRVVFixedLengthDataVectorKind(int LMulLog2) { + switch (LMulLog2) { + case -3: + return VectorKind::RVVFixedLengthData_MF8; + case -2: + return VectorKind::RVVFixedLengthData_MF4; + case -1: + return VectorKind::RVVFixedLengthData_MF2; + case 0: + return VectorKind::RVVFixedLengthData_M1; + case 1: + return VectorKind::RVVFixedLengthData_M2; + case 2: + return VectorKind::RVVFixedLengthData_M4; + case 3: + return VectorKind::RVVFixedLengthData_M8; + default: + llvm_unreachable("LMUL out of range for an RVV type"); + } +} + /// Represents a GCC generic vector type. This type is created using /// __attribute__((vector_size(n)), where "n" specifies the vector size in /// bytes; or from an Altivec __vector or vector declaration. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 01d71388cbc0e3..6afc80a2b908bb 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2155,7 +2155,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { else if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) // Adjust the alignment for fixed-length SVE predicates. Align = 16; - else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || + else if (isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || VT->getVectorKind() == VectorKind::RVVFixedLengthMask || VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || @@ -10771,8 +10771,8 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, First->getVectorKind() != VectorKind::SveFixedLengthPredicate && Second->getVectorKind() != VectorKind::SveFixedLengthData && Second->getVectorKind() != VectorKind::SveFixedLengthPredicate && - First->getVectorKind() != VectorKind::RVVFixedLengthData && - Second->getVectorKind() != VectorKind::RVVFixedLengthData && + !isRVVFixedLengthDataVectorKind(First->getVectorKind()) && + !isRVVFixedLengthDataVectorKind(Second->getVectorKind()) && First->getVectorKind() != VectorKind::RVVFixedLengthMask && Second->getVectorKind() != VectorKind::RVVFixedLengthMask && First->getVectorKind() != VectorKind::RVVFixedLengthMask_1 && @@ -10884,7 +10884,7 @@ bool ASTContext::areCompatibleRVVTypes(QualType FirstType, Info.ElementType == BoolTy && getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 2); } - if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || + if (isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || VT->getVectorKind() == VectorKind::Generic) return FirstType->isRVVVLSBuiltinType() && getTypeSize(SecondType) == getRVVTypeSize(*this, BT) && diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 02f27cec53f699..8fd9059abcdf3d 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4316,7 +4316,7 @@ void CXXNameMangler::mangleAArch64FixedSveVectorType( } void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { - assert((T->getVectorKind() == VectorKind::RVVFixedLengthData || + assert((isRVVFixedLengthDataVectorKind(T->getVectorKind()) || T->getVectorKind() == VectorKind::RVVFixedLengthMask || T->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || T->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || @@ -4335,7 +4335,7 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { TypeNameOS << "int8"; break; case BuiltinType::UChar: - if (T->getVectorKind() == VectorKind::RVVFixedLengthData) + if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) TypeNameOS << "uint8"; else TypeNameOS << "bool"; @@ -4392,19 +4392,19 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { break; } - // Apend the LMUL suffix. - auto VScale = getASTContext().getTargetInfo().getVScaleRange( - getASTContext().getLangOpts(), - TargetInfo::ArmStreamingKind::NotStreaming); - unsigned VLen = VScale->first * llvm::RISCV::RVVBitsPerBlock; - - if (T->getVectorKind() == VectorKind::RVVFixedLengthData) { - TypeNameOS << 'm'; - if (VecSizeInBits >= VLen) - TypeNameOS << (VecSizeInBits / VLen); - else - TypeNameOS << 'f' << (VLen / VecSizeInBits); + // Append the LMUL suffix. For data types the LMUL is recorded in the vector + // kind, so the mangled name names the type the typedef was written against + // even when the typedef is shorter than VLEN * LMUL, and does not depend on + // VLEN at all. Mask types are still tied to a fixed VLEN, so their ratio is + // derived from it. + if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) { + TypeNameOS << getRVVFixedLengthDataLMulString(T->getVectorKind(), + /*MF=*/true); } else { + auto VScale = getASTContext().getTargetInfo().getVScaleRange( + getASTContext().getLangOpts(), + TargetInfo::ArmStreamingKind::NotStreaming); + unsigned VLen = VScale->first * llvm::RISCV::RVVBitsPerBlock; TypeNameOS << (VLen / VecSizeInBits); } TypeNameOS << "_t"; @@ -4445,7 +4445,7 @@ void CXXNameMangler::mangleType(const VectorType *T) { T->getVectorKind() == VectorKind::SveFixedLengthPredicate) { mangleAArch64FixedSveVectorType(T); return; - } else if (T->getVectorKind() == VectorKind::RVVFixedLengthData || + } else if (isRVVFixedLengthDataVectorKind(T->getVectorKind()) || T->getVectorKind() == VectorKind::RVVFixedLengthMask || T->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || T->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || @@ -4478,7 +4478,7 @@ void CXXNameMangler::mangleType(const DependentVectorType *T) { T->getVectorKind() == VectorKind::SveFixedLengthPredicate) { mangleAArch64FixedSveVectorType(T); return; - } else if (T->getVectorKind() == VectorKind::RVVFixedLengthData) { + } else if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) { mangleRISCVFixedRVVVectorType(T); return; } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 75abc4777f717f..2555c3658df02f 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -750,8 +750,18 @@ void JSONNodeDumper::VisitVectorType(const VectorType *VT) { case VectorKind::SveFixedLengthPredicate: JOS.attribute("vectorKind", "fixed-length sve predicate vector"); break; - case VectorKind::RVVFixedLengthData: - JOS.attribute("vectorKind", "fixed-length rvv data vector"); + case VectorKind::RVVFixedLengthData_MF8: + case VectorKind::RVVFixedLengthData_MF4: + case VectorKind::RVVFixedLengthData_MF2: + case VectorKind::RVVFixedLengthData_M1: + case VectorKind::RVVFixedLengthData_M2: + case VectorKind::RVVFixedLengthData_M4: + case VectorKind::RVVFixedLengthData_M8: + JOS.attribute("vectorKind", + "fixed-length rvv data vector lmul " + + getRVVFixedLengthDataLMulString(VT->getVectorKind(), + /*MF=*/false) + .str()); break; case VectorKind::RVVFixedLengthMask: case VectorKind::RVVFixedLengthMask_1: diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 497fca228e428d..f1b216d970c731 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -2168,8 +2168,15 @@ void TextNodeDumper::VisitVectorType(const VectorType *T) { case VectorKind::SveFixedLengthPredicate: OS << " fixed-length sve predicate vector"; break; - case VectorKind::RVVFixedLengthData: - OS << " fixed-length rvv data vector"; + case VectorKind::RVVFixedLengthData_MF8: + case VectorKind::RVVFixedLengthData_MF4: + case VectorKind::RVVFixedLengthData_MF2: + case VectorKind::RVVFixedLengthData_M1: + case VectorKind::RVVFixedLengthData_M2: + case VectorKind::RVVFixedLengthData_M4: + case VectorKind::RVVFixedLengthData_M8: + OS << " fixed-length rvv data vector lmul " + << getRVVFixedLengthDataLMulString(T->getVectorKind(), /*MF=*/false); break; case VectorKind::RVVFixedLengthMask: case VectorKind::RVVFixedLengthMask_1: diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 13929f6fe08005..12cce9ccc32a55 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -718,7 +718,13 @@ void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) { OS << ") * 8))) "; printBefore(T->getElementType(), OS); break; - case VectorKind::RVVFixedLengthData: + case VectorKind::RVVFixedLengthData_MF8: + case VectorKind::RVVFixedLengthData_MF4: + case VectorKind::RVVFixedLengthData_MF2: + case VectorKind::RVVFixedLengthData_M1: + case VectorKind::RVVFixedLengthData_M2: + case VectorKind::RVVFixedLengthData_M4: + case VectorKind::RVVFixedLengthData_M8: case VectorKind::RVVFixedLengthMask: case VectorKind::RVVFixedLengthMask_1: case VectorKind::RVVFixedLengthMask_2: @@ -813,7 +819,13 @@ void TypePrinter::printDependentVectorBefore( OS << "))) "; printBefore(T->getElementType(), OS); break; - case VectorKind::RVVFixedLengthData: + case VectorKind::RVVFixedLengthData_MF8: + case VectorKind::RVVFixedLengthData_MF4: + case VectorKind::RVVFixedLengthData_MF2: + case VectorKind::RVVFixedLengthData_M1: + case VectorKind::RVVFixedLengthData_M2: + case VectorKind::RVVFixedLengthData_M4: + case VectorKind::RVVFixedLengthData_M8: case VectorKind::RVVFixedLengthMask: case VectorKind::RVVFixedLengthMask_1: case VectorKind::RVVFixedLengthMask_2: diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index 4bac5711a2dd66..c84a4f00f4bc7f 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -40,6 +40,8 @@ class RISCVABIInfo : public DefaultABIInfo { llvm::Type *detectHomogeneousRVVFixedLengthStruct(QualType Ty) const; + unsigned getRVVFixedLengthMinElts(const VectorType *VT) const; + public: RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen, bool EABI) @@ -410,6 +412,35 @@ ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct( return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType); } +/// Minimum element count of the scalable vector an RVV fixed-length *data* +/// vector is coerced to, i.e. the N in <vscale x N x T>. The LMUL comes from +/// the vector kind - the type the typedef was written against - rather than +/// from VLEN and the element count. +static unsigned getRVVFixedLengthDataMinElts(VectorKind VK, + unsigned EltSizeInBits) { + // The underlying scalable type holds LMUL * RVVBitsPerBlock bits at + // vscale=1. + int LMulLog2 = getRVVFixedLengthDataLMulLog2(VK); + unsigned SizeAtVScale1 = LMulLog2 >= 0 + ? llvm::RISCV::RVVBitsPerBlock << LMulLog2 + : llvm::RISCV::RVVBitsPerBlock >> -LMulLog2; + assert(SizeAtVScale1 >= EltSizeInBits && "LMUL too small for element type"); + return SizeAtVScale1 / EltSizeInBits; +} + +/// Minimum element count of the scalable vector \p VT is coerced to, in units +/// of \p VT's own Clang element type. Masks are modelled as i8 vectors and are +/// exactly VLEN * LMUL wide, so their LMUL is recovered from VLEN. +unsigned RISCVABIInfo::getRVVFixedLengthMinElts(const VectorType *VT) const { + unsigned EltSizeInBits = getContext().getTypeSize(VT->getElementType()); + if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) + return getRVVFixedLengthDataMinElts(VT->getVectorKind(), EltSizeInBits); + + auto VScale = getContext().getTargetInfo().getVScaleRange( + getContext().getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming); + return llvm::divideCeil(VT->getNumElements(), VScale->first); +} + llvm::Type *RISCVABIInfo::detectVLSCCEligibleStruct(QualType Ty, unsigned ABIVLen) const { // No riscv_vls_cc attribute. @@ -556,8 +587,9 @@ RISCVABIInfo::detectHomogeneousRVVFixedLengthStruct(QualType Ty) const { return nullptr; auto IsFixedLengthRVVVector = [](const VectorType *VT) { + if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) + return true; switch (VT->getVectorKind()) { - case VectorKind::RVVFixedLengthData: case VectorKind::RVVFixedLengthMask: case VectorKind::RVVFixedLengthMask_1: case VectorKind::RVVFixedLengthMask_2: @@ -607,24 +639,21 @@ RISCVABIInfo::detectHomogeneousRVVFixedLengthStruct(QualType Ty) const { const auto *VT = CommonTy->castAs<VectorType>(); llvm::Type *EltType = CGT.ConvertType(VT->getElementType()); - auto VScale = getContext().getTargetInfo().getVScaleRange( - getContext().getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming); - - // Ensure total register usage does not exceed 8. - if (Count > 1 && - Count * llvm::divideCeil((uint64_t)VT->getNumElements() * - EltType->getScalarSizeInBits(), - VScale->first * llvm::RISCV::RVVBitsPerBlock) > - 8) + unsigned MinElts = getRVVFixedLengthMinElts(VT); + + // Ensure total register usage does not exceed 8. Each vector occupies + // max(1, LMUL) registers. + uint64_t RegsPerVec = + llvm::divideCeil((uint64_t)MinElts * EltType->getScalarSizeInBits(), + llvm::RISCV::RVVBitsPerBlock); + if (Count > 1 && Count * RegsPerVec > 8) return nullptr; - unsigned MinElts = llvm::divideCeil(VT->getNumElements(), VScale->first); if (Count == 1) return llvm::ScalableVectorType::get(EltType, MinElts); - unsigned I8EltCount = llvm::divideCeil((uint64_t)VT->getNumElements() * - EltType->getScalarSizeInBits(), - VScale->first * 8); + unsigned I8EltCount = + llvm::divideCeil((uint64_t)MinElts * EltType->getScalarSizeInBits(), 8); auto *I8Vec = llvm::ScalableVectorType::get( llvm::Type::getInt8Ty(getVMContext()), I8EltCount); return llvm::TargetExtType::get(getVMContext(), "riscv.vector.tuple", I8Vec, @@ -675,7 +704,7 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const { break; default: assert((VT->getVectorKind() == VectorKind::Generic || - VT->getVectorKind() == VectorKind::RVVFixedLengthData) && + isRVVFixedLengthDataVectorKind(VT->getVectorKind())) && "Unexpected vector kind"); EltType = CGT.ConvertType(VT->getElementType()); } @@ -683,11 +712,19 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const { llvm::ScalableVectorType *ResType; if (ABIVLen == 0) { - // The MinNumElts is simplified from equation: - // NumElts / VScale = - // (EltSize * NumElts / (VScale * RVVBitsPerBlock)) - // * (RVVBitsPerBlock / EltSize) - ResType = llvm::ScalableVectorType::get(EltType, NumElts / VScale->first); + unsigned MinScalableElts; + if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) { + // Use the LMUL of the type the typedef was written against. + MinScalableElts = getRVVFixedLengthDataMinElts( + VT->getVectorKind(), EltType->getScalarSizeInBits()); + } else { + // The MinNumElts is simplified from equation: + // NumElts / VScale = + // (EltSize * NumElts / (VScale * RVVBitsPerBlock)) + // * (RVVBitsPerBlock / EltSize) + MinScalableElts = NumElts / VScale->first; + } + ResType = llvm::ScalableVectorType::get(EltType, MinScalableElts); } else { // Check registers needed <= 8. if ((EltType->getScalarSizeInBits() * NumElts / ABIVLen) > 8) @@ -824,7 +861,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/419 if (const VectorType *VT = Ty->getAs<VectorType>(); VT && !VT->getElementType()->isBitIntType()) { - if (VT->getVectorKind() == VectorKind::RVVFixedLengthData || + if (isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || VT->getVectorKind() == VectorKind::RVVFixedLengthMask || VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 00dd8acf1f68dd..9a11c859997eb6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11061,7 +11061,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, if (VecType->getVectorKind() == VectorKind::SveFixedLengthData || VecType->getVectorKind() == VectorKind::SveFixedLengthPredicate) return true; - if (VecType->getVectorKind() == VectorKind::RVVFixedLengthData || + if (isRVVFixedLengthDataVectorKind(VecType->getVectorKind()) || VecType->getVectorKind() == VectorKind::RVVFixedLengthMask || VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || @@ -11096,7 +11096,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, SecondVecType->getVectorKind() == VectorKind::SveFixedLengthPredicate) return true; - if (SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthData || + if (isRVVFixedLengthDataVectorKind(SecondVecType->getVectorKind()) || SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask || SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index a1ba3b3934daa6..907123cd6379c0 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -1634,7 +1634,7 @@ bool SemaRISCV::isValidRVVBitcast(QualType srcTy, QualType destTy) { return false; const auto *VecTy = SecondType->getAs<VectorType>(); - return VecTy && VecTy->getVectorKind() == VectorKind::RVVFixedLengthData; + return VecTy && isRVVFixedLengthDataVectorKind(VecTy->getVectorKind()); }; return ValidScalableConversion(srcTy, destTy) || diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f55c78b138d9ad..9c299b9e55da8d 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -46,6 +46,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include <bitset> #include <optional> @@ -8870,7 +8871,7 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType, S.Context.getBuiltinVectorTypeInfo(CurType->castAs<BuiltinType>()); unsigned MinElts = Info.EC.getKnownMinValue(); - VectorKind VecKind = VectorKind::RVVFixedLengthData; + VectorKind VecKind = VectorKind::RVVFixedLengthMask; unsigned ExpectedSize = VScale->first * MinElts; QualType EltType = CurType->getRVVEltType(S.Context); unsigned EltSize = S.Context.getTypeSize(EltType); @@ -8895,6 +8896,13 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType, } else { ExpectedSize *= EltSize; NumElts = VecSize / EltSize; + + // Record the LMUL of the sizeless type in the vector kind, so that later + // stages do not have to re-derive it from VLEN and the element count. + // LMUL = MinElts * EltSize / RVVBitsPerBlock + VecKind = getRVVFixedLengthDataVectorKind( + int(llvm::Log2_32(MinElts * EltSize)) - + int(llvm::Log2_32(llvm::RISCV::RVVBitsPerBlock))); } // The attribute vector size must match -mrvv-vector-bits. diff --git a/clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c b/clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c new file mode 100644 index 00000000000000..4ba0ea48ba4240 --- /dev/null +++ b/clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c @@ -0,0 +1,40 @@ +// Verify that a riscv_rvv_vector_bits typedef of a data type records the LMUL +// of the sizeless type it was written against. + +// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +zve64d \ +// RUN: -mvscale-min=2 -mvscale-max=2 -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +zve64d \ +// RUN: -mvscale-min=2 -mvscale-max=2 -ast-dump=json %s \ +// RUN: | FileCheck %s --check-prefix=JSON + +// VLEN=128. +typedef __rvv_int8mf8_t fixed_i8mf8 __attribute__((riscv_rvv_vector_bits(16))); +typedef __rvv_int16mf4_t fixed_i16mf4 __attribute__((riscv_rvv_vector_bits(32))); +typedef __rvv_int32mf2_t fixed_i32mf2 __attribute__((riscv_rvv_vector_bits(64))); +typedef __rvv_int32m1_t fixed_i32m1 __attribute__((riscv_rvv_vector_bits(128))); +typedef __rvv_int32m2_t fixed_i32m2 __attribute__((riscv_rvv_vector_bits(256))); +typedef __rvv_int64m4_t fixed_i64m4 __attribute__((riscv_rvv_vector_bits(512))); +typedef __rvv_int8m8_t fixed_i8m8 __attribute__((riscv_rvv_vector_bits(1024))); + +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i8mf8 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/8 2 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i16mf4 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/4 2 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i32mf2 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/2 2 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i32m1 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1 4 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i32m2 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 2 8 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i64m4 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 4 8 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_i8m8 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 8 128 + +// JSON: "vectorKind": "fixed-length rvv data vector lmul 1/8" +// JSON: "vectorKind": "fixed-length rvv data vector lmul 1/4" +// JSON: "vectorKind": "fixed-length rvv data vector lmul 1/2" +// JSON: "vectorKind": "fixed-length rvv data vector lmul 1" +// JSON: "vectorKind": "fixed-length rvv data vector lmul 2" +// JSON: "vectorKind": "fixed-length rvv data vector lmul 4" +// JSON: "vectorKind": "fixed-length rvv data vector lmul 8" >From b403710c1b536f5736a8a597941b83cb88196a3b Mon Sep 17 00:00:00 2001 From: Kito Cheng <[email protected]> Date: Tue, 3 Nov 2026 09:23:59 +0800 Subject: [PATCH 2/3] fixup! [Clang][RISCV] Record the LMUL in RVV fixed-length data vector kinds Record the ratio in RVV fixed-length mask vector kinds too. Replace RVVFixedLengthMask{,_1,_2,_4} with RVVFixedLengthMaskRatio<R> and RVVFixedLengthMaskRatio<R>_{1,2,4}, and read R from the kind instead of re-deriving it from VLEN. VecKind grows to 6 bits. Assisted-by: Claude --- clang/include/clang/AST/TypeBase.h | 217 +++++++++++++++++- clang/lib/AST/ASTContext.cpp | 44 +--- clang/lib/AST/ItaniumMangle.cpp | 45 +--- clang/lib/AST/JSONNodeDumper.cpp | 33 ++- clang/lib/AST/TextNodeDumper.cpp | 25 +- clang/lib/AST/TypePrinter.cpp | 73 ++---- clang/lib/CodeGen/Targets/RISCV.cpp | 61 ++--- clang/lib/Sema/SemaExpr.cpp | 13 +- clang/lib/Sema/SemaType.cpp | 26 +-- ...ump-riscv-rvv-fixed-length-vector-kinds.c} | 20 +- 10 files changed, 335 insertions(+), 222 deletions(-) rename clang/test/AST/{ast-dump-riscv-rvv-fixed-length-data-types.c => ast-dump-riscv-rvv-fixed-length-vector-kinds.c} (64%) diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index 09b381b512d0d4..4f4f4b8a22d63c 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -2133,7 +2133,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. LLVM_PREFERRED_TYPE(VectorKind) - unsigned VecKind : 5; + unsigned VecKind : 6; /// The number of elements in the vector. uint32_t NumElements; }; @@ -4263,12 +4263,36 @@ enum class VectorKind { RVVFixedLengthData_M4, RVVFixedLengthData_M8, - /// is RISC-V RVV fixed-length mask vector - RVVFixedLengthMask, - - RVVFixedLengthMask_1, - RVVFixedLengthMask_2, - RVVFixedLengthMask_4 + /// is RISC-V RVV fixed-length mask vector of vbool<R>_t; the _<L> kinds + /// have only L lanes in a single byte + RVVFixedLengthMaskRatio1, + RVVFixedLengthMaskRatio1_1, + RVVFixedLengthMaskRatio1_2, + RVVFixedLengthMaskRatio1_4, + RVVFixedLengthMaskRatio2, + RVVFixedLengthMaskRatio2_1, + RVVFixedLengthMaskRatio2_2, + RVVFixedLengthMaskRatio2_4, + RVVFixedLengthMaskRatio4, + RVVFixedLengthMaskRatio4_1, + RVVFixedLengthMaskRatio4_2, + RVVFixedLengthMaskRatio4_4, + RVVFixedLengthMaskRatio8, + RVVFixedLengthMaskRatio8_1, + RVVFixedLengthMaskRatio8_2, + RVVFixedLengthMaskRatio8_4, + RVVFixedLengthMaskRatio16, + RVVFixedLengthMaskRatio16_1, + RVVFixedLengthMaskRatio16_2, + RVVFixedLengthMaskRatio16_4, + RVVFixedLengthMaskRatio32, + RVVFixedLengthMaskRatio32_1, + RVVFixedLengthMaskRatio32_2, + RVVFixedLengthMaskRatio32_4, + RVVFixedLengthMaskRatio64, + RVVFixedLengthMaskRatio64_1, + RVVFixedLengthMaskRatio64_2, + RVVFixedLengthMaskRatio64_4 }; /// True if \p VK is one of the RVV fixed-length data vector kinds, i.e. a @@ -4356,6 +4380,178 @@ inline VectorKind getRVVFixedLengthDataVectorKind(int LMulLog2) { } } +/// True if \p VK is one of the RVV fixed-length mask vector kinds, i.e. a +/// riscv_rvv_vector_bits typedef of a vbool<R>_t type. +inline bool isRVVFixedLengthMaskVectorKind(VectorKind VK) { + switch (VK) { + case VectorKind::RVVFixedLengthMaskRatio1: + case VectorKind::RVVFixedLengthMaskRatio1_1: + case VectorKind::RVVFixedLengthMaskRatio1_2: + case VectorKind::RVVFixedLengthMaskRatio1_4: + case VectorKind::RVVFixedLengthMaskRatio2: + case VectorKind::RVVFixedLengthMaskRatio2_1: + case VectorKind::RVVFixedLengthMaskRatio2_2: + case VectorKind::RVVFixedLengthMaskRatio2_4: + case VectorKind::RVVFixedLengthMaskRatio4: + case VectorKind::RVVFixedLengthMaskRatio4_1: + case VectorKind::RVVFixedLengthMaskRatio4_2: + case VectorKind::RVVFixedLengthMaskRatio4_4: + case VectorKind::RVVFixedLengthMaskRatio8: + case VectorKind::RVVFixedLengthMaskRatio8_1: + case VectorKind::RVVFixedLengthMaskRatio8_2: + case VectorKind::RVVFixedLengthMaskRatio8_4: + case VectorKind::RVVFixedLengthMaskRatio16: + case VectorKind::RVVFixedLengthMaskRatio16_1: + case VectorKind::RVVFixedLengthMaskRatio16_2: + case VectorKind::RVVFixedLengthMaskRatio16_4: + case VectorKind::RVVFixedLengthMaskRatio32: + case VectorKind::RVVFixedLengthMaskRatio32_1: + case VectorKind::RVVFixedLengthMaskRatio32_2: + case VectorKind::RVVFixedLengthMaskRatio32_4: + case VectorKind::RVVFixedLengthMaskRatio64: + case VectorKind::RVVFixedLengthMaskRatio64_1: + case VectorKind::RVVFixedLengthMaskRatio64_2: + case VectorKind::RVVFixedLengthMaskRatio64_4: + return true; + default: + return false; + } +} + +/// Return log2 of the R of the vbool<R>_t type recorded in an RVV fixed-length +/// mask vector kind: Ratio1 -> 0, Ratio2 -> 1, ..., Ratio64 -> 6. +inline unsigned getRVVFixedLengthMaskRatioLog2(VectorKind VK) { + switch (VK) { + case VectorKind::RVVFixedLengthMaskRatio1: + case VectorKind::RVVFixedLengthMaskRatio1_1: + case VectorKind::RVVFixedLengthMaskRatio1_2: + case VectorKind::RVVFixedLengthMaskRatio1_4: + return 0; + case VectorKind::RVVFixedLengthMaskRatio2: + case VectorKind::RVVFixedLengthMaskRatio2_1: + case VectorKind::RVVFixedLengthMaskRatio2_2: + case VectorKind::RVVFixedLengthMaskRatio2_4: + return 1; + case VectorKind::RVVFixedLengthMaskRatio4: + case VectorKind::RVVFixedLengthMaskRatio4_1: + case VectorKind::RVVFixedLengthMaskRatio4_2: + case VectorKind::RVVFixedLengthMaskRatio4_4: + return 2; + case VectorKind::RVVFixedLengthMaskRatio8: + case VectorKind::RVVFixedLengthMaskRatio8_1: + case VectorKind::RVVFixedLengthMaskRatio8_2: + case VectorKind::RVVFixedLengthMaskRatio8_4: + return 3; + case VectorKind::RVVFixedLengthMaskRatio16: + case VectorKind::RVVFixedLengthMaskRatio16_1: + case VectorKind::RVVFixedLengthMaskRatio16_2: + case VectorKind::RVVFixedLengthMaskRatio16_4: + return 4; + case VectorKind::RVVFixedLengthMaskRatio32: + case VectorKind::RVVFixedLengthMaskRatio32_1: + case VectorKind::RVVFixedLengthMaskRatio32_2: + case VectorKind::RVVFixedLengthMaskRatio32_4: + return 5; + case VectorKind::RVVFixedLengthMaskRatio64: + case VectorKind::RVVFixedLengthMaskRatio64_1: + case VectorKind::RVVFixedLengthMaskRatio64_2: + case VectorKind::RVVFixedLengthMaskRatio64_4: + return 6; + default: + llvm_unreachable("not an RVV fixed-length mask vector kind"); + } +} + +/// Return the number of lanes (1, 2 or 4) of an RVV fixed-length mask vector +/// kind that fits in less than one byte, or 0 if its lanes fill whole bytes. +inline unsigned getRVVFixedLengthMaskSubByteLanes(VectorKind VK) { + switch (VK) { + case VectorKind::RVVFixedLengthMaskRatio1: + case VectorKind::RVVFixedLengthMaskRatio2: + case VectorKind::RVVFixedLengthMaskRatio4: + case VectorKind::RVVFixedLengthMaskRatio8: + case VectorKind::RVVFixedLengthMaskRatio16: + case VectorKind::RVVFixedLengthMaskRatio32: + case VectorKind::RVVFixedLengthMaskRatio64: + return 0; + case VectorKind::RVVFixedLengthMaskRatio1_1: + case VectorKind::RVVFixedLengthMaskRatio2_1: + case VectorKind::RVVFixedLengthMaskRatio4_1: + case VectorKind::RVVFixedLengthMaskRatio8_1: + case VectorKind::RVVFixedLengthMaskRatio16_1: + case VectorKind::RVVFixedLengthMaskRatio32_1: + case VectorKind::RVVFixedLengthMaskRatio64_1: + return 1; + case VectorKind::RVVFixedLengthMaskRatio1_2: + case VectorKind::RVVFixedLengthMaskRatio2_2: + case VectorKind::RVVFixedLengthMaskRatio4_2: + case VectorKind::RVVFixedLengthMaskRatio8_2: + case VectorKind::RVVFixedLengthMaskRatio16_2: + case VectorKind::RVVFixedLengthMaskRatio32_2: + case VectorKind::RVVFixedLengthMaskRatio64_2: + return 2; + case VectorKind::RVVFixedLengthMaskRatio1_4: + case VectorKind::RVVFixedLengthMaskRatio2_4: + case VectorKind::RVVFixedLengthMaskRatio4_4: + case VectorKind::RVVFixedLengthMaskRatio8_4: + case VectorKind::RVVFixedLengthMaskRatio16_4: + case VectorKind::RVVFixedLengthMaskRatio32_4: + case VectorKind::RVVFixedLengthMaskRatio64_4: + return 4; + default: + llvm_unreachable("not an RVV fixed-length mask vector kind"); + } +} + +/// Inverse of getRVVFixedLengthMaskRatioLog2() and +/// getRVVFixedLengthMaskSubByteLanes(). +inline VectorKind getRVVFixedLengthMaskVectorKind(unsigned RatioLog2, + unsigned SubByteLanes) { + static constexpr VectorKind Kinds[7][4] = { + {VectorKind::RVVFixedLengthMaskRatio1, + VectorKind::RVVFixedLengthMaskRatio1_1, + VectorKind::RVVFixedLengthMaskRatio1_2, + VectorKind::RVVFixedLengthMaskRatio1_4}, + {VectorKind::RVVFixedLengthMaskRatio2, + VectorKind::RVVFixedLengthMaskRatio2_1, + VectorKind::RVVFixedLengthMaskRatio2_2, + VectorKind::RVVFixedLengthMaskRatio2_4}, + {VectorKind::RVVFixedLengthMaskRatio4, + VectorKind::RVVFixedLengthMaskRatio4_1, + VectorKind::RVVFixedLengthMaskRatio4_2, + VectorKind::RVVFixedLengthMaskRatio4_4}, + {VectorKind::RVVFixedLengthMaskRatio8, + VectorKind::RVVFixedLengthMaskRatio8_1, + VectorKind::RVVFixedLengthMaskRatio8_2, + VectorKind::RVVFixedLengthMaskRatio8_4}, + {VectorKind::RVVFixedLengthMaskRatio16, + VectorKind::RVVFixedLengthMaskRatio16_1, + VectorKind::RVVFixedLengthMaskRatio16_2, + VectorKind::RVVFixedLengthMaskRatio16_4}, + {VectorKind::RVVFixedLengthMaskRatio32, + VectorKind::RVVFixedLengthMaskRatio32_1, + VectorKind::RVVFixedLengthMaskRatio32_2, + VectorKind::RVVFixedLengthMaskRatio32_4}, + {VectorKind::RVVFixedLengthMaskRatio64, + VectorKind::RVVFixedLengthMaskRatio64_1, + VectorKind::RVVFixedLengthMaskRatio64_2, + VectorKind::RVVFixedLengthMaskRatio64_4}, + }; + assert(RatioLog2 < 7 && "ratio out of range for an RVV mask type"); + switch (SubByteLanes) { + case 0: + return Kinds[RatioLog2][0]; + case 1: + return Kinds[RatioLog2][1]; + case 2: + return Kinds[RatioLog2][2]; + case 4: + return Kinds[RatioLog2][3]; + default: + llvm_unreachable("unexpected sub-byte lane count"); + } +} + /// Represents a GCC generic vector type. This type is created using /// __attribute__((vector_size(n)), where "n" specifies the vector size in /// bytes; or from an Altivec __vector or vector declaration. @@ -4385,6 +4581,13 @@ class VectorType : public Type, public llvm::FoldingSetNode { return VectorKind(VectorTypeBits.VecKind); } + /// Return the number of lanes of an RVV fixed-length mask vector. Its + /// elements are bytes, but each lane is a single bit. + unsigned getRVVFixedLengthMaskLanes() const { + unsigned SubByteLanes = getRVVFixedLengthMaskSubByteLanes(getVectorKind()); + return SubByteLanes ? SubByteLanes : getNumElements() * 8; + } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getNumElements(), getTypeClass(), getVectorKind()); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6afc80a2b908bb..4a2bb929be42eb 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -91,6 +91,7 @@ #include "llvm/Support/SipHash.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/AArch64TargetParser.h" +#include "llvm/TargetParser/RISCVTargetParser.h" #include "llvm/TargetParser/Triple.h" #include <algorithm> #include <cassert> @@ -2156,10 +2157,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { // Adjust the alignment for fixed-length SVE predicates. Align = 16; else if (isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) + isRVVFixedLengthMaskVectorKind(VT->getVectorKind())) // Adjust the alignment for fixed-length RVV vectors. Align = std::min<unsigned>(64, Width); // Vector types have their natural alignment resist reduction by @@ -10773,14 +10771,8 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec, Second->getVectorKind() != VectorKind::SveFixedLengthPredicate && !isRVVFixedLengthDataVectorKind(First->getVectorKind()) && !isRVVFixedLengthDataVectorKind(Second->getVectorKind()) && - First->getVectorKind() != VectorKind::RVVFixedLengthMask && - Second->getVectorKind() != VectorKind::RVVFixedLengthMask && - First->getVectorKind() != VectorKind::RVVFixedLengthMask_1 && - Second->getVectorKind() != VectorKind::RVVFixedLengthMask_1 && - First->getVectorKind() != VectorKind::RVVFixedLengthMask_2 && - Second->getVectorKind() != VectorKind::RVVFixedLengthMask_2 && - First->getVectorKind() != VectorKind::RVVFixedLengthMask_4 && - Second->getVectorKind() != VectorKind::RVVFixedLengthMask_4) + !isRVVFixedLengthMaskVectorKind(First->getVectorKind()) && + !isRVVFixedLengthMaskVectorKind(Second->getVectorKind())) return true; // In OpenCL, treat half and _Float16 vector types as compatible. @@ -10860,29 +10852,17 @@ bool ASTContext::areCompatibleRVVTypes(QualType FirstType, auto IsValidCast = [this](QualType FirstType, QualType SecondType) { if (const auto *BT = FirstType->getAs<BuiltinType>()) { if (const auto *VT = SecondType->getAs<VectorType>()) { - if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) { + if (isRVVFixedLengthMaskVectorKind(VT->getVectorKind())) { BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT); + // A mask typedef converts to and from the vbool<R>_t type it was + // written against: vbool<R>_t has RVVBitsPerBlock / R lanes at + // vscale=1. return FirstType->isRVVVLSBuiltinType() && Info.ElementType == BoolTy && - getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT))); - } - if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1) { - BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT); - return FirstType->isRVVVLSBuiltinType() && - Info.ElementType == BoolTy && - getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT) * 8)); - } - if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2) { - BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT); - return FirstType->isRVVVLSBuiltinType() && - Info.ElementType == BoolTy && - getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 4); - } - if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) { - BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT); - return FirstType->isRVVVLSBuiltinType() && - Info.ElementType == BoolTy && - getTypeSize(SecondType) == ((getRVVTypeSize(*this, BT)) * 2); + (llvm::RISCV::RVVBitsPerBlock >> + getRVVFixedLengthMaskRatioLog2(VT->getVectorKind())) == + Info.EC.getKnownMinValue() && + VT->getRVVFixedLengthMaskLanes() == getRVVTypeSize(*this, BT); } if (isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || VT->getVectorKind() == VectorKind::Generic) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 8fd9059abcdf3d..6f24eb0a829aec 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -35,7 +35,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/TargetParser/RISCVTargetParser.h" #include <optional> using namespace clang; @@ -4317,10 +4316,7 @@ void CXXNameMangler::mangleAArch64FixedSveVectorType( void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { assert((isRVVFixedLengthDataVectorKind(T->getVectorKind()) || - T->getVectorKind() == VectorKind::RVVFixedLengthMask || - T->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || - T->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || - T->getVectorKind() == VectorKind::RVVFixedLengthMask_4) && + isRVVFixedLengthMaskVectorKind(T->getVectorKind())) && "expected fixed-length RVV vector!"); QualType EltType = T->getElementType(); @@ -4376,36 +4372,20 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { llvm_unreachable("unexpected element type for fixed-length RVV vector!"); } - unsigned VecSizeInBits; - switch (T->getVectorKind()) { - case VectorKind::RVVFixedLengthMask_1: - VecSizeInBits = 1; - break; - case VectorKind::RVVFixedLengthMask_2: - VecSizeInBits = 2; - break; - case VectorKind::RVVFixedLengthMask_4: - VecSizeInBits = 4; - break; - default: - VecSizeInBits = getASTContext().getTypeInfo(T).Width; - break; - } + // A mask typedef is mangled with its lane count, which is less than its + // size in bits when it fits in a single byte. + unsigned VecSizeInBits = isRVVFixedLengthMaskVectorKind(T->getVectorKind()) + ? T->getRVVFixedLengthMaskLanes() + : getASTContext().getTypeInfo(T).Width; - // Append the LMUL suffix. For data types the LMUL is recorded in the vector - // kind, so the mangled name names the type the typedef was written against - // even when the typedef is shorter than VLEN * LMUL, and does not depend on - // VLEN at all. Mask types are still tied to a fixed VLEN, so their ratio is - // derived from it. + // Append the LMUL suffix of a data type, or the ratio of a mask type. Both + // are recorded in the vector kind, so the mangled name names the type the + // typedef was written against and does not depend on VLEN. if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) { TypeNameOS << getRVVFixedLengthDataLMulString(T->getVectorKind(), /*MF=*/true); } else { - auto VScale = getASTContext().getTargetInfo().getVScaleRange( - getASTContext().getLangOpts(), - TargetInfo::ArmStreamingKind::NotStreaming); - unsigned VLen = VScale->first * llvm::RISCV::RVVBitsPerBlock; - TypeNameOS << (VLen / VecSizeInBits); + TypeNameOS << (1u << getRVVFixedLengthMaskRatioLog2(T->getVectorKind())); } TypeNameOS << "_t"; @@ -4446,10 +4426,7 @@ void CXXNameMangler::mangleType(const VectorType *T) { mangleAArch64FixedSveVectorType(T); return; } else if (isRVVFixedLengthDataVectorKind(T->getVectorKind()) || - T->getVectorKind() == VectorKind::RVVFixedLengthMask || - T->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || - T->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || - T->getVectorKind() == VectorKind::RVVFixedLengthMask_4) { + isRVVFixedLengthMaskVectorKind(T->getVectorKind())) { mangleRISCVFixedRVVVectorType(T); return; } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 2555c3658df02f..c7015feeb6e3ff 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -750,24 +750,21 @@ void JSONNodeDumper::VisitVectorType(const VectorType *VT) { case VectorKind::SveFixedLengthPredicate: JOS.attribute("vectorKind", "fixed-length sve predicate vector"); break; - case VectorKind::RVVFixedLengthData_MF8: - case VectorKind::RVVFixedLengthData_MF4: - case VectorKind::RVVFixedLengthData_MF2: - case VectorKind::RVVFixedLengthData_M1: - case VectorKind::RVVFixedLengthData_M2: - case VectorKind::RVVFixedLengthData_M4: - case VectorKind::RVVFixedLengthData_M8: - JOS.attribute("vectorKind", - "fixed-length rvv data vector lmul " + - getRVVFixedLengthDataLMulString(VT->getVectorKind(), - /*MF=*/false) - .str()); - break; - case VectorKind::RVVFixedLengthMask: - case VectorKind::RVVFixedLengthMask_1: - case VectorKind::RVVFixedLengthMask_2: - case VectorKind::RVVFixedLengthMask_4: - JOS.attribute("vectorKind", "fixed-length rvv mask vector"); + default: + if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) { + JOS.attribute("vectorKind", + "fixed-length rvv data vector lmul " + + getRVVFixedLengthDataLMulString(VT->getVectorKind(), + /*MF=*/false) + .str()); + } else { + assert(isRVVFixedLengthMaskVectorKind(VT->getVectorKind()) && + "unexpected vector kind"); + JOS.attribute("vectorKind", + "fixed-length rvv mask vector ratio " + + std::to_string(1u << getRVVFixedLengthMaskRatioLog2( + VT->getVectorKind()))); + } break; } } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index f1b216d970c731..48c4043ad5cafa 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -2168,21 +2168,16 @@ void TextNodeDumper::VisitVectorType(const VectorType *T) { case VectorKind::SveFixedLengthPredicate: OS << " fixed-length sve predicate vector"; break; - case VectorKind::RVVFixedLengthData_MF8: - case VectorKind::RVVFixedLengthData_MF4: - case VectorKind::RVVFixedLengthData_MF2: - case VectorKind::RVVFixedLengthData_M1: - case VectorKind::RVVFixedLengthData_M2: - case VectorKind::RVVFixedLengthData_M4: - case VectorKind::RVVFixedLengthData_M8: - OS << " fixed-length rvv data vector lmul " - << getRVVFixedLengthDataLMulString(T->getVectorKind(), /*MF=*/false); - break; - case VectorKind::RVVFixedLengthMask: - case VectorKind::RVVFixedLengthMask_1: - case VectorKind::RVVFixedLengthMask_2: - case VectorKind::RVVFixedLengthMask_4: - OS << " fixed-length rvv mask vector"; + default: + if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) { + OS << " fixed-length rvv data vector lmul " + << getRVVFixedLengthDataLMulString(T->getVectorKind(), /*MF=*/false); + } else { + assert(isRVVFixedLengthMaskVectorKind(T->getVectorKind()) && + "unexpected vector kind"); + OS << " fixed-length rvv mask vector ratio " + << (1u << getRVVFixedLengthMaskRatioLog2(T->getVectorKind())); + } break; } OS << " " << T->getNumElements(); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 12cce9ccc32a55..b438b41b3f8f73 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -718,37 +718,23 @@ void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) { OS << ") * 8))) "; printBefore(T->getElementType(), OS); break; - case VectorKind::RVVFixedLengthData_MF8: - case VectorKind::RVVFixedLengthData_MF4: - case VectorKind::RVVFixedLengthData_MF2: - case VectorKind::RVVFixedLengthData_M1: - case VectorKind::RVVFixedLengthData_M2: - case VectorKind::RVVFixedLengthData_M4: - case VectorKind::RVVFixedLengthData_M8: - case VectorKind::RVVFixedLengthMask: - case VectorKind::RVVFixedLengthMask_1: - case VectorKind::RVVFixedLengthMask_2: - case VectorKind::RVVFixedLengthMask_4: + default: + // The RVV fixed-length data and mask kinds. + assert((isRVVFixedLengthDataVectorKind(T->getVectorKind()) || + isRVVFixedLengthMaskVectorKind(T->getVectorKind())) && + "unexpected vector kind"); // FIXME: We prefer to print the size directly here, but have no way // to get the size of the type. OS << "__attribute__((__riscv_rvv_vector_bits__("; - switch (T->getVectorKind()) { - case VectorKind::RVVFixedLengthMask_1: - OS << '1'; - break; - case VectorKind::RVVFixedLengthMask_2: - OS << '2'; - break; - case VectorKind::RVVFixedLengthMask_4: - OS << '4'; - break; - default: + if (isRVVFixedLengthMaskVectorKind(T->getVectorKind()) && + getRVVFixedLengthMaskSubByteLanes(T->getVectorKind())) { + OS << getRVVFixedLengthMaskSubByteLanes(T->getVectorKind()); + } else { OS << T->getNumElements(); OS << " * sizeof("; print(T->getElementType(), OS, StringRef()); // Multiply by 8 for the number of bits. OS << ") * 8"; - break; } OS << "))) "; printBefore(T->getElementType(), OS); @@ -819,39 +805,20 @@ void TypePrinter::printDependentVectorBefore( OS << "))) "; printBefore(T->getElementType(), OS); break; - case VectorKind::RVVFixedLengthData_MF8: - case VectorKind::RVVFixedLengthData_MF4: - case VectorKind::RVVFixedLengthData_MF2: - case VectorKind::RVVFixedLengthData_M1: - case VectorKind::RVVFixedLengthData_M2: - case VectorKind::RVVFixedLengthData_M4: - case VectorKind::RVVFixedLengthData_M8: - case VectorKind::RVVFixedLengthMask: - case VectorKind::RVVFixedLengthMask_1: - case VectorKind::RVVFixedLengthMask_2: - case VectorKind::RVVFixedLengthMask_4: + default: + // The RVV fixed-length data and mask kinds. + assert((isRVVFixedLengthDataVectorKind(T->getVectorKind()) || + isRVVFixedLengthMaskVectorKind(T->getVectorKind())) && + "unexpected vector kind"); // FIXME: We prefer to print the size directly here, but have no way // to get the size of the type. OS << "__attribute__((__riscv_rvv_vector_bits__("; - switch (T->getVectorKind()) { - case VectorKind::RVVFixedLengthMask_1: - OS << '1'; - break; - case VectorKind::RVVFixedLengthMask_2: - OS << '2'; - break; - case VectorKind::RVVFixedLengthMask_4: - OS << '4'; - break; - default: - if (T->getSizeExpr()) { - T->getSizeExpr()->printPretty(OS, nullptr, Policy); - OS << " * sizeof("; - print(T->getElementType(), OS, StringRef()); - // Multiply by 8 for the number of bits. - OS << ") * 8"; - } - break; + if (T->getSizeExpr()) { + T->getSizeExpr()->printPretty(OS, nullptr, Policy); + OS << " * sizeof("; + print(T->getElementType(), OS, StringRef()); + // Multiply by 8 for the number of bits. + OS << ") * 8"; } OS << "))) "; printBefore(T->getElementType(), OS); diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index c84a4f00f4bc7f..fb539e87591b67 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -428,17 +428,23 @@ static unsigned getRVVFixedLengthDataMinElts(VectorKind VK, return SizeAtVScale1 / EltSizeInBits; } +/// Minimum element count of the scalable vector a vbool<R>_t mask is coerced +/// to, i.e. the N in <vscale x N x i1>. +static unsigned getRVVFixedLengthMaskMinElts(VectorKind VK) { + return llvm::RISCV::RVVBitsPerBlock >> getRVVFixedLengthMaskRatioLog2(VK); +} + /// Minimum element count of the scalable vector \p VT is coerced to, in units -/// of \p VT's own Clang element type. Masks are modelled as i8 vectors and are -/// exactly VLEN * LMUL wide, so their LMUL is recovered from VLEN. +/// of \p VT's own Clang element type. Masks are modelled as i8 vectors, so +/// their i1 lane count is rounded up to whole bytes. unsigned RISCVABIInfo::getRVVFixedLengthMinElts(const VectorType *VT) const { unsigned EltSizeInBits = getContext().getTypeSize(VT->getElementType()); if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) return getRVVFixedLengthDataMinElts(VT->getVectorKind(), EltSizeInBits); - - auto VScale = getContext().getTargetInfo().getVScaleRange( - getContext().getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming); - return llvm::divideCeil(VT->getNumElements(), VScale->first); + assert(isRVVFixedLengthMaskVectorKind(VT->getVectorKind()) && + "not an RVV fixed-length vector"); + return llvm::divideCeil(getRVVFixedLengthMaskMinElts(VT->getVectorKind()), + EltSizeInBits); } llvm::Type *RISCVABIInfo::detectVLSCCEligibleStruct(QualType Ty, @@ -587,17 +593,8 @@ RISCVABIInfo::detectHomogeneousRVVFixedLengthStruct(QualType Ty) const { return nullptr; auto IsFixedLengthRVVVector = [](const VectorType *VT) { - if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) - return true; - switch (VT->getVectorKind()) { - case VectorKind::RVVFixedLengthMask: - case VectorKind::RVVFixedLengthMask_1: - case VectorKind::RVVFixedLengthMask_2: - case VectorKind::RVVFixedLengthMask_4: - return true; - default: - return false; - } + return isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || + isRVVFixedLengthMaskVectorKind(VT->getVectorKind()); }; QualType CommonTy; @@ -688,24 +685,16 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const { auto VScale = getContext().getTargetInfo().getVScaleRange( getContext().getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming); - unsigned NumElts = VT->getNumElements(); - llvm::Type *EltType = llvm::Type::getInt1Ty(getVMContext()); - switch (VT->getVectorKind()) { - case VectorKind::RVVFixedLengthMask_1: - break; - case VectorKind::RVVFixedLengthMask_2: - NumElts *= 2; - break; - case VectorKind::RVVFixedLengthMask_4: - NumElts *= 4; - break; - case VectorKind::RVVFixedLengthMask: - NumElts *= 8; - break; - default: + unsigned NumElts; + llvm::Type *EltType; + if (isRVVFixedLengthMaskVectorKind(VT->getVectorKind())) { + NumElts = VT->getRVVFixedLengthMaskLanes(); + EltType = llvm::Type::getInt1Ty(getVMContext()); + } else { assert((VT->getVectorKind() == VectorKind::Generic || isRVVFixedLengthDataVectorKind(VT->getVectorKind())) && "Unexpected vector kind"); + NumElts = VT->getNumElements(); EltType = CGT.ConvertType(VT->getElementType()); } @@ -717,6 +706,9 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const { // Use the LMUL of the type the typedef was written against. MinScalableElts = getRVVFixedLengthDataMinElts( VT->getVectorKind(), EltType->getScalarSizeInBits()); + } else if (isRVVFixedLengthMaskVectorKind(VT->getVectorKind())) { + // Use the ratio of the vbool<R>_t type the typedef was written against. + MinScalableElts = getRVVFixedLengthMaskMinElts(VT->getVectorKind()); } else { // The MinNumElts is simplified from equation: // NumElts / VScale = @@ -862,10 +854,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed, if (const VectorType *VT = Ty->getAs<VectorType>(); VT && !VT->getElementType()->isBitIntType()) { if (isRVVFixedLengthDataVectorKind(VT->getVectorKind()) || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || - VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4) + isRVVFixedLengthMaskVectorKind(VT->getVectorKind())) return coerceVLSVector(Ty); if (VT->getVectorKind() == VectorKind::Generic && ABIVLen != 0) // Generic vector without riscv_vls_cc should fall through and pass by diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9a11c859997eb6..00a2e23497aa87 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -11062,10 +11062,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, VecType->getVectorKind() == VectorKind::SveFixedLengthPredicate) return true; if (isRVVFixedLengthDataVectorKind(VecType->getVectorKind()) || - VecType->getVectorKind() == VectorKind::RVVFixedLengthMask || - VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_1 || - VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_2 || - VecType->getVectorKind() == VectorKind::RVVFixedLengthMask_4) { + isRVVFixedLengthMaskVectorKind(VecType->getVectorKind())) { SVEorRVV = 1; return true; } @@ -11097,13 +11094,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, VectorKind::SveFixedLengthPredicate) return true; if (isRVVFixedLengthDataVectorKind(SecondVecType->getVectorKind()) || - SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask || - SecondVecType->getVectorKind() == - VectorKind::RVVFixedLengthMask_1 || - SecondVecType->getVectorKind() == - VectorKind::RVVFixedLengthMask_2 || - SecondVecType->getVectorKind() == - VectorKind::RVVFixedLengthMask_4) { + isRVVFixedLengthMaskVectorKind(SecondVecType->getVectorKind())) { SVEorRVV = 1; return true; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 9c299b9e55da8d..e16630ce9cd844 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -8871,28 +8871,26 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType, S.Context.getBuiltinVectorTypeInfo(CurType->castAs<BuiltinType>()); unsigned MinElts = Info.EC.getKnownMinValue(); - VectorKind VecKind = VectorKind::RVVFixedLengthMask; + VectorKind VecKind; unsigned ExpectedSize = VScale->first * MinElts; QualType EltType = CurType->getRVVEltType(S.Context); unsigned EltSize = S.Context.getTypeSize(EltType); unsigned NumElts; if (Info.ElementType == S.Context.BoolTy) { + // A mask is stored in bytes. One with fewer than 8 lanes takes a single + // byte, and its lane count is recorded in the vector kind. NumElts = VecSize / S.Context.getCharWidth(); + unsigned SubByteLanes = 0; if (!NumElts) { NumElts = 1; - switch (VecSize) { - case 1: - VecKind = VectorKind::RVVFixedLengthMask_1; - break; - case 2: - VecKind = VectorKind::RVVFixedLengthMask_2; - break; - case 4: - VecKind = VectorKind::RVVFixedLengthMask_4; - break; - } - } else - VecKind = VectorKind::RVVFixedLengthMask; + if (VecSize == 1 || VecSize == 2 || VecSize == 4) + SubByteLanes = VecSize; + } + // Record the ratio of the vbool<R>_t type in the vector kind, so that + // later stages do not have to re-derive it from VLEN and the lane count. + // vbool<R>_t has RVVBitsPerBlock / R lanes at vscale=1. + VecKind = getRVVFixedLengthMaskVectorKind( + llvm::Log2_32(llvm::RISCV::RVVBitsPerBlock / MinElts), SubByteLanes); } else { ExpectedSize *= EltSize; NumElts = VecSize / EltSize; diff --git a/clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c b/clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c similarity index 64% rename from clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c rename to clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c index 4ba0ea48ba4240..e2ce3ac4d611e6 100644 --- a/clang/test/AST/ast-dump-riscv-rvv-fixed-length-data-types.c +++ b/clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c @@ -1,5 +1,5 @@ -// Verify that a riscv_rvv_vector_bits typedef of a data type records the LMUL -// of the sizeless type it was written against. +// Verify that a riscv_rvv_vector_bits typedef records the LMUL of the sizeless +// data type, or the ratio of the sizeless mask type, it was written against. // RUN: %clang_cc1 -triple riscv64-none-linux-gnu -target-feature +zve64d \ // RUN: -mvscale-min=2 -mvscale-max=2 -ast-dump %s | FileCheck %s @@ -15,6 +15,10 @@ typedef __rvv_int32m1_t fixed_i32m1 __attribute__((riscv_rvv_vector_bits(128))); typedef __rvv_int32m2_t fixed_i32m2 __attribute__((riscv_rvv_vector_bits(256))); typedef __rvv_int64m4_t fixed_i64m4 __attribute__((riscv_rvv_vector_bits(512))); typedef __rvv_int8m8_t fixed_i8m8 __attribute__((riscv_rvv_vector_bits(1024))); +typedef __rvv_bool1_t fixed_b1 __attribute__((riscv_rvv_vector_bits(128))); +typedef __rvv_bool8_t fixed_b8 __attribute__((riscv_rvv_vector_bits(16))); +typedef __rvv_bool32_t fixed_b32 __attribute__((riscv_rvv_vector_bits(4))); +typedef __rvv_bool64_t fixed_b64 __attribute__((riscv_rvv_vector_bits(2))); // CHECK-LABEL: TypedefDecl {{.*}} fixed_i8mf8 // CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/8 2 @@ -30,6 +34,14 @@ typedef __rvv_int8m8_t fixed_i8m8 __attribute__((riscv_rvv_vector_bits(1024))); // CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 4 8 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i8m8 // CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 8 128 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_b1 +// CHECK: VectorType {{.*}} fixed-length rvv mask vector ratio 1 16 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_b8 +// CHECK: VectorType {{.*}} fixed-length rvv mask vector ratio 8 2 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_b32 +// CHECK: VectorType {{.*}} fixed-length rvv mask vector ratio 32 1 +// CHECK-LABEL: TypedefDecl {{.*}} fixed_b64 +// CHECK: VectorType {{.*}} fixed-length rvv mask vector ratio 64 1 // JSON: "vectorKind": "fixed-length rvv data vector lmul 1/8" // JSON: "vectorKind": "fixed-length rvv data vector lmul 1/4" @@ -38,3 +50,7 @@ typedef __rvv_int8m8_t fixed_i8m8 __attribute__((riscv_rvv_vector_bits(1024))); // JSON: "vectorKind": "fixed-length rvv data vector lmul 2" // JSON: "vectorKind": "fixed-length rvv data vector lmul 4" // JSON: "vectorKind": "fixed-length rvv data vector lmul 8" +// JSON: "vectorKind": "fixed-length rvv mask vector ratio 1" +// JSON: "vectorKind": "fixed-length rvv mask vector ratio 8" +// JSON: "vectorKind": "fixed-length rvv mask vector ratio 32" +// JSON: "vectorKind": "fixed-length rvv mask vector ratio 64" >From 9dc58094ef772cd8b8842f5597076c2c9f1a9bda Mon Sep 17 00:00:00 2001 From: Kito Cheng <[email protected]> Date: Tue, 3 Nov 2026 13:43:56 +0800 Subject: [PATCH 3/3] fixup! [Clang][RISCV] Record the LMUL in RVV fixed-length data vector kinds --- clang/include/clang/AST/TypeBase.h | 20 ++++++------- clang/lib/AST/ItaniumMangle.cpp | 3 +- clang/lib/AST/JSONNodeDumper.cpp | 9 +++--- clang/lib/AST/TextNodeDumper.cpp | 2 +- ...dump-riscv-rvv-fixed-length-vector-kinds.c | 28 +++++++++---------- 5 files changed, 30 insertions(+), 32 deletions(-) diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index 4f4f4b8a22d63c..c9e64040aeefe1 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -4335,24 +4335,24 @@ inline int getRVVFixedLengthDataLMulLog2(VectorKind VK) { } } -/// Return the LMUL of an RVV fixed-length data vector kind as a string: -/// "mf8" .. "m8" if \p MF is true, "1/8" .. "8" otherwise. -inline StringRef getRVVFixedLengthDataLMulString(VectorKind VK, bool MF) { +/// Return the LMUL of an RVV fixed-length data vector kind as a string, +/// "mf8" .. "m8". +inline StringRef getRVVFixedLengthDataLMulString(VectorKind VK) { switch (VK) { case VectorKind::RVVFixedLengthData_MF8: - return MF ? "mf8" : "1/8"; + return "mf8"; case VectorKind::RVVFixedLengthData_MF4: - return MF ? "mf4" : "1/4"; + return "mf4"; case VectorKind::RVVFixedLengthData_MF2: - return MF ? "mf2" : "1/2"; + return "mf2"; case VectorKind::RVVFixedLengthData_M1: - return MF ? "m1" : "1"; + return "m1"; case VectorKind::RVVFixedLengthData_M2: - return MF ? "m2" : "2"; + return "m2"; case VectorKind::RVVFixedLengthData_M4: - return MF ? "m4" : "4"; + return "m4"; case VectorKind::RVVFixedLengthData_M8: - return MF ? "m8" : "8"; + return "m8"; default: llvm_unreachable("not an RVV fixed-length data vector kind"); } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 6f24eb0a829aec..edb7ca8e33d1e1 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4382,8 +4382,7 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) { // are recorded in the vector kind, so the mangled name names the type the // typedef was written against and does not depend on VLEN. if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) { - TypeNameOS << getRVVFixedLengthDataLMulString(T->getVectorKind(), - /*MF=*/true); + TypeNameOS << getRVVFixedLengthDataLMulString(T->getVectorKind()); } else { TypeNameOS << (1u << getRVVFixedLengthMaskRatioLog2(T->getVectorKind())); } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index c7015feeb6e3ff..cb0d8a6d3f4ea9 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -752,11 +752,10 @@ void JSONNodeDumper::VisitVectorType(const VectorType *VT) { break; default: if (isRVVFixedLengthDataVectorKind(VT->getVectorKind())) { - JOS.attribute("vectorKind", - "fixed-length rvv data vector lmul " + - getRVVFixedLengthDataLMulString(VT->getVectorKind(), - /*MF=*/false) - .str()); + JOS.attribute( + "vectorKind", + "fixed-length rvv data vector lmul " + + getRVVFixedLengthDataLMulString(VT->getVectorKind()).str()); } else { assert(isRVVFixedLengthMaskVectorKind(VT->getVectorKind()) && "unexpected vector kind"); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 48c4043ad5cafa..7812bf16986195 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -2171,7 +2171,7 @@ void TextNodeDumper::VisitVectorType(const VectorType *T) { default: if (isRVVFixedLengthDataVectorKind(T->getVectorKind())) { OS << " fixed-length rvv data vector lmul " - << getRVVFixedLengthDataLMulString(T->getVectorKind(), /*MF=*/false); + << getRVVFixedLengthDataLMulString(T->getVectorKind()); } else { assert(isRVVFixedLengthMaskVectorKind(T->getVectorKind()) && "unexpected vector kind"); diff --git a/clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c b/clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c index e2ce3ac4d611e6..aa48f3d8487b11 100644 --- a/clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c +++ b/clang/test/AST/ast-dump-riscv-rvv-fixed-length-vector-kinds.c @@ -21,19 +21,19 @@ typedef __rvv_bool32_t fixed_b32 __attribute__((riscv_rvv_vector_bits(4))); typedef __rvv_bool64_t fixed_b64 __attribute__((riscv_rvv_vector_bits(2))); // CHECK-LABEL: TypedefDecl {{.*}} fixed_i8mf8 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/8 2 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul mf8 2 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i16mf4 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/4 2 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul mf4 2 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i32mf2 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1/2 2 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul mf2 2 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i32m1 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 1 4 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul m1 4 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i32m2 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 2 8 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul m2 8 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i64m4 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 4 8 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul m4 8 // CHECK-LABEL: TypedefDecl {{.*}} fixed_i8m8 -// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul 8 128 +// CHECK: VectorType {{.*}} fixed-length rvv data vector lmul m8 128 // CHECK-LABEL: TypedefDecl {{.*}} fixed_b1 // CHECK: VectorType {{.*}} fixed-length rvv mask vector ratio 1 16 // CHECK-LABEL: TypedefDecl {{.*}} fixed_b8 @@ -43,13 +43,13 @@ typedef __rvv_bool64_t fixed_b64 __attribute__((riscv_rvv_vector_bits(2))); // CHECK-LABEL: TypedefDecl {{.*}} fixed_b64 // CHECK: VectorType {{.*}} fixed-length rvv mask vector ratio 64 1 -// JSON: "vectorKind": "fixed-length rvv data vector lmul 1/8" -// JSON: "vectorKind": "fixed-length rvv data vector lmul 1/4" -// JSON: "vectorKind": "fixed-length rvv data vector lmul 1/2" -// JSON: "vectorKind": "fixed-length rvv data vector lmul 1" -// JSON: "vectorKind": "fixed-length rvv data vector lmul 2" -// JSON: "vectorKind": "fixed-length rvv data vector lmul 4" -// JSON: "vectorKind": "fixed-length rvv data vector lmul 8" +// JSON: "vectorKind": "fixed-length rvv data vector lmul mf8" +// JSON: "vectorKind": "fixed-length rvv data vector lmul mf4" +// JSON: "vectorKind": "fixed-length rvv data vector lmul mf2" +// JSON: "vectorKind": "fixed-length rvv data vector lmul m1" +// JSON: "vectorKind": "fixed-length rvv data vector lmul m2" +// JSON: "vectorKind": "fixed-length rvv data vector lmul m4" +// JSON: "vectorKind": "fixed-length rvv data vector lmul m8" // JSON: "vectorKind": "fixed-length rvv mask vector ratio 1" // JSON: "vectorKind": "fixed-length rvv mask vector ratio 8" // JSON: "vectorKind": "fixed-length rvv mask vector ratio 32" _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
