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