27#include "llvm/ADT/SmallVector.h"
28#include "llvm/TargetParser/RISCVISAInfo.h"
29#include "llvm/TargetParser/RISCVTargetParser.h"
43struct RVVIntrinsicDef {
45 std::string BuiltinName;
51struct RVVOverloadIntrinsicDef {
59#define DECL_SIGNATURE_TABLE
60#include "clang/Basic/riscv_vector_builtin_sema.inc"
61#undef DECL_SIGNATURE_TABLE
65#define DECL_SIGNATURE_TABLE
66#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
67#undef DECL_SIGNATURE_TABLE
71#define DECL_INTRINSIC_RECORDS
72#include "clang/Basic/riscv_vector_builtin_sema.inc"
73#undef DECL_INTRINSIC_RECORDS
77#define DECL_INTRINSIC_RECORDS
78#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
79#undef DECL_INTRINSIC_RECORDS
86 case IntrinsicKind::RVV:
88 case IntrinsicKind::SIFIVE_VECTOR:
91 llvm_unreachable(
"Unhandled IntrinsicKind");
96 switch (
Type->getScalarType()) {
97 case ScalarTypeKind::Void:
100 case ScalarTypeKind::Size_t:
103 case ScalarTypeKind::Ptrdiff_t:
106 case ScalarTypeKind::UnsignedLong:
109 case ScalarTypeKind::SignedLong:
112 case ScalarTypeKind::Boolean:
115 case ScalarTypeKind::SignedInteger:
118 case ScalarTypeKind::UnsignedInteger:
121 case ScalarTypeKind::BFloat:
124 case ScalarTypeKind::Float:
125 switch (
Type->getElementBitwidth()) {
136 llvm_unreachable(
"Unsupported floating point width.");
141 llvm_unreachable(
"Unhandled type.");
143 if (
Type->isVector()) {
150 if (
Type->isConstant())
154 if (
Type->isPointer())
166 bool ConstructedRISCVVBuiltins;
167 bool ConstructedRISCVSiFiveVectorBuiltins;
170 std::vector<RVVIntrinsicDef> IntrinsicList;
172 StringMap<uint32_t> Intrinsics;
174 StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;
178 StringRef OverloadedSuffixStr,
bool IsMask,
190 RISCVIntrinsicManagerImpl(
clang::Sema &S) : S(S), Context(S.Context) {
191 ConstructedRISCVVBuiltins =
false;
192 ConstructedRISCVSiFiveVectorBuiltins =
false;
205void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
208 static const std::pair<const char *, RVVRequire> FeatureCheckList[] = {
231 for (
auto &
Record : Recs) {
233 if (llvm::any_of(FeatureCheckList, [&](
const auto &Item) {
234 return (
Record.RequiredExtensions & Item.second) == Item.second &&
246 K,
Record.OverloadedSuffixIndex,
Record.OverloadedSuffixSize);
253 const Policy DefaultPolicy;
257 BasicProtoSeq,
false,
259 UnMaskedPolicyScheme, DefaultPolicy,
Record.IsTuple);
264 BasicProtoSeq,
true,
Record.HasMaskedOffOperand,
265 Record.HasVL,
Record.NF, MaskedPolicyScheme, DefaultPolicy,
268 bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
269 bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
276 for (
unsigned int TypeRangeMaskShift = 0;
277 TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
278 ++TypeRangeMaskShift) {
279 unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
280 BaseType =
static_cast<BasicType>(BaseTypeI);
282 if ((BaseTypeI &
Record.TypeRangeMask) != BaseTypeI)
286 for (
int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
287 if (!(
Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
290 std::optional<RVVTypes> Types =
291 TypeCache.computeTypes(BaseType, Log2LMUL,
Record.NF, ProtoSeq);
294 if (!Types.has_value())
298 TypeCache, BaseType, Log2LMUL, SuffixProto);
300 TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
303 InitRVVIntrinsic(
Record, SuffixStr, OverloadedSuffixStr,
false, *Types,
304 UnMaskedHasPolicy, DefaultPolicy);
307 if (
Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
308 for (
auto P : SupportedUnMaskedPolicies) {
311 BasicProtoSeq,
false,
313 UnMaskedPolicyScheme,
P,
Record.IsTuple);
314 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
315 BaseType, Log2LMUL,
Record.NF, PolicyPrototype);
316 InitRVVIntrinsic(
Record, SuffixStr, OverloadedSuffixStr,
317 false, *PolicyTypes, UnMaskedHasPolicy,
324 std::optional<RVVTypes> MaskTypes =
325 TypeCache.computeTypes(BaseType, Log2LMUL,
Record.NF, ProtoMaskSeq);
326 InitRVVIntrinsic(
Record, SuffixStr, OverloadedSuffixStr,
true,
327 *MaskTypes, MaskedHasPolicy, DefaultPolicy);
328 if (
Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
331 for (
auto P : SupportedMaskedPolicies) {
334 BasicProtoSeq,
true,
Record.HasMaskedOffOperand,
337 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
338 BaseType, Log2LMUL,
Record.NF, PolicyPrototype);
339 InitRVVIntrinsic(
Record, SuffixStr, OverloadedSuffixStr,
340 true, *PolicyTypes, MaskedHasPolicy,
P);
347void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
350 ConstructedRISCVVBuiltins =
true;
354 !ConstructedRISCVSiFiveVectorBuiltins) {
355 ConstructedRISCVSiFiveVectorBuiltins =
true;
357 IntrinsicKind::SIFIVE_VECTOR);
362void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
364 StringRef OverloadedSuffixStr,
bool IsMasked,
RVVTypes &Signature,
365 bool HasPolicy,
Policy PolicyAttrs) {
367 std::string Name =
Record.Name;
368 if (!SuffixStr.empty())
369 Name +=
"_" + SuffixStr.str();
372 std::string OverloadedName;
373 if (!
Record.OverloadedName)
374 OverloadedName = StringRef(
Record.Name).split(
"_").first.str();
376 OverloadedName =
Record.OverloadedName;
377 if (!OverloadedSuffixStr.empty())
378 OverloadedName +=
"_" + OverloadedSuffixStr.str();
381 std::string BuiltinName = std::string(
Record.Name);
384 OverloadedName, PolicyAttrs,
385 Record.HasFRMRoundModeOp);
388 uint32_t Index = IntrinsicList.size();
389 assert(IntrinsicList.size() == (
size_t)Index &&
390 "Intrinsics indices overflow.");
391 IntrinsicList.push_back({BuiltinName, Signature});
394 Intrinsics.insert({Name, Index});
397 RVVOverloadIntrinsicDef &OverloadIntrinsicDef =
398 OverloadIntrinsics[OverloadedName];
401 OverloadIntrinsicDef.Indexes.push_back(Index);
404void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(
LookupResult &LR,
410 RVVIntrinsicDef &IDef = IntrinsicList[Index];
412 size_t SigLength = Sigs.size();
419 for (
size_t i = 1; i < SigLength; ++i)
432 Context,
Parent,
Loc,
Loc, II, BuiltinFuncType,
nullptr,
439 const auto *FP = cast<FunctionProtoType>(BuiltinFuncType);
441 for (
unsigned IParm = 0,
E = FP->getNumParams(); IParm !=
E; ++IParm) {
444 FP->getParamType(IParm),
nullptr,
SC_None,
nullptr);
446 ParmList.push_back(Parm);
448 RVVIntrinsicDecl->setParams(ParmList);
452 RVVIntrinsicDecl->
addAttr(OverloadableAttr::CreateImplicit(Context));
458 BuiltinAliasAttr::CreateImplicit(S.
Context, &IntrinsicII));
464bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(
LookupResult &LR,
467 StringRef Name = II->
getName();
468 if (!Name.consume_front(
"__riscv_"))
472 auto OvIItr = OverloadIntrinsics.find(Name);
473 if (OvIItr != OverloadIntrinsics.end()) {
474 const RVVOverloadIntrinsicDef &OvIntrinsicDef = OvIItr->second;
475 for (
auto Index : OvIntrinsicDef.Indexes)
476 CreateRVVIntrinsicDecl(LR, II, PP, Index,
485 auto Itr = Intrinsics.find(Name);
486 if (Itr != Intrinsics.end()) {
487 CreateRVVIntrinsicDecl(LR, II, PP, Itr->second,
497std::unique_ptr<clang::sema::RISCVIntrinsicManager>
499 return std::make_unique<RISCVIntrinsicManagerImpl>(S);
514 int64_t Val =
Result.getSExtValue();
515 if ((Val >= 0 && Val <= 3) || (Val >= 5 && Val <= 7))
518 return Diag(TheCall->
getBeginLoc(), diag::err_riscv_builtin_invalid_lmul)
524 assert((EGW == 128 || EGW == 256) &&
"EGW can only be 128 or 256 bits");
530 unsigned MinElemCount = Info.
EC.getKnownMinValue();
532 unsigned EGS = EGW / ElemSize;
535 if (EGS <= MinElemCount)
539 assert(EGS % MinElemCount == 0);
540 unsigned VScaleFactor = EGS / MinElemCount;
542 unsigned MinRequiredVLEN = VScaleFactor * llvm::RISCV::RVVBitsPerBlock;
543 std::string RequiredExt =
"zvl" + std::to_string(MinRequiredVLEN) +
"b";
546 diag::err_riscv_type_requires_extension)
547 <<
Type << RequiredExt;
561 case RISCVVector::BI__builtin_rvv_vmulhsu_vv:
562 case RISCVVector::BI__builtin_rvv_vmulhsu_vx:
563 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tu:
564 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tu:
565 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_m:
566 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_m:
567 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_mu:
568 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_mu:
569 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tum:
570 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tum:
571 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tumu:
572 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tumu:
573 case RISCVVector::BI__builtin_rvv_vmulhu_vv:
574 case RISCVVector::BI__builtin_rvv_vmulhu_vx:
575 case RISCVVector::BI__builtin_rvv_vmulhu_vv_tu:
576 case RISCVVector::BI__builtin_rvv_vmulhu_vx_tu:
577 case RISCVVector::BI__builtin_rvv_vmulhu_vv_m:
578 case RISCVVector::BI__builtin_rvv_vmulhu_vx_m:
579 case RISCVVector::BI__builtin_rvv_vmulhu_vv_mu:
580 case RISCVVector::BI__builtin_rvv_vmulhu_vx_mu:
581 case RISCVVector::BI__builtin_rvv_vmulhu_vv_tum:
582 case RISCVVector::BI__builtin_rvv_vmulhu_vx_tum:
583 case RISCVVector::BI__builtin_rvv_vmulhu_vv_tumu:
584 case RISCVVector::BI__builtin_rvv_vmulhu_vx_tumu:
585 case RISCVVector::BI__builtin_rvv_vmulh_vv:
586 case RISCVVector::BI__builtin_rvv_vmulh_vx:
587 case RISCVVector::BI__builtin_rvv_vmulh_vv_tu:
588 case RISCVVector::BI__builtin_rvv_vmulh_vx_tu:
589 case RISCVVector::BI__builtin_rvv_vmulh_vv_m:
590 case RISCVVector::BI__builtin_rvv_vmulh_vx_m:
591 case RISCVVector::BI__builtin_rvv_vmulh_vv_mu:
592 case RISCVVector::BI__builtin_rvv_vmulh_vx_mu:
593 case RISCVVector::BI__builtin_rvv_vmulh_vv_tum:
594 case RISCVVector::BI__builtin_rvv_vmulh_vx_tum:
595 case RISCVVector::BI__builtin_rvv_vmulh_vv_tumu:
596 case RISCVVector::BI__builtin_rvv_vmulh_vx_tumu:
597 case RISCVVector::BI__builtin_rvv_vsmul_vv:
598 case RISCVVector::BI__builtin_rvv_vsmul_vx:
599 case RISCVVector::BI__builtin_rvv_vsmul_vv_tu:
600 case RISCVVector::BI__builtin_rvv_vsmul_vx_tu:
601 case RISCVVector::BI__builtin_rvv_vsmul_vv_m:
602 case RISCVVector::BI__builtin_rvv_vsmul_vx_m:
603 case RISCVVector::BI__builtin_rvv_vsmul_vv_mu:
604 case RISCVVector::BI__builtin_rvv_vsmul_vx_mu:
605 case RISCVVector::BI__builtin_rvv_vsmul_vv_tum:
606 case RISCVVector::BI__builtin_rvv_vsmul_vx_tum:
607 case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu:
608 case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu: {
613 llvm::StringMap<bool> FunctionFeatureMap;
617 !FunctionFeatureMap.lookup(
"v"))
619 diag::err_riscv_builtin_requires_extension)
627 case RISCVVector::BI__builtin_rvv_vsetvli:
630 case RISCVVector::BI__builtin_rvv_vsetvlimax:
633 case RISCVVector::BI__builtin_rvv_vget_v: {
644 MaxIndex = (VecInfo.
EC.getKnownMinValue() * VecInfo.
NumVectors) /
645 (ResVecInfo.
EC.getKnownMinValue() * ResVecInfo.
NumVectors);
648 case RISCVVector::BI__builtin_rvv_vset_v: {
659 MaxIndex = (ResVecInfo.
EC.getKnownMinValue() * ResVecInfo.
NumVectors) /
664 case RISCVVector::BI__builtin_rvv_vaeskf1_vi_tu:
665 case RISCVVector::BI__builtin_rvv_vaeskf2_vi_tu:
666 case RISCVVector::BI__builtin_rvv_vaeskf2_vi:
667 case RISCVVector::BI__builtin_rvv_vsm4k_vi_tu: {
674 case RISCVVector::BI__builtin_rvv_vsm3c_vi_tu:
675 case RISCVVector::BI__builtin_rvv_vsm3c_vi: {
680 case RISCVVector::BI__builtin_rvv_vaeskf1_vi:
681 case RISCVVector::BI__builtin_rvv_vsm4k_vi: {
686 case RISCVVector::BI__builtin_rvv_vaesdf_vv:
687 case RISCVVector::BI__builtin_rvv_vaesdf_vs:
688 case RISCVVector::BI__builtin_rvv_vaesdm_vv:
689 case RISCVVector::BI__builtin_rvv_vaesdm_vs:
690 case RISCVVector::BI__builtin_rvv_vaesef_vv:
691 case RISCVVector::BI__builtin_rvv_vaesef_vs:
692 case RISCVVector::BI__builtin_rvv_vaesem_vv:
693 case RISCVVector::BI__builtin_rvv_vaesem_vs:
694 case RISCVVector::BI__builtin_rvv_vaesz_vs:
695 case RISCVVector::BI__builtin_rvv_vsm4r_vv:
696 case RISCVVector::BI__builtin_rvv_vsm4r_vs:
697 case RISCVVector::BI__builtin_rvv_vaesdf_vv_tu:
698 case RISCVVector::BI__builtin_rvv_vaesdf_vs_tu:
699 case RISCVVector::BI__builtin_rvv_vaesdm_vv_tu:
700 case RISCVVector::BI__builtin_rvv_vaesdm_vs_tu:
701 case RISCVVector::BI__builtin_rvv_vaesef_vv_tu:
702 case RISCVVector::BI__builtin_rvv_vaesef_vs_tu:
703 case RISCVVector::BI__builtin_rvv_vaesem_vv_tu:
704 case RISCVVector::BI__builtin_rvv_vaesem_vs_tu:
705 case RISCVVector::BI__builtin_rvv_vaesz_vs_tu:
706 case RISCVVector::BI__builtin_rvv_vsm4r_vv_tu:
707 case RISCVVector::BI__builtin_rvv_vsm4r_vs_tu: {