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