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