clang 22.0.0git
SemaRISCV.cpp
Go to the documentation of this file.
1//===------ SemaRISCV.cpp ------- RISC-V target-specific routines ---------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis functions specific to RISC-V.
10//
11//===----------------------------------------------------------------------===//
12
15#include "clang/AST/Attr.h"
16#include "clang/AST/Attrs.inc"
17#include "clang/AST/Decl.h"
22#include "clang/Sema/Attr.h"
24#include "clang/Sema/Lookup.h"
27#include "clang/Sema/Sema.h"
29#include "llvm/ADT/SmallVector.h"
30#include "llvm/TargetParser/RISCVISAInfo.h"
31#include "llvm/TargetParser/RISCVTargetParser.h"
32#include <optional>
33#include <string>
34#include <vector>
35
36using namespace llvm;
37using namespace clang;
38using namespace clang::RISCV;
39
41
42namespace {
43
44// Function definition of a RVV intrinsic.
45struct RVVIntrinsicDef {
46 /// Mapping to which clang built-in function, e.g. __builtin_rvv_vadd.
47 std::string BuiltinName;
48
49 /// Mapping to RequiredFeatures in riscv_vector.td
50 StringRef RequiredExtensions;
51
52 /// Function signature, first element is return type.
53 RVVTypes Signature;
54};
55
56struct RVVOverloadIntrinsicDef {
57 // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList.
59};
60
61} // namespace
62
64#define DECL_SIGNATURE_TABLE
65#include "clang/Basic/riscv_vector_builtin_sema.inc"
66#undef DECL_SIGNATURE_TABLE
67};
68
70#define DECL_SIGNATURE_TABLE
71#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
72#undef DECL_SIGNATURE_TABLE
73};
74
76#define DECL_SIGNATURE_TABLE
77#include "clang/Basic/riscv_andes_vector_builtin_sema.inc"
78#undef DECL_SIGNATURE_TABLE
79};
80
82#define DECL_INTRINSIC_RECORDS
83#include "clang/Basic/riscv_vector_builtin_sema.inc"
84#undef DECL_INTRINSIC_RECORDS
85};
86
88#define DECL_INTRINSIC_RECORDS
89#include "clang/Basic/riscv_sifive_vector_builtin_sema.inc"
90#undef DECL_INTRINSIC_RECORDS
91};
92
94#define DECL_INTRINSIC_RECORDS
95#include "clang/Basic/riscv_andes_vector_builtin_sema.inc"
96#undef DECL_INTRINSIC_RECORDS
97};
98
99// Get subsequence of signature table.
101ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length) {
102 switch (K) {
103 case IntrinsicKind::RVV:
104 return ArrayRef(&RVVSignatureTable[Index], Length);
105 case IntrinsicKind::SIFIVE_VECTOR:
106 return ArrayRef(&RVSiFiveVectorSignatureTable[Index], Length);
107 case IntrinsicKind::ANDES_VECTOR:
108 return ArrayRef(&RVAndesVectorSignatureTable[Index], Length);
109 }
110 llvm_unreachable("Unhandled IntrinsicKind");
111}
112
113static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type) {
114 QualType QT;
115 switch (Type->getScalarType()) {
116 case ScalarTypeKind::Void:
117 QT = Context.VoidTy;
118 break;
119 case ScalarTypeKind::Size_t:
120 QT = Context.getSizeType();
121 break;
122 case ScalarTypeKind::Ptrdiff_t:
123 QT = Context.getPointerDiffType();
124 break;
125 case ScalarTypeKind::UnsignedLong:
126 QT = Context.UnsignedLongTy;
127 break;
128 case ScalarTypeKind::SignedLong:
129 QT = Context.LongTy;
130 break;
131 case ScalarTypeKind::Boolean:
132 QT = Context.BoolTy;
133 break;
134 case ScalarTypeKind::SignedInteger:
135 QT = Context.getIntTypeForBitwidth(Type->getElementBitwidth(), true);
136 break;
137 case ScalarTypeKind::UnsignedInteger:
138 QT = Context.getIntTypeForBitwidth(Type->getElementBitwidth(), false);
139 break;
140 case ScalarTypeKind::BFloat:
141 QT = Context.BFloat16Ty;
142 break;
143 case ScalarTypeKind::Float:
144 switch (Type->getElementBitwidth()) {
145 case 64:
146 QT = Context.DoubleTy;
147 break;
148 case 32:
149 QT = Context.FloatTy;
150 break;
151 case 16:
152 QT = Context.Float16Ty;
153 break;
154 default:
155 llvm_unreachable("Unsupported floating point width.");
156 }
157 break;
158 case Invalid:
159 case Undefined:
160 llvm_unreachable("Unhandled type.");
161 }
162 if (Type->isVector()) {
163 if (Type->isTuple())
164 QT = Context.getScalableVectorType(QT, *Type->getScale(), Type->getNF());
165 else
166 QT = Context.getScalableVectorType(QT, *Type->getScale());
167 }
168
169 if (Type->isConstant())
170 QT = Context.getConstType(QT);
171
172 // Transform the type to a pointer as the last step, if necessary.
173 if (Type->isPointer())
174 QT = Context.getPointerType(QT);
175
176 return QT;
177}
178
179namespace {
180class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
181private:
182 Sema &S;
183 RVVTypeCache TypeCache;
184 bool ConstructedRISCVVBuiltins;
185 bool ConstructedRISCVSiFiveVectorBuiltins;
186 bool ConstructedRISCVAndesVectorBuiltins;
187
188 // List of all RVV intrinsic.
189 std::vector<RVVIntrinsicDef> IntrinsicList;
190 // Mapping function name to index of IntrinsicList.
191 StringMap<uint32_t> Intrinsics;
192 // Mapping function name to RVVOverloadIntrinsicDef.
193 StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;
194
195 // Create RVVIntrinsicDef.
196 void InitRVVIntrinsic(const RVVIntrinsicRecord &Record, StringRef SuffixStr,
197 StringRef OverloadedSuffixStr, bool IsMask,
198 RVVTypes &Types, bool HasPolicy, Policy PolicyAttrs);
199
200 // Create FunctionDecl for a vector intrinsic.
201 void CreateRVVIntrinsicDecl(LookupResult &LR, IdentifierInfo *II,
202 Preprocessor &PP, uint32_t Index,
203 bool IsOverload);
204
205 void ConstructRVVIntrinsics(ArrayRef<RVVIntrinsicRecord> Recs,
206 IntrinsicKind K);
207
208public:
209 RISCVIntrinsicManagerImpl(clang::Sema &S) : S(S) {
210 ConstructedRISCVVBuiltins = false;
211 ConstructedRISCVSiFiveVectorBuiltins = false;
212 ConstructedRISCVAndesVectorBuiltins = false;
213 }
214
215 // Initialize IntrinsicList
216 void InitIntrinsicList() override;
217
218 // Create RISC-V vector intrinsic and insert into symbol table if found, and
219 // return true, otherwise return false.
221 Preprocessor &PP) override;
222};
223} // namespace
224
225void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
227 // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
228 // in RISCVVEmitter.cpp.
229 for (auto &Record : Recs) {
230 // Create Intrinsics for each type and LMUL.
231 BasicType BaseType = BasicType::Unknown;
232 ArrayRef<PrototypeDescriptor> BasicProtoSeq =
233 ProtoSeq2ArrayRef(K, Record.PrototypeIndex, Record.PrototypeLength);
235 ProtoSeq2ArrayRef(K, Record.SuffixIndex, Record.SuffixLength);
236 ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
237 K, Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
238
239 PolicyScheme UnMaskedPolicyScheme =
240 static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
241 PolicyScheme MaskedPolicyScheme =
242 static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
243
244 const Policy DefaultPolicy;
245
248 BasicProtoSeq, /*IsMasked=*/false,
249 /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
250 UnMaskedPolicyScheme, DefaultPolicy, Record.IsTuple);
251
253 if (Record.HasMasked)
255 BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
256 Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy,
257 Record.IsTuple);
258
259 bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
260 bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
261 SmallVector<Policy> SupportedUnMaskedPolicies =
263 SmallVector<Policy> SupportedMaskedPolicies =
265 Record.HasMaskPolicy);
266
267 for (unsigned int TypeRangeMaskShift = 0;
268 TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
269 ++TypeRangeMaskShift) {
270 unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
271 BaseType = static_cast<BasicType>(BaseTypeI);
272
273 if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
274 continue;
275
276 // Expanded with different LMUL.
277 for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
278 if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
279 continue;
280
281 std::optional<RVVTypes> Types =
282 TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
283
284 // Ignored to create new intrinsic if there are any illegal types.
285 if (!Types.has_value())
286 continue;
287
288 std::string SuffixStr = RVVIntrinsic::getSuffixStr(
289 TypeCache, BaseType, Log2LMUL, SuffixProto);
290 std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
291 TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
292
293 // Create non-masked intrinsic.
294 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
295 UnMaskedHasPolicy, DefaultPolicy);
296
297 // Create non-masked policy intrinsic.
298 if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
299 for (auto P : SupportedUnMaskedPolicies) {
302 BasicProtoSeq, /*IsMasked=*/false,
303 /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
304 UnMaskedPolicyScheme, P, Record.IsTuple);
305 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
306 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
307 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
308 /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
309 P);
310 }
311 }
312 if (!Record.HasMasked)
313 continue;
314 // Create masked intrinsic.
315 std::optional<RVVTypes> MaskTypes =
316 TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
317 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
318 *MaskTypes, MaskedHasPolicy, DefaultPolicy);
319 if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
320 continue;
321 // Create masked policy intrinsic.
322 for (auto P : SupportedMaskedPolicies) {
325 BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
326 Record.HasVL, Record.NF, MaskedPolicyScheme, P,
327 Record.IsTuple);
328 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
329 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
330 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
331 /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
332 }
333 } // End for different LMUL
334 } // End for different TypeRange
335 }
336}
337
338void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
339
340 if (S.RISCV().DeclareRVVBuiltins && !ConstructedRISCVVBuiltins) {
341 ConstructedRISCVVBuiltins = true;
342 ConstructRVVIntrinsics(RVVIntrinsicRecords, IntrinsicKind::RVV);
343 }
345 !ConstructedRISCVSiFiveVectorBuiltins) {
346 ConstructedRISCVSiFiveVectorBuiltins = true;
347 ConstructRVVIntrinsics(RVSiFiveVectorIntrinsicRecords,
348 IntrinsicKind::SIFIVE_VECTOR);
349 }
351 !ConstructedRISCVAndesVectorBuiltins) {
352 ConstructedRISCVAndesVectorBuiltins = true;
353 ConstructRVVIntrinsics(RVAndesVectorIntrinsicRecords,
354 IntrinsicKind::ANDES_VECTOR);
355 }
356}
357
358// Compute name and signatures for intrinsic with practical types.
359void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
360 const RVVIntrinsicRecord &Record, StringRef SuffixStr,
361 StringRef OverloadedSuffixStr, bool IsMasked, RVVTypes &Signature,
362 bool HasPolicy, Policy PolicyAttrs) {
363 // Function name, e.g. vadd_vv_i32m1.
364 std::string Name = Record.Name;
365 if (!SuffixStr.empty())
366 Name += "_" + SuffixStr.str();
367
368 // Overloaded function name, e.g. vadd.
369 std::string OverloadedName;
370 if (!Record.OverloadedName)
371 OverloadedName = StringRef(Record.Name).split("_").first.str();
372 else
373 OverloadedName = Record.OverloadedName;
374 if (!OverloadedSuffixStr.empty())
375 OverloadedName += "_" + OverloadedSuffixStr.str();
376
377 // clang built-in function name, e.g. __builtin_rvv_vadd.
378 std::string BuiltinName = std::string(Record.Name);
379
380 RVVIntrinsic::updateNamesAndPolicy(IsMasked, HasPolicy, Name, BuiltinName,
381 OverloadedName, PolicyAttrs,
382 Record.HasFRMRoundModeOp);
383
384 // Put into IntrinsicList.
385 uint32_t Index = IntrinsicList.size();
386 assert(IntrinsicList.size() == (size_t)Index &&
387 "Intrinsics indices overflow.");
388 IntrinsicList.push_back({BuiltinName, Record.RequiredExtensions, Signature});
389
390 // Creating mapping to Intrinsics.
391 Intrinsics.insert({Name, Index});
392
393 // Get the RVVOverloadIntrinsicDef.
394 RVVOverloadIntrinsicDef &OverloadIntrinsicDef =
395 OverloadIntrinsics[OverloadedName];
396
397 // And added the index.
398 OverloadIntrinsicDef.Indexes.push_back(Index);
399}
400
401void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR,
402 IdentifierInfo *II,
403 Preprocessor &PP,
404 uint32_t Index,
405 bool IsOverload) {
406 ASTContext &Context = S.Context;
407 RVVIntrinsicDef &IDef = IntrinsicList[Index];
408 RVVTypes Sigs = IDef.Signature;
409 size_t SigLength = Sigs.size();
410 RVVType *ReturnType = Sigs[0];
411 QualType RetType = RVVType2Qual(Context, ReturnType);
413 QualType BuiltinFuncType;
414
415 // Skip return type, and convert RVVType to QualType for arguments.
416 for (size_t i = 1; i < SigLength; ++i)
417 ArgTypes.push_back(RVVType2Qual(Context, Sigs[i]));
418
421
422 PI.Variadic = false;
423
425 BuiltinFuncType = Context.getFunctionType(RetType, ArgTypes, PI);
427
428 FunctionDecl *RVVIntrinsicDecl = FunctionDecl::Create(
429 Context, Parent, Loc, Loc, II, BuiltinFuncType, /*TInfo=*/nullptr,
431 /*isInlineSpecified*/ false,
432 /*hasWrittenPrototype*/ true);
433
434 // Create Decl objects for each parameter, adding them to the
435 // FunctionDecl.
436 const auto *FP = cast<FunctionProtoType>(BuiltinFuncType);
438 for (unsigned IParm = 0, E = FP->getNumParams(); IParm != E; ++IParm) {
439 ParmVarDecl *Parm =
440 ParmVarDecl::Create(Context, RVVIntrinsicDecl, Loc, Loc, nullptr,
441 FP->getParamType(IParm), nullptr, SC_None, nullptr);
442 Parm->setScopeInfo(0, IParm);
443 ParmList.push_back(Parm);
444 }
445 RVVIntrinsicDecl->setParams(ParmList);
446
447 // Add function attributes.
448 if (IsOverload)
449 RVVIntrinsicDecl->addAttr(OverloadableAttr::CreateImplicit(Context));
450
451 if (IDef.RequiredExtensions != "")
452 RVVIntrinsicDecl->addAttr(
453 TargetAttr::CreateImplicit(Context, IDef.RequiredExtensions));
454 // Setup alias to __builtin_rvv_*
455 IdentifierInfo &IntrinsicII =
456 PP.getIdentifierTable().get("__builtin_rvv_" + IDef.BuiltinName);
457 RVVIntrinsicDecl->addAttr(
458 BuiltinAliasAttr::CreateImplicit(S.Context, &IntrinsicII));
459
460 // Add to symbol table.
461 LR.addDecl(RVVIntrinsicDecl);
462}
463
464bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(LookupResult &LR,
465 IdentifierInfo *II,
466 Preprocessor &PP) {
467 StringRef Name = II->getName();
468 if (!Name.consume_front("__riscv_"))
469 return false;
470
471 // Lookup the function name from the overload intrinsics first.
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,
477 /*IsOverload*/ true);
478
479 // If we added overloads, need to resolve the lookup result.
480 LR.resolveKind();
481 return true;
482 }
483
484 // Lookup the function name from the intrinsics.
485 auto Itr = Intrinsics.find(Name);
486 if (Itr != Intrinsics.end()) {
487 CreateRVVIntrinsicDecl(LR, II, PP, Itr->second,
488 /*IsOverload*/ false);
489 return true;
490 }
491
492 // It's not an RVV intrinsics.
493 return false;
494}
495
496namespace clang {
497std::unique_ptr<clang::sema::RISCVIntrinsicManager>
499 return std::make_unique<RISCVIntrinsicManagerImpl>(S);
500}
501
502bool SemaRISCV::CheckLMUL(CallExpr *TheCall, unsigned ArgNum) {
503 llvm::APSInt Result;
504
505 // We can't check the value of a dependent argument.
506 Expr *Arg = TheCall->getArg(ArgNum);
507 if (Arg->isTypeDependent() || Arg->isValueDependent())
508 return false;
509
510 // Check constant-ness first.
511 if (SemaRef.BuiltinConstantArg(TheCall, ArgNum, Result))
512 return true;
513
514 int64_t Val = Result.getSExtValue();
515 if ((Val >= 0 && Val <= 3) || (Val >= 5 && Val <= 7))
516 return false;
517
518 return Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_invalid_lmul)
519 << Arg->getSourceRange();
520}
521
523 llvm::StringMap<bool> &FunctionFeatureMap,
524 CallExpr *TheCall, Sema &S, QualType Type,
525 int EGW) {
526 assert((EGW == 128 || EGW == 256) && "EGW can only be 128 or 256 bits");
527
528 // LMUL * VLEN >= EGW
531 unsigned ElemSize = S.Context.getTypeSize(Info.ElementType);
532 unsigned MinElemCount = Info.EC.getKnownMinValue();
533
534 unsigned EGS = EGW / ElemSize;
535 // If EGS is less than or equal to the minimum number of elements, then the
536 // type is valid.
537 if (EGS <= MinElemCount)
538 return false;
539
540 // Otherwise, we need vscale to be at least EGS / MinElemCont.
541 assert(EGS % MinElemCount == 0);
542 unsigned VScaleFactor = EGS / MinElemCount;
543 // Vscale is VLEN/RVVBitsPerBlock.
544 unsigned MinRequiredVLEN = VScaleFactor * llvm::RISCV::RVVBitsPerBlock;
545 std::string RequiredExt = "zvl" + std::to_string(MinRequiredVLEN) + "b";
546 if (!TI.hasFeature(RequiredExt) && !FunctionFeatureMap.lookup(RequiredExt))
547 return S.Diag(TheCall->getBeginLoc(),
548 diag::err_riscv_type_requires_extension)
549 << Type << RequiredExt;
550
551 return false;
552}
553
555 unsigned BuiltinID,
556 CallExpr *TheCall) {
557 ASTContext &Context = getASTContext();
559 llvm::StringMap<bool> FunctionFeatureMap;
560 Context.getFunctionFeatureMap(FunctionFeatureMap, FD);
561
562 if (const auto *A = TheCall->getCalleeDecl()->getAttr<TargetAttr>()) {
563 StringRef FeaturesStr = A->getFeaturesStr();
564 llvm::SmallVector<StringRef> RequiredFeatures;
565 FeaturesStr.split(RequiredFeatures, ',');
566 for (auto RF : RequiredFeatures)
567 if (!TI.hasFeature(RF) && !FunctionFeatureMap.lookup(RF))
568 return Diag(TheCall->getBeginLoc(),
569 diag::err_riscv_builtin_requires_extension)
570 << /* IsExtension */ true << TheCall->getSourceRange() << RF;
571 }
572
573 // vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx,
574 // vsmul.vv, vsmul.vx are not included for EEW=64 in Zve64*.
575 switch (BuiltinID) {
576 default:
577 break;
578 case RISCVVector::BI__builtin_rvv_vmulhsu_vv:
579 case RISCVVector::BI__builtin_rvv_vmulhsu_vx:
580 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tu:
581 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tu:
582 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_m:
583 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_m:
584 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_mu:
585 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_mu:
586 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tum:
587 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tum:
588 case RISCVVector::BI__builtin_rvv_vmulhsu_vv_tumu:
589 case RISCVVector::BI__builtin_rvv_vmulhsu_vx_tumu:
590 case RISCVVector::BI__builtin_rvv_vmulhu_vv:
591 case RISCVVector::BI__builtin_rvv_vmulhu_vx:
592 case RISCVVector::BI__builtin_rvv_vmulhu_vv_tu:
593 case RISCVVector::BI__builtin_rvv_vmulhu_vx_tu:
594 case RISCVVector::BI__builtin_rvv_vmulhu_vv_m:
595 case RISCVVector::BI__builtin_rvv_vmulhu_vx_m:
596 case RISCVVector::BI__builtin_rvv_vmulhu_vv_mu:
597 case RISCVVector::BI__builtin_rvv_vmulhu_vx_mu:
598 case RISCVVector::BI__builtin_rvv_vmulhu_vv_tum:
599 case RISCVVector::BI__builtin_rvv_vmulhu_vx_tum:
600 case RISCVVector::BI__builtin_rvv_vmulhu_vv_tumu:
601 case RISCVVector::BI__builtin_rvv_vmulhu_vx_tumu:
602 case RISCVVector::BI__builtin_rvv_vmulh_vv:
603 case RISCVVector::BI__builtin_rvv_vmulh_vx:
604 case RISCVVector::BI__builtin_rvv_vmulh_vv_tu:
605 case RISCVVector::BI__builtin_rvv_vmulh_vx_tu:
606 case RISCVVector::BI__builtin_rvv_vmulh_vv_m:
607 case RISCVVector::BI__builtin_rvv_vmulh_vx_m:
608 case RISCVVector::BI__builtin_rvv_vmulh_vv_mu:
609 case RISCVVector::BI__builtin_rvv_vmulh_vx_mu:
610 case RISCVVector::BI__builtin_rvv_vmulh_vv_tum:
611 case RISCVVector::BI__builtin_rvv_vmulh_vx_tum:
612 case RISCVVector::BI__builtin_rvv_vmulh_vv_tumu:
613 case RISCVVector::BI__builtin_rvv_vmulh_vx_tumu:
614 case RISCVVector::BI__builtin_rvv_vsmul_vv:
615 case RISCVVector::BI__builtin_rvv_vsmul_vx:
616 case RISCVVector::BI__builtin_rvv_vsmul_vv_tu:
617 case RISCVVector::BI__builtin_rvv_vsmul_vx_tu:
618 case RISCVVector::BI__builtin_rvv_vsmul_vv_m:
619 case RISCVVector::BI__builtin_rvv_vsmul_vx_m:
620 case RISCVVector::BI__builtin_rvv_vsmul_vv_mu:
621 case RISCVVector::BI__builtin_rvv_vsmul_vx_mu:
622 case RISCVVector::BI__builtin_rvv_vsmul_vv_tum:
623 case RISCVVector::BI__builtin_rvv_vsmul_vx_tum:
624 case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu:
625 case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu: {
627 TheCall->getType()->castAs<BuiltinType>());
628
629 if (Context.getTypeSize(Info.ElementType) == 64 && !TI.hasFeature("v") &&
630 !FunctionFeatureMap.lookup("v"))
631 return Diag(TheCall->getBeginLoc(),
632 diag::err_riscv_builtin_requires_extension)
633 << /* IsExtension */ true << TheCall->getSourceRange() << "v";
634
635 break;
636 }
637 }
638
639 auto CheckVSetVL = [&](unsigned SEWOffset, unsigned LMULOffset) -> bool {
641 llvm::StringMap<bool> FunctionFeatureMap;
642 Context.getFunctionFeatureMap(FunctionFeatureMap, FD);
643 llvm::APSInt SEWResult;
644 llvm::APSInt LMULResult;
645 if (SemaRef.BuiltinConstantArg(TheCall, SEWOffset, SEWResult) ||
646 SemaRef.BuiltinConstantArg(TheCall, LMULOffset, LMULResult))
647 return true;
648 int SEWValue = SEWResult.getSExtValue();
649 int LMULValue = LMULResult.getSExtValue();
650 if (((SEWValue == 0 && LMULValue == 5) || // e8mf8
651 (SEWValue == 1 && LMULValue == 6) || // e16mf4
652 (SEWValue == 2 && LMULValue == 7) || // e32mf2
653 SEWValue == 3) && // e64
654 !TI.hasFeature("zve64x") &&
655 !FunctionFeatureMap.lookup("zve64x"))
656 return Diag(TheCall->getBeginLoc(),
657 diag::err_riscv_builtin_requires_extension)
658 << /* IsExtension */ true << TheCall->getSourceRange() << "zve64x";
659 return SemaRef.BuiltinConstantArgRange(TheCall, SEWOffset, 0, 3) ||
660 CheckLMUL(TheCall, LMULOffset);
661 };
662 switch (BuiltinID) {
663 case RISCVVector::BI__builtin_rvv_vsetvli:
664 return CheckVSetVL(1, 2);
665 case RISCVVector::BI__builtin_rvv_vsetvlimax:
666 return CheckVSetVL(0, 1);
667 case RISCVVector::BI__builtin_rvv_vget_v: {
669 Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(
670 TheCall->getType().getCanonicalType().getTypePtr()));
672 Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(
673 TheCall->getArg(0)->getType().getCanonicalType().getTypePtr()));
674 unsigned MaxIndex;
675 if (VecInfo.NumVectors != 1) // vget for tuple type
676 MaxIndex = VecInfo.NumVectors;
677 else // vget for non-tuple type
678 MaxIndex = (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors) /
679 (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors);
680 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1);
681 }
682 case RISCVVector::BI__builtin_rvv_vset_v: {
684 Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(
685 TheCall->getType().getCanonicalType().getTypePtr()));
687 Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(
688 TheCall->getArg(2)->getType().getCanonicalType().getTypePtr()));
689 unsigned MaxIndex;
690 if (ResVecInfo.NumVectors != 1) // vset for tuple type
691 MaxIndex = ResVecInfo.NumVectors;
692 else // vset fo non-tuple type
693 MaxIndex = (ResVecInfo.EC.getKnownMinValue() * ResVecInfo.NumVectors) /
694 (VecInfo.EC.getKnownMinValue() * VecInfo.NumVectors);
695 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, MaxIndex - 1);
696 }
697 // Vector Crypto
698 case RISCVVector::BI__builtin_rvv_vaeskf1_vi_tu:
699 case RISCVVector::BI__builtin_rvv_vaeskf2_vi_tu:
700 case RISCVVector::BI__builtin_rvv_vaeskf2_vi:
701 case RISCVVector::BI__builtin_rvv_vsm4k_vi_tu: {
702 QualType Arg0Type = TheCall->getArg(0)->getType();
703 QualType Arg1Type = TheCall->getArg(1)->getType();
704 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
705 Arg0Type, 128) ||
706 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
707 Arg1Type, 128) ||
708 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31);
709 }
710 case RISCVVector::BI__builtin_rvv_vsm3c_vi_tu:
711 case RISCVVector::BI__builtin_rvv_vsm3c_vi: {
712 QualType Arg0Type = TheCall->getArg(0)->getType();
713 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
714 Arg0Type, 256) ||
715 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31);
716 }
717 case RISCVVector::BI__builtin_rvv_vaeskf1_vi:
718 case RISCVVector::BI__builtin_rvv_vsm4k_vi: {
719 QualType Arg0Type = TheCall->getArg(0)->getType();
720 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
721 Arg0Type, 128) ||
722 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
723 }
724 case RISCVVector::BI__builtin_rvv_vaesdf_vv:
725 case RISCVVector::BI__builtin_rvv_vaesdf_vs:
726 case RISCVVector::BI__builtin_rvv_vaesdm_vv:
727 case RISCVVector::BI__builtin_rvv_vaesdm_vs:
728 case RISCVVector::BI__builtin_rvv_vaesef_vv:
729 case RISCVVector::BI__builtin_rvv_vaesef_vs:
730 case RISCVVector::BI__builtin_rvv_vaesem_vv:
731 case RISCVVector::BI__builtin_rvv_vaesem_vs:
732 case RISCVVector::BI__builtin_rvv_vaesz_vs:
733 case RISCVVector::BI__builtin_rvv_vsm4r_vv:
734 case RISCVVector::BI__builtin_rvv_vsm4r_vs:
735 case RISCVVector::BI__builtin_rvv_vaesdf_vv_tu:
736 case RISCVVector::BI__builtin_rvv_vaesdf_vs_tu:
737 case RISCVVector::BI__builtin_rvv_vaesdm_vv_tu:
738 case RISCVVector::BI__builtin_rvv_vaesdm_vs_tu:
739 case RISCVVector::BI__builtin_rvv_vaesef_vv_tu:
740 case RISCVVector::BI__builtin_rvv_vaesef_vs_tu:
741 case RISCVVector::BI__builtin_rvv_vaesem_vv_tu:
742 case RISCVVector::BI__builtin_rvv_vaesem_vs_tu:
743 case RISCVVector::BI__builtin_rvv_vaesz_vs_tu:
744 case RISCVVector::BI__builtin_rvv_vsm4r_vv_tu:
745 case RISCVVector::BI__builtin_rvv_vsm4r_vs_tu: {
746 QualType Arg0Type = TheCall->getArg(0)->getType();
747 QualType Arg1Type = TheCall->getArg(1)->getType();
748 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
749 Arg0Type, 128) ||
750 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
751 Arg1Type, 128);
752 }
753 case RISCVVector::BI__builtin_rvv_vsha2ch_vv:
754 case RISCVVector::BI__builtin_rvv_vsha2cl_vv:
755 case RISCVVector::BI__builtin_rvv_vsha2ms_vv:
756 case RISCVVector::BI__builtin_rvv_vsha2ch_vv_tu:
757 case RISCVVector::BI__builtin_rvv_vsha2cl_vv_tu:
758 case RISCVVector::BI__builtin_rvv_vsha2ms_vv_tu: {
759 QualType Arg0Type = TheCall->getArg(0)->getType();
760 QualType Arg1Type = TheCall->getArg(1)->getType();
761 QualType Arg2Type = TheCall->getArg(2)->getType();
763 Context.getBuiltinVectorTypeInfo(Arg0Type->castAs<BuiltinType>());
764 uint64_t ElemSize = Context.getTypeSize(Info.ElementType);
765 if (ElemSize == 64 && !TI.hasFeature("zvknhb") &&
766 !FunctionFeatureMap.lookup("zvknhb"))
767 return Diag(TheCall->getBeginLoc(),
768 diag::err_riscv_builtin_requires_extension)
769 << /* IsExtension */ true << TheCall->getSourceRange() << "zvknhb";
770 // If ElemSize is 32, check at least zvknha or zvknhb is enabled.
771 if (!TI.hasFeature("zvknha") && !FunctionFeatureMap.lookup("zvknha") &&
772 !TI.hasFeature("zvknhb") && !FunctionFeatureMap.lookup("zvknhb"))
773 return Diag(TheCall->getBeginLoc(),
774 diag::err_riscv_builtin_requires_extension)
775 << /* IsExtension */ true << TheCall->getSourceRange()
776 << "zvknha or zvknhb";
777
778 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
779 Arg0Type, ElemSize * 4) ||
780 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
781 Arg1Type, ElemSize * 4) ||
782 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, SemaRef,
783 Arg2Type, ElemSize * 4);
784 }
785
786 case RISCVVector::BI__builtin_rvv_sf_vc_i_se:
787 // bit_27_26, bit_24_20, bit_11_7, simm5, sew, log2lmul
788 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
789 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) ||
790 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) ||
791 SemaRef.BuiltinConstantArgRange(TheCall, 3, -16, 15) ||
792 CheckLMUL(TheCall, 5);
793 case RISCVVector::BI__builtin_rvv_sf_vc_iv_se:
794 // bit_27_26, bit_11_7, vs2, simm5
795 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
796 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) ||
797 SemaRef.BuiltinConstantArgRange(TheCall, 3, -16, 15);
798 case RISCVVector::BI__builtin_rvv_sf_vc_v_i:
799 case RISCVVector::BI__builtin_rvv_sf_vc_v_i_se:
800 // bit_27_26, bit_24_20, simm5
801 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
802 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) ||
803 SemaRef.BuiltinConstantArgRange(TheCall, 2, -16, 15);
804 case RISCVVector::BI__builtin_rvv_sf_vc_v_iv:
805 case RISCVVector::BI__builtin_rvv_sf_vc_v_iv_se:
806 // bit_27_26, vs2, simm5
807 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
808 SemaRef.BuiltinConstantArgRange(TheCall, 2, -16, 15);
809 case RISCVVector::BI__builtin_rvv_sf_vc_ivv_se:
810 case RISCVVector::BI__builtin_rvv_sf_vc_ivw_se:
811 case RISCVVector::BI__builtin_rvv_sf_vc_v_ivv:
812 case RISCVVector::BI__builtin_rvv_sf_vc_v_ivw:
813 case RISCVVector::BI__builtin_rvv_sf_vc_v_ivv_se:
814 case RISCVVector::BI__builtin_rvv_sf_vc_v_ivw_se:
815 // bit_27_26, vd, vs2, simm5
816 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
817 SemaRef.BuiltinConstantArgRange(TheCall, 3, -16, 15);
818 case RISCVVector::BI__builtin_rvv_sf_vc_x_se:
819 // bit_27_26, bit_24_20, bit_11_7, xs1, sew, log2lmul
820 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
821 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31) ||
822 SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 31) ||
823 CheckLMUL(TheCall, 5);
824 case RISCVVector::BI__builtin_rvv_sf_vc_xv_se:
825 case RISCVVector::BI__builtin_rvv_sf_vc_vv_se:
826 // bit_27_26, bit_11_7, vs2, xs1/vs1
827 case RISCVVector::BI__builtin_rvv_sf_vc_v_x:
828 case RISCVVector::BI__builtin_rvv_sf_vc_v_x_se:
829 // bit_27_26, bit_24-20, xs1
830 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3) ||
831 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
832 case RISCVVector::BI__builtin_rvv_sf_vc_vvv_se:
833 case RISCVVector::BI__builtin_rvv_sf_vc_xvv_se:
834 case RISCVVector::BI__builtin_rvv_sf_vc_vvw_se:
835 case RISCVVector::BI__builtin_rvv_sf_vc_xvw_se:
836 // bit_27_26, vd, vs2, xs1
837 case RISCVVector::BI__builtin_rvv_sf_vc_v_xv:
838 case RISCVVector::BI__builtin_rvv_sf_vc_v_vv:
839 case RISCVVector::BI__builtin_rvv_sf_vc_v_xv_se:
840 case RISCVVector::BI__builtin_rvv_sf_vc_v_vv_se:
841 // bit_27_26, vs2, xs1/vs1
842 case RISCVVector::BI__builtin_rvv_sf_vc_v_xvv:
843 case RISCVVector::BI__builtin_rvv_sf_vc_v_vvv:
844 case RISCVVector::BI__builtin_rvv_sf_vc_v_xvw:
845 case RISCVVector::BI__builtin_rvv_sf_vc_v_vvw:
846 case RISCVVector::BI__builtin_rvv_sf_vc_v_xvv_se:
847 case RISCVVector::BI__builtin_rvv_sf_vc_v_vvv_se:
848 case RISCVVector::BI__builtin_rvv_sf_vc_v_xvw_se:
849 case RISCVVector::BI__builtin_rvv_sf_vc_v_vvw_se:
850 // bit_27_26, vd, vs2, xs1/vs1
851 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 3);
852 case RISCVVector::BI__builtin_rvv_sf_vc_fv_se:
853 // bit_26, bit_11_7, vs2, fs1
854 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1) ||
855 SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 31);
856 case RISCVVector::BI__builtin_rvv_sf_vc_fvv_se:
857 case RISCVVector::BI__builtin_rvv_sf_vc_fvw_se:
858 case RISCVVector::BI__builtin_rvv_sf_vc_v_fvv:
859 case RISCVVector::BI__builtin_rvv_sf_vc_v_fvw:
860 case RISCVVector::BI__builtin_rvv_sf_vc_v_fvv_se:
861 case RISCVVector::BI__builtin_rvv_sf_vc_v_fvw_se:
862 // bit_26, vd, vs2, fs1
863 case RISCVVector::BI__builtin_rvv_sf_vc_v_fv:
864 case RISCVVector::BI__builtin_rvv_sf_vc_v_fv_se:
865 // bit_26, vs2, fs1
866 return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 1);
867 // Check if byteselect is in [0, 3]
868 case RISCV::BI__builtin_riscv_aes32dsi:
869 case RISCV::BI__builtin_riscv_aes32dsmi:
870 case RISCV::BI__builtin_riscv_aes32esi:
871 case RISCV::BI__builtin_riscv_aes32esmi:
872 case RISCV::BI__builtin_riscv_sm4ks:
873 case RISCV::BI__builtin_riscv_sm4ed:
874 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3);
875 // Check if rnum is in [0, 10]
876 case RISCV::BI__builtin_riscv_aes64ks1i:
877 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 10);
878 // Check if value range for vxrm is in [0, 3]
879 case RISCVVector::BI__builtin_rvv_vaaddu_vv:
880 case RISCVVector::BI__builtin_rvv_vaaddu_vx:
881 case RISCVVector::BI__builtin_rvv_vaadd_vv:
882 case RISCVVector::BI__builtin_rvv_vaadd_vx:
883 case RISCVVector::BI__builtin_rvv_vasubu_vv:
884 case RISCVVector::BI__builtin_rvv_vasubu_vx:
885 case RISCVVector::BI__builtin_rvv_vasub_vv:
886 case RISCVVector::BI__builtin_rvv_vasub_vx:
887 case RISCVVector::BI__builtin_rvv_vsmul_vv:
888 case RISCVVector::BI__builtin_rvv_vsmul_vx:
889 case RISCVVector::BI__builtin_rvv_vssra_vv:
890 case RISCVVector::BI__builtin_rvv_vssra_vx:
891 case RISCVVector::BI__builtin_rvv_vssrl_vv:
892 case RISCVVector::BI__builtin_rvv_vssrl_vx:
893 case RISCVVector::BI__builtin_rvv_vnclip_wv:
894 case RISCVVector::BI__builtin_rvv_vnclip_wx:
895 case RISCVVector::BI__builtin_rvv_vnclipu_wv:
896 case RISCVVector::BI__builtin_rvv_vnclipu_wx:
897 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 3);
898 case RISCVVector::BI__builtin_rvv_vaaddu_vv_tu:
899 case RISCVVector::BI__builtin_rvv_vaaddu_vx_tu:
900 case RISCVVector::BI__builtin_rvv_vaadd_vv_tu:
901 case RISCVVector::BI__builtin_rvv_vaadd_vx_tu:
902 case RISCVVector::BI__builtin_rvv_vasubu_vv_tu:
903 case RISCVVector::BI__builtin_rvv_vasubu_vx_tu:
904 case RISCVVector::BI__builtin_rvv_vasub_vv_tu:
905 case RISCVVector::BI__builtin_rvv_vasub_vx_tu:
906 case RISCVVector::BI__builtin_rvv_vsmul_vv_tu:
907 case RISCVVector::BI__builtin_rvv_vsmul_vx_tu:
908 case RISCVVector::BI__builtin_rvv_vssra_vv_tu:
909 case RISCVVector::BI__builtin_rvv_vssra_vx_tu:
910 case RISCVVector::BI__builtin_rvv_vssrl_vv_tu:
911 case RISCVVector::BI__builtin_rvv_vssrl_vx_tu:
912 case RISCVVector::BI__builtin_rvv_vnclip_wv_tu:
913 case RISCVVector::BI__builtin_rvv_vnclip_wx_tu:
914 case RISCVVector::BI__builtin_rvv_vnclipu_wv_tu:
915 case RISCVVector::BI__builtin_rvv_vnclipu_wx_tu:
916 case RISCVVector::BI__builtin_rvv_vaaddu_vv_m:
917 case RISCVVector::BI__builtin_rvv_vaaddu_vx_m:
918 case RISCVVector::BI__builtin_rvv_vaadd_vv_m:
919 case RISCVVector::BI__builtin_rvv_vaadd_vx_m:
920 case RISCVVector::BI__builtin_rvv_vasubu_vv_m:
921 case RISCVVector::BI__builtin_rvv_vasubu_vx_m:
922 case RISCVVector::BI__builtin_rvv_vasub_vv_m:
923 case RISCVVector::BI__builtin_rvv_vasub_vx_m:
924 case RISCVVector::BI__builtin_rvv_vsmul_vv_m:
925 case RISCVVector::BI__builtin_rvv_vsmul_vx_m:
926 case RISCVVector::BI__builtin_rvv_vssra_vv_m:
927 case RISCVVector::BI__builtin_rvv_vssra_vx_m:
928 case RISCVVector::BI__builtin_rvv_vssrl_vv_m:
929 case RISCVVector::BI__builtin_rvv_vssrl_vx_m:
930 case RISCVVector::BI__builtin_rvv_vnclip_wv_m:
931 case RISCVVector::BI__builtin_rvv_vnclip_wx_m:
932 case RISCVVector::BI__builtin_rvv_vnclipu_wv_m:
933 case RISCVVector::BI__builtin_rvv_vnclipu_wx_m:
934 return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 3);
935 case RISCVVector::BI__builtin_rvv_vaaddu_vv_tum:
936 case RISCVVector::BI__builtin_rvv_vaaddu_vv_tumu:
937 case RISCVVector::BI__builtin_rvv_vaaddu_vv_mu:
938 case RISCVVector::BI__builtin_rvv_vaaddu_vx_tum:
939 case RISCVVector::BI__builtin_rvv_vaaddu_vx_tumu:
940 case RISCVVector::BI__builtin_rvv_vaaddu_vx_mu:
941 case RISCVVector::BI__builtin_rvv_vaadd_vv_tum:
942 case RISCVVector::BI__builtin_rvv_vaadd_vv_tumu:
943 case RISCVVector::BI__builtin_rvv_vaadd_vv_mu:
944 case RISCVVector::BI__builtin_rvv_vaadd_vx_tum:
945 case RISCVVector::BI__builtin_rvv_vaadd_vx_tumu:
946 case RISCVVector::BI__builtin_rvv_vaadd_vx_mu:
947 case RISCVVector::BI__builtin_rvv_vasubu_vv_tum:
948 case RISCVVector::BI__builtin_rvv_vasubu_vv_tumu:
949 case RISCVVector::BI__builtin_rvv_vasubu_vv_mu:
950 case RISCVVector::BI__builtin_rvv_vasubu_vx_tum:
951 case RISCVVector::BI__builtin_rvv_vasubu_vx_tumu:
952 case RISCVVector::BI__builtin_rvv_vasubu_vx_mu:
953 case RISCVVector::BI__builtin_rvv_vasub_vv_tum:
954 case RISCVVector::BI__builtin_rvv_vasub_vv_tumu:
955 case RISCVVector::BI__builtin_rvv_vasub_vv_mu:
956 case RISCVVector::BI__builtin_rvv_vasub_vx_tum:
957 case RISCVVector::BI__builtin_rvv_vasub_vx_tumu:
958 case RISCVVector::BI__builtin_rvv_vasub_vx_mu:
959 case RISCVVector::BI__builtin_rvv_vsmul_vv_mu:
960 case RISCVVector::BI__builtin_rvv_vsmul_vx_mu:
961 case RISCVVector::BI__builtin_rvv_vssra_vv_mu:
962 case RISCVVector::BI__builtin_rvv_vssra_vx_mu:
963 case RISCVVector::BI__builtin_rvv_vssrl_vv_mu:
964 case RISCVVector::BI__builtin_rvv_vssrl_vx_mu:
965 case RISCVVector::BI__builtin_rvv_vnclip_wv_mu:
966 case RISCVVector::BI__builtin_rvv_vnclip_wx_mu:
967 case RISCVVector::BI__builtin_rvv_vnclipu_wv_mu:
968 case RISCVVector::BI__builtin_rvv_vnclipu_wx_mu:
969 case RISCVVector::BI__builtin_rvv_vsmul_vv_tum:
970 case RISCVVector::BI__builtin_rvv_vsmul_vx_tum:
971 case RISCVVector::BI__builtin_rvv_vssra_vv_tum:
972 case RISCVVector::BI__builtin_rvv_vssra_vx_tum:
973 case RISCVVector::BI__builtin_rvv_vssrl_vv_tum:
974 case RISCVVector::BI__builtin_rvv_vssrl_vx_tum:
975 case RISCVVector::BI__builtin_rvv_vnclip_wv_tum:
976 case RISCVVector::BI__builtin_rvv_vnclip_wx_tum:
977 case RISCVVector::BI__builtin_rvv_vnclipu_wv_tum:
978 case RISCVVector::BI__builtin_rvv_vnclipu_wx_tum:
979 case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu:
980 case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu:
981 case RISCVVector::BI__builtin_rvv_vssra_vv_tumu:
982 case RISCVVector::BI__builtin_rvv_vssra_vx_tumu:
983 case RISCVVector::BI__builtin_rvv_vssrl_vv_tumu:
984 case RISCVVector::BI__builtin_rvv_vssrl_vx_tumu:
985 case RISCVVector::BI__builtin_rvv_vnclip_wv_tumu:
986 case RISCVVector::BI__builtin_rvv_vnclip_wx_tumu:
987 case RISCVVector::BI__builtin_rvv_vnclipu_wv_tumu:
988 case RISCVVector::BI__builtin_rvv_vnclipu_wx_tumu:
989 return SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 3);
990 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm:
991 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm:
992 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm:
993 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm:
994 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm:
995 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm:
996 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm:
997 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm:
998 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm:
999 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm:
1000 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm:
1001 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm:
1002 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm:
1003 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm:
1004 return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 4);
1005 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm:
1006 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm:
1007 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm:
1008 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm:
1009 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm:
1010 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm:
1011 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm:
1012 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm:
1013 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm:
1014 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm:
1015 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm:
1016 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm:
1017 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm:
1018 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm:
1019 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm:
1020 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm:
1021 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm:
1022 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm:
1023 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm:
1024 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm:
1025 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm:
1026 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm:
1027 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm:
1028 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm:
1029 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tu:
1030 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tu:
1031 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tu:
1032 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tu:
1033 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tu:
1034 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tu:
1035 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tu:
1036 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tu:
1037 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tu:
1038 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tu:
1039 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tu:
1040 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tu:
1041 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tu:
1042 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_tu:
1043 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_m:
1044 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_m:
1045 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_m:
1046 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_m:
1047 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_m:
1048 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_m:
1049 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_m:
1050 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_m:
1051 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_m:
1052 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_m:
1053 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_m:
1054 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_m:
1055 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_m:
1056 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_m:
1057 return SemaRef.BuiltinConstantArgRange(TheCall, 2, 0, 4);
1058 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tu:
1059 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tu:
1060 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tu:
1061 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tu:
1062 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tu:
1063 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tu:
1064 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tu:
1065 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tu:
1066 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tu:
1067 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tu:
1068 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tu:
1069 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tu:
1070 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tu:
1071 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tu:
1072 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tu:
1073 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tu:
1074 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tu:
1075 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tu:
1076 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tu:
1077 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tu:
1078 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tu:
1079 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tu:
1080 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tu:
1081 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tu:
1082 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm:
1083 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm:
1084 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm:
1085 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm:
1086 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm:
1087 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm:
1088 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm:
1089 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm:
1090 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm:
1091 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm:
1092 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm:
1093 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm:
1094 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm:
1095 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm:
1096 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm:
1097 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm:
1098 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm:
1099 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm:
1100 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm:
1101 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm:
1102 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm:
1103 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm:
1104 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm:
1105 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm:
1106 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm:
1107 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm:
1108 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tu:
1109 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tu:
1110 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tu:
1111 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tu:
1112 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tu:
1113 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tu:
1114 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tu:
1115 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tu:
1116 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tu:
1117 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tu:
1118 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tu:
1119 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tu:
1120 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tu:
1121 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tu:
1122 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tu:
1123 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tu:
1124 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tu:
1125 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tu:
1126 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tu:
1127 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tu:
1128 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tu:
1129 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tu:
1130 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tu:
1131 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tu:
1132 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_tu:
1133 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_tu:
1134 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_m:
1135 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_m:
1136 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_m:
1137 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_m:
1138 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_m:
1139 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_m:
1140 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_m:
1141 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_m:
1142 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_m:
1143 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_m:
1144 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_m:
1145 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_m:
1146 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_m:
1147 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_m:
1148 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_m:
1149 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_m:
1150 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_m:
1151 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_m:
1152 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_m:
1153 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_m:
1154 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_m:
1155 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_m:
1156 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_m:
1157 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_m:
1158 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tum:
1159 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tum:
1160 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tum:
1161 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tum:
1162 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tum:
1163 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tum:
1164 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tum:
1165 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tum:
1166 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tum:
1167 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tum:
1168 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tum:
1169 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tum:
1170 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tum:
1171 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_tum:
1172 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tumu:
1173 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tumu:
1174 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tumu:
1175 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tumu:
1176 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tumu:
1177 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tumu:
1178 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tumu:
1179 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tumu:
1180 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tumu:
1181 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tumu:
1182 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tumu:
1183 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tumu:
1184 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tumu:
1185 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_tumu:
1186 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_mu:
1187 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_mu:
1188 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_mu:
1189 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_mu:
1190 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_mu:
1191 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_mu:
1192 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_mu:
1193 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_mu:
1194 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_mu:
1195 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_mu:
1196 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_mu:
1197 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_mu:
1198 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_mu:
1199 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_mu:
1200 return SemaRef.BuiltinConstantArgRange(TheCall, 3, 0, 4);
1201 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_m:
1202 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_m:
1203 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_m:
1204 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_m:
1205 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_m:
1206 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_m:
1207 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_m:
1208 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_m:
1209 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_m:
1210 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_m:
1211 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_m:
1212 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_m:
1213 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_m:
1214 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_m:
1215 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_m:
1216 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_m:
1217 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_m:
1218 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_m:
1219 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_m:
1220 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_m:
1221 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_m:
1222 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_m:
1223 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_m:
1224 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_m:
1225 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_m:
1226 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_m:
1227 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tum:
1228 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tum:
1229 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tum:
1230 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tum:
1231 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tum:
1232 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tum:
1233 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tum:
1234 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tum:
1235 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tum:
1236 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tum:
1237 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tum:
1238 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tum:
1239 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tum:
1240 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tum:
1241 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tum:
1242 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tum:
1243 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tum:
1244 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tum:
1245 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tum:
1246 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tum:
1247 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tum:
1248 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tum:
1249 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tum:
1250 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tum:
1251 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tum:
1252 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tum:
1253 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tum:
1254 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tum:
1255 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tum:
1256 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tum:
1257 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tum:
1258 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tum:
1259 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tum:
1260 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tum:
1261 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tum:
1262 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tum:
1263 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tum:
1264 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tum:
1265 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tum:
1266 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tum:
1267 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tum:
1268 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tum:
1269 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tum:
1270 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tum:
1271 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_tum:
1272 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_tum:
1273 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tum:
1274 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tum:
1275 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tum:
1276 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tum:
1277 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tumu:
1278 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tumu:
1279 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tumu:
1280 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tumu:
1281 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tumu:
1282 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tumu:
1283 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tumu:
1284 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tumu:
1285 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tumu:
1286 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tumu:
1287 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tumu:
1288 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tumu:
1289 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tumu:
1290 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tumu:
1291 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tumu:
1292 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tumu:
1293 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tumu:
1294 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tumu:
1295 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tumu:
1296 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tumu:
1297 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tumu:
1298 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tumu:
1299 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tumu:
1300 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tumu:
1301 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tumu:
1302 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tumu:
1303 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tumu:
1304 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tumu:
1305 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tumu:
1306 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tumu:
1307 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tumu:
1308 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tumu:
1309 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tumu:
1310 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tumu:
1311 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tumu:
1312 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tumu:
1313 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tumu:
1314 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tumu:
1315 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tumu:
1316 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tumu:
1317 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tumu:
1318 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tumu:
1319 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tumu:
1320 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tumu:
1321 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_tumu:
1322 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_tumu:
1323 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_mu:
1324 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_mu:
1325 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_mu:
1326 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_mu:
1327 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_mu:
1328 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_mu:
1329 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_mu:
1330 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_mu:
1331 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_mu:
1332 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_mu:
1333 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_mu:
1334 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_mu:
1335 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_mu:
1336 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_mu:
1337 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_mu:
1338 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_mu:
1339 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_mu:
1340 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_mu:
1341 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_mu:
1342 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_mu:
1343 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_mu:
1344 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_mu:
1345 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_mu:
1346 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_mu:
1347 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_mu:
1348 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_mu:
1349 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_mu:
1350 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_mu:
1351 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_mu:
1352 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_mu:
1353 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_mu:
1354 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_mu:
1355 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_mu:
1356 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_mu:
1357 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_mu:
1358 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_mu:
1359 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_mu:
1360 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_mu:
1361 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_mu:
1362 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_mu:
1363 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_mu:
1364 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_mu:
1365 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_mu:
1366 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_mu:
1367 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_mu:
1368 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_mu:
1369 return SemaRef.BuiltinConstantArgRange(TheCall, 4, 0, 4);
1370 case RISCV::BI__builtin_riscv_ntl_load:
1371 case RISCV::BI__builtin_riscv_ntl_store:
1372 DeclRefExpr *DRE =
1373 cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
1374 assert((BuiltinID == RISCV::BI__builtin_riscv_ntl_store ||
1375 BuiltinID == RISCV::BI__builtin_riscv_ntl_load) &&
1376 "Unexpected RISC-V nontemporal load/store builtin!");
1377 bool IsStore = BuiltinID == RISCV::BI__builtin_riscv_ntl_store;
1378 unsigned NumArgs = IsStore ? 3 : 2;
1379
1380 if (SemaRef.checkArgCountAtLeast(TheCall, NumArgs - 1))
1381 return true;
1382
1383 if (SemaRef.checkArgCountAtMost(TheCall, NumArgs))
1384 return true;
1385
1386 // Domain value should be compile-time constant.
1387 // 2 <= domain <= 5
1388 if (TheCall->getNumArgs() == NumArgs &&
1389 SemaRef.BuiltinConstantArgRange(TheCall, NumArgs - 1, 2, 5))
1390 return true;
1391
1392 Expr *PointerArg = TheCall->getArg(0);
1393 ExprResult PointerArgResult =
1395
1396 if (PointerArgResult.isInvalid())
1397 return true;
1398 PointerArg = PointerArgResult.get();
1399
1400 const PointerType *PtrType = PointerArg->getType()->getAs<PointerType>();
1401 if (!PtrType) {
1402 Diag(DRE->getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
1403 << PointerArg->getType() << PointerArg->getSourceRange();
1404 return true;
1405 }
1406
1407 QualType ValType = PtrType->getPointeeType();
1408 ValType = ValType.getUnqualifiedType();
1409 if (!ValType->isIntegerType() && !ValType->isAnyPointerType() &&
1410 !ValType->isBlockPointerType() && !ValType->isFloatingType() &&
1411 !ValType->isVectorType() && !ValType->isRVVSizelessBuiltinType()) {
1412 Diag(DRE->getBeginLoc(),
1413 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
1414 << PointerArg->getType() << PointerArg->getSourceRange();
1415 return true;
1416 }
1417
1418 if (!IsStore) {
1419 TheCall->setType(ValType);
1420 return false;
1421 }
1422
1423 ExprResult ValArg = TheCall->getArg(1);
1425 Context, ValType, /*consume*/ false);
1426 ValArg =
1428 if (ValArg.isInvalid())
1429 return true;
1430
1431 TheCall->setArg(1, ValArg.get());
1432 TheCall->setType(Context.VoidTy);
1433 return false;
1434 }
1435
1436 return false;
1437}
1438
1440 const llvm::StringMap<bool> &FeatureMap) {
1443 unsigned EltSize = SemaRef.Context.getTypeSize(Info.ElementType);
1444 unsigned MinElts = Info.EC.getKnownMinValue();
1445
1446 if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Double) &&
1447 !FeatureMap.lookup("zve64d"))
1448 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64d";
1449 // (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at
1450 // least zve64x
1451 else if (((EltSize == 64 && Info.ElementType->isIntegerType()) ||
1452 MinElts == 1) &&
1453 !FeatureMap.lookup("zve64x"))
1454 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x";
1455 else if (Info.ElementType->isFloat16Type() && !FeatureMap.lookup("zvfh") &&
1456 !FeatureMap.lookup("zvfhmin") &&
1457 !FeatureMap.lookup("xandesvpackfph"))
1459 Diag(Loc, diag::err_riscv_type_requires_extension, D)
1460 << Ty << "zvfh, zvfhmin or xandesvpackfph";
1461 } else {
1462 Diag(Loc, diag::err_riscv_type_requires_extension, D)
1463 << Ty << "zvfh or zvfhmin";
1464 }
1465 else if (Info.ElementType->isBFloat16Type() &&
1466 !FeatureMap.lookup("zvfbfmin") &&
1467 !FeatureMap.lookup("xandesvbfhcvt"))
1469 Diag(Loc, diag::err_riscv_type_requires_extension, D)
1470 << Ty << "zvfbfmin or xandesvbfhcvt";
1471 } else {
1472 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin";
1473 }
1474 else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) &&
1475 !FeatureMap.lookup("zve32f"))
1476 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f";
1477 // Given that caller already checked isRVVType() before calling this function,
1478 // if we don't have at least zve32x supported, then we need to emit error.
1479 else if (!FeatureMap.lookup("zve32x"))
1480 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x";
1481}
1482
1483/// Are the two types RVV-bitcast-compatible types? I.e. is bitcasting from the
1484/// first RVV type (e.g. an RVV scalable type) to the second type (e.g. an RVV
1485/// VLS type) allowed?
1486///
1487/// This will also return false if the two given types do not make sense from
1488/// the perspective of RVV bitcasts.
1490 assert(srcTy->isVectorType() || destTy->isVectorType());
1491
1492 auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) {
1493 if (!FirstType->isRVVSizelessBuiltinType())
1494 return false;
1495
1496 const auto *VecTy = SecondType->getAs<VectorType>();
1497 return VecTy && VecTy->getVectorKind() == VectorKind::RVVFixedLengthData;
1498 };
1499
1500 return ValidScalableConversion(srcTy, destTy) ||
1501 ValidScalableConversion(destTy, srcTy);
1502}
1503
1505 // Warn about repeated attributes.
1506 if (const auto *A = D->getAttr<RISCVInterruptAttr>()) {
1507 Diag(AL.getRange().getBegin(),
1508 diag::warn_riscv_repeated_interrupt_attribute);
1509 Diag(A->getLocation(), diag::note_riscv_repeated_interrupt_attribute);
1510 return;
1511 }
1512
1513 // Semantic checks for a function with the 'interrupt' attribute:
1514 // - Must be a function.
1515 // - Must have no parameters.
1516 // - Must have the 'void' return type.
1517 // - The attribute itself must have at most 2 arguments
1518 // - The attribute arguments must be string literals, and valid choices.
1519 // - The attribute arguments must be a valid combination
1520 // - The current target must support the right extensions for the combination.
1521
1522 if (D->getFunctionType() == nullptr) {
1523 Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
1525 return;
1526 }
1527
1529 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
1530 << /*RISC-V*/ 2 << /*interrupt*/ 0 << 0;
1531 return;
1532 }
1533
1534 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
1535 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
1536 << /*RISC-V*/ 2 << /*interrupt*/ 0 << 1;
1537 return;
1538 }
1539
1540 if (!AL.checkAtMostNumArgs(SemaRef, 2))
1541 return;
1542
1543 bool HasSiFiveCLICType = false;
1544 bool HasUnaryType = false;
1545
1546 SmallSet<RISCVInterruptAttr::InterruptType, 2> Types;
1547 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1548 RISCVInterruptAttr::InterruptType Type;
1549 StringRef TypeString;
1551
1552 if (!SemaRef.checkStringLiteralArgumentAttr(AL, ArgIndex, TypeString, &Loc))
1553 return;
1554
1555 if (!RISCVInterruptAttr::ConvertStrToInterruptType(TypeString, Type)) {
1556 std::string TypeLiteral = ("\"" + TypeString + "\"").str();
1557 Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
1558 << AL << TypeLiteral << Loc;
1559 return;
1560 }
1561
1562 switch (Type) {
1563 case RISCVInterruptAttr::machine:
1564 // "machine" could be combined with the SiFive CLIC types, or could be
1565 // just "machine".
1566 break;
1567 case RISCVInterruptAttr::SiFiveCLICPreemptible:
1568 case RISCVInterruptAttr::SiFiveCLICStackSwap:
1569 // SiFive-CLIC types can be combined with each other and "machine"
1570 HasSiFiveCLICType = true;
1571 break;
1572 case RISCVInterruptAttr::supervisor:
1573 case RISCVInterruptAttr::rnmi:
1574 case RISCVInterruptAttr::qcinest:
1575 case RISCVInterruptAttr::qcinonest:
1576 // "supervisor", "rnmi" and "qci-(no)nest" cannot be combined with any
1577 // other types
1578 HasUnaryType = true;
1579 break;
1580 }
1581
1582 Types.insert(Type);
1583 }
1584
1585 if (HasUnaryType && Types.size() > 1) {
1586 Diag(AL.getLoc(), diag::err_riscv_attribute_interrupt_invalid_combination);
1587 return;
1588 }
1589
1590 if (HasUnaryType && HasSiFiveCLICType) {
1591 Diag(AL.getLoc(), diag::err_riscv_attribute_interrupt_invalid_combination);
1592 return;
1593 }
1594
1595 // "machine" is the default, if nothing is specified.
1596 if (AL.getNumArgs() == 0)
1597 Types.insert(RISCVInterruptAttr::machine);
1598
1599 const TargetInfo &TI = getASTContext().getTargetInfo();
1600 llvm::StringMap<bool> FunctionFeatureMap;
1601 getASTContext().getFunctionFeatureMap(FunctionFeatureMap,
1602 dyn_cast<FunctionDecl>(D));
1603
1604 auto HasFeature = [&](StringRef FeatureName) -> bool {
1605 return TI.hasFeature(FeatureName) || FunctionFeatureMap.lookup(FeatureName);
1606 };
1607
1608 for (RISCVInterruptAttr::InterruptType Type : Types) {
1609 switch (Type) {
1610 // The QCI interrupt types require Xqciint
1611 case RISCVInterruptAttr::qcinest:
1612 case RISCVInterruptAttr::qcinonest: {
1613 if (!HasFeature("experimental-xqciint")) {
1614 Diag(AL.getLoc(),
1615 diag::err_riscv_attribute_interrupt_requires_extension)
1616 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Type) << "Xqciint";
1617 return;
1618 }
1619 } break;
1620 // The SiFive CLIC interrupt types require Xsfmclic
1621 case RISCVInterruptAttr::SiFiveCLICPreemptible:
1622 case RISCVInterruptAttr::SiFiveCLICStackSwap: {
1623 if (!HasFeature("experimental-xsfmclic")) {
1624 Diag(AL.getLoc(),
1625 diag::err_riscv_attribute_interrupt_requires_extension)
1626 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Type)
1627 << "XSfmclic";
1628 return;
1629 }
1630 } break;
1631 case RISCVInterruptAttr::rnmi: {
1632 if (!HasFeature("smrnmi")) {
1633 Diag(AL.getLoc(),
1634 diag::err_riscv_attribute_interrupt_requires_extension)
1635 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Type) << "Smrnmi";
1636 return;
1637 }
1638 } break;
1639 default:
1640 break;
1641 }
1642 }
1643
1645 Types.end());
1646
1647 D->addAttr(::new (getASTContext()) RISCVInterruptAttr(
1648 getASTContext(), AL, TypesVec.data(), TypesVec.size()));
1649}
1650
1651bool SemaRISCV::isAliasValid(unsigned BuiltinID, StringRef AliasName) {
1652 return BuiltinID >= RISCV::FirstRVVBuiltin &&
1653 BuiltinID <= RISCV::LastRVVBuiltin;
1654}
1655
1657 if (Ext.empty())
1658 return false;
1659
1660 if (!Ext.consume_front("+"))
1661 return false;
1662
1663 return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second;
1664}
1665
1666bool SemaRISCV::checkTargetVersionAttr(const StringRef Param,
1667 const SourceLocation Loc) {
1668 using namespace DiagAttrParams;
1669
1671 Param.split(AttrStrs, ';');
1672
1673 bool HasArch = false;
1674 bool HasPriority = false;
1675 bool HasDefault = false;
1676 bool DuplicateAttr = false;
1677 for (StringRef AttrStr : AttrStrs) {
1678 AttrStr = AttrStr.trim();
1679 // Only support arch=+ext,... syntax.
1680 if (AttrStr.starts_with("arch=+")) {
1681 DuplicateAttr = HasArch;
1682 HasArch = true;
1683 ParsedTargetAttr TargetAttr =
1685
1686 if (TargetAttr.Features.empty() ||
1687 llvm::any_of(TargetAttr.Features, [&](const StringRef Ext) {
1688 return !isValidFMVExtension(Ext);
1689 }))
1690 return Diag(Loc, diag::warn_unsupported_target_attribute)
1691 << Unsupported << None << AttrStr << TargetVersion;
1692 } else if (AttrStr == "default") {
1693 DuplicateAttr = HasDefault;
1694 HasDefault = true;
1695 } else if (AttrStr.consume_front("priority=")) {
1696 DuplicateAttr = HasPriority;
1697 HasPriority = true;
1698 unsigned Digit;
1699 if (AttrStr.getAsInteger(0, Digit))
1700 return Diag(Loc, diag::warn_unsupported_target_attribute)
1701 << Unsupported << None << AttrStr << TargetVersion;
1702 } else {
1703 return Diag(Loc, diag::warn_unsupported_target_attribute)
1704 << Unsupported << None << AttrStr << TargetVersion;
1705 }
1706 }
1707
1708 if (((HasPriority || HasArch) && HasDefault) || DuplicateAttr ||
1709 (HasPriority && !HasArch))
1710 return Diag(Loc, diag::warn_unsupported_target_attribute)
1711 << Unsupported << None << Param << TargetVersion;
1712
1713 return false;
1714}
1715
1718 SmallVectorImpl<SmallString<64>> &NewParams) {
1719 using namespace DiagAttrParams;
1720
1721 assert(Params.size() == Locs.size() &&
1722 "Mismatch between number of string parameters and locations");
1723
1724 bool HasDefault = false;
1725 for (unsigned I = 0, E = Params.size(); I < E; ++I) {
1726 const StringRef Param = Params[I].trim();
1727 const SourceLocation &Loc = Locs[I];
1728
1730 Param.split(AttrStrs, ';');
1731
1732 bool IsPriority = false;
1733 bool IsDefault = false;
1734 for (StringRef AttrStr : AttrStrs) {
1735 AttrStr = AttrStr.trim();
1736 // Only support arch=+ext,... syntax.
1737 if (AttrStr.starts_with("arch=+")) {
1738 ParsedTargetAttr TargetAttr =
1740
1741 if (TargetAttr.Features.empty() ||
1742 llvm::any_of(TargetAttr.Features, [&](const StringRef Ext) {
1743 return !isValidFMVExtension(Ext);
1744 }))
1745 return Diag(Loc, diag::warn_unsupported_target_attribute)
1746 << Unsupported << None << Param << TargetClones;
1747 } else if (AttrStr == "default") {
1748 IsDefault = true;
1749 HasDefault = true;
1750 } else if (AttrStr.consume_front("priority=")) {
1751 IsPriority = true;
1752 unsigned Digit;
1753 if (AttrStr.getAsInteger(0, Digit))
1754 return Diag(Loc, diag::warn_unsupported_target_attribute)
1755 << Unsupported << None << Param << TargetClones;
1756 } else {
1757 return Diag(Loc, diag::warn_unsupported_target_attribute)
1758 << Unsupported << None << Param << TargetClones;
1759 }
1760 }
1761
1762 if (IsPriority && IsDefault)
1763 return Diag(Loc, diag::warn_unsupported_target_attribute)
1764 << Unsupported << None << Param << TargetClones;
1765
1766 if (llvm::is_contained(NewParams, Param))
1767 Diag(Loc, diag::warn_target_clone_duplicate_options);
1768 NewParams.push_back(Param);
1769 }
1770 if (!HasDefault)
1771 return Diag(Locs[0], diag::err_target_clone_must_have_default);
1772
1773 return false;
1774}
1775
1777
1778} // namespace clang
Defines the clang::ASTContext interface.
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
Defines enum values for all the target-independent builtin functions.
const Decl * D
Expr * E
llvm::MachO::Record Record
Definition: MachO.h:31
static bool HasFeature(const Preprocessor &PP, StringRef Feature)
HasFeature - Return true if we recognize and implement the feature specified by the identifier as a s...
Defines the clang::Preprocessor interface.
SourceLocation Loc
Definition: SemaObjC.cpp:754
static const RVVIntrinsicRecord RVSiFiveVectorIntrinsicRecords[]
Definition: SemaRISCV.cpp:87
static const RVVIntrinsicRecord RVAndesVectorIntrinsicRecords[]
Definition: SemaRISCV.cpp:93
static const PrototypeDescriptor RVAndesVectorSignatureTable[]
Definition: SemaRISCV.cpp:75
static const RVVIntrinsicRecord RVVIntrinsicRecords[]
Definition: SemaRISCV.cpp:81
static const PrototypeDescriptor RVSiFiveVectorSignatureTable[]
Definition: SemaRISCV.cpp:69
static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type)
Definition: SemaRISCV.cpp:113
static ArrayRef< PrototypeDescriptor > ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length)
Definition: SemaRISCV.cpp:101
static const PrototypeDescriptor RVVSignatureTable[]
Definition: SemaRISCV.cpp:63
This file declares semantic analysis functions specific to RISC-V.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
BuiltinVectorTypeInfo getBuiltinVectorTypeInfo(const BuiltinType *VecTy) const
Returns the element type, element count and number of vectors (in case of tuple) for a builtin vector...
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1201
CanQualType LongTy
Definition: ASTContext.h:1231
QualType getScalableVectorType(QualType EltTy, unsigned NumElts, unsigned NumFields=1) const
Return the unique reference to a scalable vector type of the specified element type and scalable numb...
CanQualType FloatTy
Definition: ASTContext.h:1234
CanQualType DoubleTy
Definition: ASTContext.h:1234
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
Definition: ASTContext.h:1461
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
CanQualType BoolTy
Definition: ASTContext.h:1223
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...
CanQualType UnsignedLongTy
Definition: ASTContext.h:1232
CanQualType Float16Ty
Definition: ASTContext.h:1248
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2625
CanQualType VoidTy
Definition: ASTContext.h:1222
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1750
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:859
CanQualType BFloat16Ty
Definition: ASTContext.h:1247
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
PtrTy get() const
Definition: Ownership.h:171
bool isInvalid() const
Definition: Ownership.h:167
SourceLocation getLoc() const
This class is used for builtin types like 'int'.
Definition: TypeBase.h:3182
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2879
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition: Expr.h:3083
SourceLocation getBeginLoc() const
Definition: Expr.h:3213
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
Definition: Expr.h:3096
Expr * getCallee()
Definition: Expr.h:3026
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition: Expr.h:3070
Decl * getCalleeDecl()
Definition: Expr.h:3056
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1272
SourceLocation getBeginLoc() const
Definition: Expr.h:1351
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
T * getAttr() const
Definition: DeclBase.h:573
void addAttr(Attr *A)
Definition: DeclBase.cpp:1022
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
Definition: DeclBase.cpp:1199
SourceLocation getLocation() const
Definition: DeclBase.h:439
This represents one expression.
Definition: Expr.h:112
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3078
void setType(QualType t)
Definition: Expr.h:145
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:177
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:194
QualType getType() const
Definition: Expr.h:144
bool isFPConstrained() const
Definition: LangOptions.h:844
Represents a function declaration or definition.
Definition: Decl.h:1999
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
Definition: Decl.h:2188
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
Represents the results of name lookup.
Definition: Lookup.h:147
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access.
Definition: Lookup.h:475
void resolveKind()
Resolves the result kind of the lookup, possibly hiding decls.
Definition: SemaLookup.cpp:488
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:666
Represents a parameter to a function.
Definition: Decl.h:1789
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1822
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2946
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:119
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:371
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
Definition: ParsedAttr.cpp:298
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
QualType getPointeeType() const
Definition: TypeBase.h:3356
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:145
IdentifierTable & getIdentifierTable()
A (possibly-)qualified type.
Definition: TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: TypeBase.h:8343
QualType getCanonicalType() const
Definition: TypeBase.h:8395
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: TypeBase.h:8437
static llvm::SmallVector< Policy > getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy)
static llvm::SmallVector< PrototypeDescriptor > computeBuiltinTypes(llvm::ArrayRef< PrototypeDescriptor > Prototype, bool IsMasked, bool HasMaskedOffOperand, bool HasVL, unsigned NF, PolicyScheme DefaultScheme, Policy PolicyAttrs, bool IsTuple)
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy, std::string &Name, std::string &BuiltinName, std::string &OverloadedName, Policy &PolicyAttrs, bool HasFRMRoundModeOp)
static std::string getSuffixStr(RVVTypeCache &TypeCache, BasicType Type, int Log2LMUL, llvm::ArrayRef< PrototypeDescriptor > PrototypeDescriptors)
static llvm::SmallVector< Policy > getSupportedUnMaskedPolicies()
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:61
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
Sema & SemaRef
Definition: SemaBase.h:40
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Definition: SemaRISCV.cpp:554
bool CheckLMUL(CallExpr *TheCall, unsigned ArgNum)
Definition: SemaRISCV.cpp:502
bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName)
Definition: SemaRISCV.cpp:1651
bool isValidFMVExtension(StringRef Ext)
Definition: SemaRISCV.cpp:1656
bool DeclareAndesVectorBuiltins
Indicate RISC-V Andes vector builtin functions enabled or not.
Definition: SemaRISCV.h:55
bool DeclareSiFiveVectorBuiltins
Indicate RISC-V SiFive vector builtin functions enabled or not.
Definition: SemaRISCV.h:52
SemaRISCV(Sema &S)
Definition: SemaRISCV.cpp:1776
void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D, const llvm::StringMap< bool > &FeatureMap)
Definition: SemaRISCV.cpp:1439
bool isValidRVVBitcast(QualType srcType, QualType destType)
Are the two types RVV-bitcast-compatible types? I.e.
Definition: SemaRISCV.cpp:1489
void handleInterruptAttr(Decl *D, const ParsedAttr &AL)
Definition: SemaRISCV.cpp:1504
bool checkTargetClonesAttr(SmallVectorImpl< StringRef > &Params, SmallVectorImpl< SourceLocation > &Locs, SmallVectorImpl< SmallString< 64 > > &NewParams)
Definition: SemaRISCV.cpp:1716
bool DeclareRVVBuiltins
Indicate RISC-V vector builtin functions enabled or not.
Definition: SemaRISCV.h:49
bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc)
Definition: SemaRISCV.cpp:1666
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:850
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
Definition: Sema.cpp:1647
ASTContext & Context
Definition: Sema.h:1276
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
Definition: SemaExpr.cpp:748
FPOptions & getCurFPFeatures()
Definition: Sema.h:913
SemaRISCV & RISCV()
Definition: Sema.h:1513
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
Definition: SemaInit.cpp:9874
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI, const Expr *E, StringRef &Str, SourceLocation *ArgLocation=nullptr)
Check if the argument E is a ASCII string literal.
Encodes a location in the source.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
Exposes information about the current target.
Definition: TargetInfo.h:226
virtual CallingConv getDefaultCallingConv() const
Gets the default calling convention for the given target.
Definition: TargetInfo.h:1719
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
Definition: TargetInfo.cpp:577
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
Definition: TargetInfo.h:1526
The base class of the type hierarchy.
Definition: TypeBase.h:1833
bool isBlockPointerType() const
Definition: TypeBase.h:8600
bool isFloat16Type() const
Definition: TypeBase.h:8945
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: TypeBase.h:8980
const T * castAs() const
Member-template castAs<specific type>.
Definition: TypeBase.h:9226
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
Definition: TypeBase.h:8905
bool isBFloat16Type() const
Definition: TypeBase.h:8957
bool isVectorType() const
Definition: TypeBase.h:8719
bool isRVVSizelessBuiltinType() const
Returns true for RVV scalable vector types.
Definition: Type.cpp:2599
bool isFloatingType() const
Definition: Type.cpp:2308
bool isAnyPointerType() const
Definition: TypeBase.h:8588
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
Represents a GCC generic vector type.
Definition: TypeBase.h:4191
VectorKind getVectorKind() const
Definition: TypeBase.h:4211
virtual bool CreateIntrinsicIfFound(LookupResult &LR, IdentifierInfo *II, Preprocessor &PP)=0
Defines the clang::TargetInfo interface.
RISCV builtins.
std::vector< RVVTypePtr > RVVTypes
The JSON file list parser is used to communicate input to InstallAPI.
@ ExpectedFunction
Definition: ParsedAttr.h:1075
QualType getFunctionOrMethodResultType(const Decl *D)
Definition: Attr.h:98
std::unique_ptr< sema::RISCVIntrinsicManager > CreateRISCVIntrinsicManager(Sema &S)
Definition: SemaRISCV.cpp:498
@ SC_Extern
Definition: Specifiers.h:251
@ SC_None
Definition: Specifiers.h:250
@ Result
The result type of a method or function.
static bool CheckInvalidVLENandLMUL(const TargetInfo &TI, llvm::StringMap< bool > &FunctionFeatureMap, CallExpr *TheCall, Sema &S, QualType Type, int EGW)
Definition: SemaRISCV.cpp:522
bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
Definition: Attr.h:55
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
Definition: Attr.h:64
@ RVVFixedLengthData
is RISC-V RVV fixed-length data vector
@ None
The alignment was not explicit in code.
unsigned int uint32_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
Extra information about a function prototype.
Definition: TypeBase.h:5367
Contains information gathered from parsing the contents of TargetAttr.
Definition: TargetInfo.h:60
std::vector< std::string > Features
Definition: TargetInfo.h:61