Skip to content

Commit c92ad41

Browse files
committed
Recommit "[RISCV] Support __riscv_v_fixed_vlen for vbool types. (llvm#76551)"
Test updated to expect i8 gep. Original message: This adopts a similar behavior to AArch64 SVE, where bool vectors are represented as a vector of chars with 1/8 the number of elements. This ensures the vector always occupies a power of 2 number of bytes. A consequence of this is that vbool64_t, vbool32_t, and vool16_t can only be used with a vector length that guarantees at least 8 bits.
1 parent 849951f commit c92ad41

20 files changed

+1065
-34
lines changed

clang/docs/ReleaseNotes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ LoongArch Support
149149
RISC-V Support
150150
^^^^^^^^^^^^^^
151151

152+
- ``__attribute__((rvv_vector_bits(N))) is now supported for RVV vbool*_t types.
153+
152154
CUDA/HIP Language Changes
153155
^^^^^^^^^^^^^^^^^^^^^^^^^
154156

clang/include/clang/AST/Type.h

+3
Original file line numberDiff line numberDiff line change
@@ -3495,6 +3495,9 @@ enum class VectorKind {
34953495

34963496
/// is RISC-V RVV fixed-length data vector
34973497
RVVFixedLengthData,
3498+
3499+
/// is RISC-V RVV fixed-length mask vector
3500+
RVVFixedLengthMask,
34983501
};
34993502

35003503
/// Represents a GCC generic vector type. This type is created using

clang/include/clang/Basic/AttrDocs.td

+4-1
Original file line numberDiff line numberDiff line change
@@ -2424,7 +2424,10 @@ only be a power of 2 between 64 and 65536.
24242424
For types where LMUL!=1, ``__riscv_v_fixed_vlen`` needs to be scaled by the LMUL
24252425
of the type before passing to the attribute.
24262426

2427-
``vbool*_t`` types are not supported at this time.
2427+
For ``vbool*_t`` types, ``__riscv_v_fixed_vlen`` needs to be divided by the
2428+
number from the type name. For example, ``vbool8_t`` needs to use
2429+
``__riscv_v_fixed_vlen`` / 8. If the resulting value is not a multiple of 8,
2430+
the type is not supported for that value of ``__riscv_v_fixed_vlen``.
24282431
}];
24292432
}
24302433

clang/lib/AST/ASTContext.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -1945,7 +1945,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
19451945
else if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
19461946
// Adjust the alignment for fixed-length SVE predicates.
19471947
Align = 16;
1948-
else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData)
1948+
else if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
1949+
VT->getVectorKind() == VectorKind::RVVFixedLengthMask)
19491950
// Adjust the alignment for fixed-length RVV vectors.
19501951
Align = std::min<unsigned>(64, Width);
19511952
break;
@@ -9416,7 +9417,9 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,
94169417
Second->getVectorKind() != VectorKind::SveFixedLengthData &&
94179418
Second->getVectorKind() != VectorKind::SveFixedLengthPredicate &&
94189419
First->getVectorKind() != VectorKind::RVVFixedLengthData &&
9419-
Second->getVectorKind() != VectorKind::RVVFixedLengthData)
9420+
Second->getVectorKind() != VectorKind::RVVFixedLengthData &&
9421+
First->getVectorKind() != VectorKind::RVVFixedLengthMask &&
9422+
Second->getVectorKind() != VectorKind::RVVFixedLengthMask)
94209423
return true;
94219424

94229425
return false;
@@ -9522,8 +9525,11 @@ static uint64_t getRVVTypeSize(ASTContext &Context, const BuiltinType *Ty) {
95229525

95239526
ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo(Ty);
95249527

9525-
uint64_t EltSize = Context.getTypeSize(Info.ElementType);
9526-
uint64_t MinElts = Info.EC.getKnownMinValue();
9528+
unsigned EltSize = Context.getTypeSize(Info.ElementType);
9529+
if (Info.ElementType == Context.BoolTy)
9530+
EltSize = 1;
9531+
9532+
unsigned MinElts = Info.EC.getKnownMinValue();
95279533
return VScale->first * MinElts * EltSize;
95289534
}
95299535

@@ -9537,6 +9543,12 @@ bool ASTContext::areCompatibleRVVTypes(QualType FirstType,
95379543
auto IsValidCast = [this](QualType FirstType, QualType SecondType) {
95389544
if (const auto *BT = FirstType->getAs<BuiltinType>()) {
95399545
if (const auto *VT = SecondType->getAs<VectorType>()) {
9546+
if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) {
9547+
BuiltinVectorTypeInfo Info = getBuiltinVectorTypeInfo(BT);
9548+
return FirstType->isRVVVLSBuiltinType() &&
9549+
Info.ElementType == BoolTy &&
9550+
getTypeSize(SecondType) == getRVVTypeSize(*this, BT);
9551+
}
95409552
if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
95419553
VT->getVectorKind() == VectorKind::Generic)
95429554
return FirstType->isRVVVLSBuiltinType() &&

clang/lib/AST/ItaniumMangle.cpp

+17-8
Original file line numberDiff line numberDiff line change
@@ -3994,7 +3994,8 @@ void CXXNameMangler::mangleAArch64FixedSveVectorType(
39943994
}
39953995

39963996
void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) {
3997-
assert(T->getVectorKind() == VectorKind::RVVFixedLengthData &&
3997+
assert((T->getVectorKind() == VectorKind::RVVFixedLengthData ||
3998+
T->getVectorKind() == VectorKind::RVVFixedLengthMask) &&
39983999
"expected fixed-length RVV vector!");
39994000

40004001
QualType EltType = T->getElementType();
@@ -4009,7 +4010,10 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) {
40094010
TypeNameOS << "int8";
40104011
break;
40114012
case BuiltinType::UChar:
4012-
TypeNameOS << "uint8";
4013+
if (T->getVectorKind() == VectorKind::RVVFixedLengthData)
4014+
TypeNameOS << "uint8";
4015+
else
4016+
TypeNameOS << "bool";
40134017
break;
40144018
case BuiltinType::Short:
40154019
TypeNameOS << "int16";
@@ -4048,12 +4052,16 @@ void CXXNameMangler::mangleRISCVFixedRVVVectorType(const VectorType *T) {
40484052
auto VScale = getASTContext().getTargetInfo().getVScaleRange(
40494053
getASTContext().getLangOpts());
40504054
unsigned VLen = VScale->first * llvm::RISCV::RVVBitsPerBlock;
4051-
TypeNameOS << 'm';
4052-
if (VecSizeInBits >= VLen)
4053-
TypeNameOS << (VecSizeInBits / VLen);
4054-
else
4055-
TypeNameOS << 'f' << (VLen / VecSizeInBits);
40564055

4056+
if (T->getVectorKind() == VectorKind::RVVFixedLengthData) {
4057+
TypeNameOS << 'm';
4058+
if (VecSizeInBits >= VLen)
4059+
TypeNameOS << (VecSizeInBits / VLen);
4060+
else
4061+
TypeNameOS << 'f' << (VLen / VecSizeInBits);
4062+
} else {
4063+
TypeNameOS << (VLen / VecSizeInBits);
4064+
}
40574065
TypeNameOS << "_t";
40584066

40594067
Out << "9__RVV_VLSI" << 'u' << TypeNameStr.size() << TypeNameStr << "Lj"
@@ -4093,7 +4101,8 @@ void CXXNameMangler::mangleType(const VectorType *T) {
40934101
T->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
40944102
mangleAArch64FixedSveVectorType(T);
40954103
return;
4096-
} else if (T->getVectorKind() == VectorKind::RVVFixedLengthData) {
4104+
} else if (T->getVectorKind() == VectorKind::RVVFixedLengthData ||
4105+
T->getVectorKind() == VectorKind::RVVFixedLengthMask) {
40974106
mangleRISCVFixedRVVVectorType(T);
40984107
return;
40994108
}

clang/lib/AST/JSONNodeDumper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ void JSONNodeDumper::VisitVectorType(const VectorType *VT) {
703703
case VectorKind::RVVFixedLengthData:
704704
JOS.attribute("vectorKind", "fixed-length rvv data vector");
705705
break;
706+
case VectorKind::RVVFixedLengthMask:
707+
JOS.attribute("vectorKind", "fixed-length rvv mask vector");
708+
break;
706709
}
707710
}
708711

clang/lib/AST/TextNodeDumper.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,9 @@ void TextNodeDumper::VisitVectorType(const VectorType *T) {
16231623
case VectorKind::RVVFixedLengthData:
16241624
OS << " fixed-length rvv data vector";
16251625
break;
1626+
case VectorKind::RVVFixedLengthMask:
1627+
OS << " fixed-length rvv mask vector";
1628+
break;
16261629
}
16271630
OS << " " << T->getNumElements();
16281631
}

clang/lib/AST/Type.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -2479,6 +2479,9 @@ bool Type::isRVVVLSBuiltinType() const {
24792479
IsFP, IsBF) \
24802480
case BuiltinType::Id: \
24812481
return NF == 1;
2482+
#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
2483+
case BuiltinType::Id: \
2484+
return true;
24822485
#include "clang/Basic/RISCVVTypes.def"
24832486
default:
24842487
return false;
@@ -2491,7 +2494,17 @@ QualType Type::getRVVEltType(const ASTContext &Ctx) const {
24912494
assert(isRVVVLSBuiltinType() && "unsupported type!");
24922495

24932496
const BuiltinType *BTy = castAs<BuiltinType>();
2494-
return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType;
2497+
2498+
switch (BTy->getKind()) {
2499+
#define RVV_PREDICATE_TYPE(Name, Id, SingletonId, NumEls) \
2500+
case BuiltinType::Id: \
2501+
return Ctx.UnsignedCharTy;
2502+
default:
2503+
return Ctx.getBuiltinVectorTypeInfo(BTy).ElementType;
2504+
#include "clang/Basic/RISCVVTypes.def"
2505+
}
2506+
2507+
llvm_unreachable("Unhandled type");
24952508
}
24962509

24972510
bool QualType::isPODType(const ASTContext &Context) const {

clang/lib/AST/TypePrinter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {
694694
printBefore(T->getElementType(), OS);
695695
break;
696696
case VectorKind::RVVFixedLengthData:
697+
case VectorKind::RVVFixedLengthMask:
697698
// FIXME: We prefer to print the size directly here, but have no way
698699
// to get the size of the type.
699700
OS << "__attribute__((__riscv_rvv_vector_bits__(";
@@ -773,6 +774,7 @@ void TypePrinter::printDependentVectorBefore(
773774
printBefore(T->getElementType(), OS);
774775
break;
775776
case VectorKind::RVVFixedLengthData:
777+
case VectorKind::RVVFixedLengthMask:
776778
// FIXME: We prefer to print the size directly here, but have no way
777779
// to get the size of the type.
778780
OS << "__attribute__((__riscv_rvv_vector_bits__(";

clang/lib/CodeGen/Targets/RISCV.cpp

+15-6
Original file line numberDiff line numberDiff line change
@@ -321,20 +321,28 @@ ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty) const {
321321
assert(Ty->isVectorType() && "expected vector type!");
322322

323323
const auto *VT = Ty->castAs<VectorType>();
324-
assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData &&
325-
"Unexpected vector kind");
326-
327324
assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
328325

329326
auto VScale =
330327
getContext().getTargetInfo().getVScaleRange(getContext().getLangOpts());
328+
329+
unsigned NumElts = VT->getNumElements();
330+
llvm::Type *EltType;
331+
if (VT->getVectorKind() == VectorKind::RVVFixedLengthMask) {
332+
NumElts *= 8;
333+
EltType = llvm::Type::getInt1Ty(getVMContext());
334+
} else {
335+
assert(VT->getVectorKind() == VectorKind::RVVFixedLengthData &&
336+
"Unexpected vector kind");
337+
EltType = CGT.ConvertType(VT->getElementType());
338+
}
339+
331340
// The MinNumElts is simplified from equation:
332341
// NumElts / VScale =
333342
// (EltSize * NumElts / (VScale * RVVBitsPerBlock))
334343
// * (RVVBitsPerBlock / EltSize)
335344
llvm::ScalableVectorType *ResType =
336-
llvm::ScalableVectorType::get(CGT.ConvertType(VT->getElementType()),
337-
VT->getNumElements() / VScale->first);
345+
llvm::ScalableVectorType::get(EltType, NumElts / VScale->first);
338346
return ABIArgInfo::getDirect(ResType);
339347
}
340348

@@ -437,7 +445,8 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
437445
}
438446

439447
if (const VectorType *VT = Ty->getAs<VectorType>())
440-
if (VT->getVectorKind() == VectorKind::RVVFixedLengthData)
448+
if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
449+
VT->getVectorKind() == VectorKind::RVVFixedLengthMask)
441450
return coerceVLSVector(Ty);
442451

443452
// Aggregates which are <= 2*XLen will be passed in registers if possible,

clang/lib/Sema/SemaExpr.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -11142,7 +11142,8 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
1114211142
if (VecType->getVectorKind() == VectorKind::SveFixedLengthData ||
1114311143
VecType->getVectorKind() == VectorKind::SveFixedLengthPredicate)
1114411144
return true;
11145-
if (VecType->getVectorKind() == VectorKind::RVVFixedLengthData) {
11145+
if (VecType->getVectorKind() == VectorKind::RVVFixedLengthData ||
11146+
VecType->getVectorKind() == VectorKind::RVVFixedLengthMask) {
1114611147
SVEorRVV = 1;
1114711148
return true;
1114811149
}
@@ -11173,7 +11174,8 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
1117311174
SecondVecType->getVectorKind() ==
1117411175
VectorKind::SveFixedLengthPredicate)
1117511176
return true;
11176-
if (SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthData) {
11177+
if (SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthData ||
11178+
SecondVecType->getVectorKind() == VectorKind::RVVFixedLengthMask) {
1117711179
SVEorRVV = 1;
1117811180
return true;
1117911181
}

clang/lib/Sema/SemaType.cpp

+15-6
Original file line numberDiff line numberDiff line change
@@ -8646,21 +8646,30 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType &CurType,
86468646

86478647
ASTContext::BuiltinVectorTypeInfo Info =
86488648
S.Context.getBuiltinVectorTypeInfo(CurType->castAs<BuiltinType>());
8649-
unsigned EltSize = S.Context.getTypeSize(Info.ElementType);
86508649
unsigned MinElts = Info.EC.getKnownMinValue();
86518650

8651+
VectorKind VecKind = VectorKind::RVVFixedLengthData;
8652+
unsigned ExpectedSize = VScale->first * MinElts;
8653+
QualType EltType = CurType->getRVVEltType(S.Context);
8654+
unsigned EltSize = S.Context.getTypeSize(EltType);
8655+
unsigned NumElts;
8656+
if (Info.ElementType == S.Context.BoolTy) {
8657+
NumElts = VecSize / S.Context.getCharWidth();
8658+
VecKind = VectorKind::RVVFixedLengthMask;
8659+
} else {
8660+
ExpectedSize *= EltSize;
8661+
NumElts = VecSize / EltSize;
8662+
}
8663+
86528664
// The attribute vector size must match -mrvv-vector-bits.
8653-
unsigned ExpectedSize = VScale->first * MinElts * EltSize;
8654-
if (VecSize != ExpectedSize) {
8665+
if (ExpectedSize % 8 != 0 || VecSize != ExpectedSize) {
86558666
S.Diag(Attr.getLoc(), diag::err_attribute_bad_rvv_vector_size)
86568667
<< VecSize << ExpectedSize;
86578668
Attr.setInvalid();
86588669
return;
86598670
}
86608671

8661-
VectorKind VecKind = VectorKind::RVVFixedLengthData;
8662-
VecSize /= EltSize;
8663-
CurType = S.Context.getVectorType(Info.ElementType, VecSize, VecKind);
8672+
CurType = S.Context.getVectorType(EltType, NumElts, VecKind);
86648673
}
86658674

86668675
/// Handle OpenCL Access Qualifier Attribute.

0 commit comments

Comments
 (0)