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