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 if rnum is in [0, 10]
972 case RISCV::BI__builtin_riscv_aes64ks1i:
973 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 10);
974 // Check if value range for vxrm is in [0, 3]
975 case RISCVVector::BI__builtin_rvv_vaaddu_vv:
976 case RISCVVector::BI__builtin_rvv_vaaddu_vx:
977 case RISCVVector::BI__builtin_rvv_vaadd_vv:
978 case RISCVVector::BI__builtin_rvv_vaadd_vx:
979 case RISCVVector::BI__builtin_rvv_vasubu_vv:
980 case RISCVVector::BI__builtin_rvv_vasubu_vx:
981 case RISCVVector::BI__builtin_rvv_vasub_vv:
982 case RISCVVector::BI__builtin_rvv_vasub_vx:
983 case RISCVVector::BI__builtin_rvv_vsmul_vv:
984 case RISCVVector::BI__builtin_rvv_vsmul_vx:
985 case RISCVVector::BI__builtin_rvv_vssra_vv:
986 case RISCVVector::BI__builtin_rvv_vssra_vx:
987 case RISCVVector::BI__builtin_rvv_vssrl_vv:
988 case RISCVVector::BI__builtin_rvv_vssrl_vx:
989 case RISCVVector::BI__builtin_rvv_vnclip_wv:
990 case RISCVVector::BI__builtin_rvv_vnclip_wx:
991 case RISCVVector::BI__builtin_rvv_vnclipu_wv:
992 case RISCVVector::BI__builtin_rvv_vnclipu_wx:
993 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 3);
994 case RISCVVector::BI__builtin_rvv_vaaddu_vv_tu:
995 case RISCVVector::BI__builtin_rvv_vaaddu_vx_tu:
996 case RISCVVector::BI__builtin_rvv_vaadd_vv_tu:
997 case RISCVVector::BI__builtin_rvv_vaadd_vx_tu:
998 case RISCVVector::BI__builtin_rvv_vasubu_vv_tu:
999 case RISCVVector::BI__builtin_rvv_vasubu_vx_tu:
1000 case RISCVVector::BI__builtin_rvv_vasub_vv_tu:
1001 case RISCVVector::BI__builtin_rvv_vasub_vx_tu:
1002 case RISCVVector::BI__builtin_rvv_vsmul_vv_tu:
1003 case RISCVVector::BI__builtin_rvv_vsmul_vx_tu:
1004 case RISCVVector::BI__builtin_rvv_vssra_vv_tu:
1005 case RISCVVector::BI__builtin_rvv_vssra_vx_tu:
1006 case RISCVVector::BI__builtin_rvv_vssrl_vv_tu:
1007 case RISCVVector::BI__builtin_rvv_vssrl_vx_tu:
1008 case RISCVVector::BI__builtin_rvv_vnclip_wv_tu:
1009 case RISCVVector::BI__builtin_rvv_vnclip_wx_tu:
1010 case RISCVVector::BI__builtin_rvv_vnclipu_wv_tu:
1011 case RISCVVector::BI__builtin_rvv_vnclipu_wx_tu:
1012 case RISCVVector::BI__builtin_rvv_vaaddu_vv_m:
1013 case RISCVVector::BI__builtin_rvv_vaaddu_vx_m:
1014 case RISCVVector::BI__builtin_rvv_vaadd_vv_m:
1015 case RISCVVector::BI__builtin_rvv_vaadd_vx_m:
1016 case RISCVVector::BI__builtin_rvv_vasubu_vv_m:
1017 case RISCVVector::BI__builtin_rvv_vasubu_vx_m:
1018 case RISCVVector::BI__builtin_rvv_vasub_vv_m:
1019 case RISCVVector::BI__builtin_rvv_vasub_vx_m:
1020 case RISCVVector::BI__builtin_rvv_vsmul_vv_m:
1021 case RISCVVector::BI__builtin_rvv_vsmul_vx_m:
1022 case RISCVVector::BI__builtin_rvv_vssra_vv_m:
1023 case RISCVVector::BI__builtin_rvv_vssra_vx_m:
1024 case RISCVVector::BI__builtin_rvv_vssrl_vv_m:
1025 case RISCVVector::BI__builtin_rvv_vssrl_vx_m:
1026 case RISCVVector::BI__builtin_rvv_vnclip_wv_m:
1027 case RISCVVector::BI__builtin_rvv_vnclip_wx_m:
1028 case RISCVVector::BI__builtin_rvv_vnclipu_wv_m:
1029 case RISCVVector::BI__builtin_rvv_vnclipu_wx_m:
1030 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 3, Low: 0, High: 3);
1031 case RISCVVector::BI__builtin_rvv_vaaddu_vv_tum:
1032 case RISCVVector::BI__builtin_rvv_vaaddu_vv_tumu:
1033 case RISCVVector::BI__builtin_rvv_vaaddu_vv_mu:
1034 case RISCVVector::BI__builtin_rvv_vaaddu_vx_tum:
1035 case RISCVVector::BI__builtin_rvv_vaaddu_vx_tumu:
1036 case RISCVVector::BI__builtin_rvv_vaaddu_vx_mu:
1037 case RISCVVector::BI__builtin_rvv_vaadd_vv_tum:
1038 case RISCVVector::BI__builtin_rvv_vaadd_vv_tumu:
1039 case RISCVVector::BI__builtin_rvv_vaadd_vv_mu:
1040 case RISCVVector::BI__builtin_rvv_vaadd_vx_tum:
1041 case RISCVVector::BI__builtin_rvv_vaadd_vx_tumu:
1042 case RISCVVector::BI__builtin_rvv_vaadd_vx_mu:
1043 case RISCVVector::BI__builtin_rvv_vasubu_vv_tum:
1044 case RISCVVector::BI__builtin_rvv_vasubu_vv_tumu:
1045 case RISCVVector::BI__builtin_rvv_vasubu_vv_mu:
1046 case RISCVVector::BI__builtin_rvv_vasubu_vx_tum:
1047 case RISCVVector::BI__builtin_rvv_vasubu_vx_tumu:
1048 case RISCVVector::BI__builtin_rvv_vasubu_vx_mu:
1049 case RISCVVector::BI__builtin_rvv_vasub_vv_tum:
1050 case RISCVVector::BI__builtin_rvv_vasub_vv_tumu:
1051 case RISCVVector::BI__builtin_rvv_vasub_vv_mu:
1052 case RISCVVector::BI__builtin_rvv_vasub_vx_tum:
1053 case RISCVVector::BI__builtin_rvv_vasub_vx_tumu:
1054 case RISCVVector::BI__builtin_rvv_vasub_vx_mu:
1055 case RISCVVector::BI__builtin_rvv_vsmul_vv_mu:
1056 case RISCVVector::BI__builtin_rvv_vsmul_vx_mu:
1057 case RISCVVector::BI__builtin_rvv_vssra_vv_mu:
1058 case RISCVVector::BI__builtin_rvv_vssra_vx_mu:
1059 case RISCVVector::BI__builtin_rvv_vssrl_vv_mu:
1060 case RISCVVector::BI__builtin_rvv_vssrl_vx_mu:
1061 case RISCVVector::BI__builtin_rvv_vnclip_wv_mu:
1062 case RISCVVector::BI__builtin_rvv_vnclip_wx_mu:
1063 case RISCVVector::BI__builtin_rvv_vnclipu_wv_mu:
1064 case RISCVVector::BI__builtin_rvv_vnclipu_wx_mu:
1065 case RISCVVector::BI__builtin_rvv_vsmul_vv_tum:
1066 case RISCVVector::BI__builtin_rvv_vsmul_vx_tum:
1067 case RISCVVector::BI__builtin_rvv_vssra_vv_tum:
1068 case RISCVVector::BI__builtin_rvv_vssra_vx_tum:
1069 case RISCVVector::BI__builtin_rvv_vssrl_vv_tum:
1070 case RISCVVector::BI__builtin_rvv_vssrl_vx_tum:
1071 case RISCVVector::BI__builtin_rvv_vnclip_wv_tum:
1072 case RISCVVector::BI__builtin_rvv_vnclip_wx_tum:
1073 case RISCVVector::BI__builtin_rvv_vnclipu_wv_tum:
1074 case RISCVVector::BI__builtin_rvv_vnclipu_wx_tum:
1075 case RISCVVector::BI__builtin_rvv_vsmul_vv_tumu:
1076 case RISCVVector::BI__builtin_rvv_vsmul_vx_tumu:
1077 case RISCVVector::BI__builtin_rvv_vssra_vv_tumu:
1078 case RISCVVector::BI__builtin_rvv_vssra_vx_tumu:
1079 case RISCVVector::BI__builtin_rvv_vssrl_vv_tumu:
1080 case RISCVVector::BI__builtin_rvv_vssrl_vx_tumu:
1081 case RISCVVector::BI__builtin_rvv_vnclip_wv_tumu:
1082 case RISCVVector::BI__builtin_rvv_vnclip_wx_tumu:
1083 case RISCVVector::BI__builtin_rvv_vnclipu_wv_tumu:
1084 case RISCVVector::BI__builtin_rvv_vnclipu_wx_tumu:
1085 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 4, Low: 0, High: 3);
1086 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm:
1087 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm:
1088 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm:
1089 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm:
1090 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm:
1091 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm:
1092 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm:
1093 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm:
1094 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm:
1095 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm:
1096 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm:
1097 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm:
1098 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm:
1099 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm:
1100 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 4);
1101 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm:
1102 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm:
1103 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm:
1104 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm:
1105 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm:
1106 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm:
1107 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm:
1108 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm:
1109 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm:
1110 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm:
1111 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm:
1112 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm:
1113 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm:
1114 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm:
1115 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm:
1116 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm:
1117 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm:
1118 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm:
1119 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm:
1120 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm:
1121 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm:
1122 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm:
1123 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm:
1124 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm:
1125 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_x_f_qf_rm:
1126 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_xu_f_qf_rm:
1127 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tu:
1128 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tu:
1129 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tu:
1130 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tu:
1131 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tu:
1132 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tu:
1133 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tu:
1134 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tu:
1135 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tu:
1136 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tu:
1137 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tu:
1138 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tu:
1139 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tu:
1140 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_tu:
1141 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_m:
1142 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_m:
1143 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_m:
1144 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_m:
1145 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_m:
1146 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_m:
1147 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_m:
1148 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_m:
1149 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_m:
1150 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_m:
1151 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_m:
1152 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_m:
1153 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_m:
1154 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_m:
1155 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 4);
1156 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tu:
1157 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tu:
1158 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tu:
1159 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tu:
1160 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tu:
1161 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tu:
1162 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tu:
1163 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tu:
1164 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tu:
1165 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tu:
1166 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tu:
1167 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tu:
1168 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tu:
1169 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tu:
1170 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tu:
1171 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tu:
1172 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tu:
1173 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tu:
1174 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tu:
1175 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tu:
1176 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tu:
1177 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tu:
1178 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tu:
1179 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tu:
1180 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm:
1181 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm:
1182 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm:
1183 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm:
1184 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm:
1185 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm:
1186 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm:
1187 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm:
1188 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm:
1189 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm:
1190 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm:
1191 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm:
1192 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm:
1193 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm:
1194 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm:
1195 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm:
1196 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm:
1197 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm:
1198 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm:
1199 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm:
1200 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm:
1201 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm:
1202 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm:
1203 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm:
1204 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm:
1205 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm:
1206 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tu:
1207 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tu:
1208 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tu:
1209 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tu:
1210 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tu:
1211 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tu:
1212 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tu:
1213 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tu:
1214 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tu:
1215 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tu:
1216 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tu:
1217 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tu:
1218 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tu:
1219 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tu:
1220 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tu:
1221 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tu:
1222 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tu:
1223 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tu:
1224 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tu:
1225 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tu:
1226 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tu:
1227 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tu:
1228 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tu:
1229 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tu:
1230 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_tu:
1231 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_tu:
1232 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_x_f_qf_rm_tu:
1233 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_xu_f_qf_rm_tu:
1234 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_m:
1235 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_m:
1236 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_m:
1237 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_m:
1238 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_m:
1239 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_m:
1240 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_m:
1241 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_m:
1242 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_m:
1243 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_m:
1244 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_m:
1245 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_m:
1246 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_m:
1247 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_m:
1248 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_m:
1249 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_m:
1250 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_m:
1251 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_m:
1252 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_m:
1253 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_m:
1254 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_m:
1255 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_m:
1256 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_m:
1257 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_m:
1258 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tum:
1259 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tum:
1260 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tum:
1261 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tum:
1262 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tum:
1263 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tum:
1264 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tum:
1265 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tum:
1266 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tum:
1267 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tum:
1268 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tum:
1269 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tum:
1270 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tum:
1271 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_tum:
1272 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_tumu:
1273 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_tumu:
1274 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_tumu:
1275 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_tumu:
1276 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_tumu:
1277 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_tumu:
1278 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_tumu:
1279 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_tumu:
1280 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_tumu:
1281 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_tumu:
1282 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_tumu:
1283 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_tumu:
1284 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_tumu:
1285 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_tumu:
1286 case RISCVVector::BI__builtin_rvv_vfsqrt_v_rm_mu:
1287 case RISCVVector::BI__builtin_rvv_vfrec7_v_rm_mu:
1288 case RISCVVector::BI__builtin_rvv_vfcvt_x_f_v_rm_mu:
1289 case RISCVVector::BI__builtin_rvv_vfcvt_xu_f_v_rm_mu:
1290 case RISCVVector::BI__builtin_rvv_vfcvt_f_x_v_rm_mu:
1291 case RISCVVector::BI__builtin_rvv_vfcvt_f_xu_v_rm_mu:
1292 case RISCVVector::BI__builtin_rvv_vfwcvt_x_f_v_rm_mu:
1293 case RISCVVector::BI__builtin_rvv_vfwcvt_xu_f_v_rm_mu:
1294 case RISCVVector::BI__builtin_rvv_vfncvt_x_f_w_rm_mu:
1295 case RISCVVector::BI__builtin_rvv_vfncvt_xu_f_w_rm_mu:
1296 case RISCVVector::BI__builtin_rvv_vfncvt_f_x_w_rm_mu:
1297 case RISCVVector::BI__builtin_rvv_vfncvt_f_xu_w_rm_mu:
1298 case RISCVVector::BI__builtin_rvv_vfncvt_f_f_w_rm_mu:
1299 case RISCVVector::BI__builtin_rvv_vfncvtbf16_f_f_w_rm_mu:
1300 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 3, Low: 0, High: 4);
1301 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_m:
1302 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_m:
1303 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_m:
1304 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_m:
1305 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_m:
1306 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_m:
1307 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_m:
1308 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_m:
1309 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_m:
1310 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_m:
1311 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_m:
1312 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_m:
1313 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_m:
1314 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_m:
1315 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_m:
1316 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_m:
1317 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_m:
1318 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_m:
1319 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_m:
1320 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_m:
1321 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_m:
1322 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_m:
1323 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_m:
1324 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_m:
1325 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_m:
1326 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_m:
1327 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tum:
1328 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tum:
1329 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tum:
1330 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tum:
1331 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tum:
1332 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tum:
1333 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tum:
1334 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tum:
1335 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tum:
1336 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tum:
1337 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tum:
1338 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tum:
1339 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tum:
1340 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tum:
1341 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tum:
1342 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tum:
1343 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tum:
1344 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tum:
1345 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tum:
1346 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tum:
1347 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tum:
1348 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tum:
1349 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tum:
1350 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tum:
1351 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tum:
1352 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tum:
1353 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tum:
1354 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tum:
1355 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tum:
1356 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tum:
1357 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tum:
1358 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tum:
1359 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tum:
1360 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tum:
1361 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tum:
1362 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tum:
1363 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tum:
1364 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tum:
1365 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tum:
1366 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tum:
1367 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tum:
1368 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tum:
1369 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tum:
1370 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tum:
1371 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_tum:
1372 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_tum:
1373 case RISCVVector::BI__builtin_rvv_vfredosum_vs_rm_tum:
1374 case RISCVVector::BI__builtin_rvv_vfredusum_vs_rm_tum:
1375 case RISCVVector::BI__builtin_rvv_vfwredosum_vs_rm_tum:
1376 case RISCVVector::BI__builtin_rvv_vfwredusum_vs_rm_tum:
1377 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_x_f_qf_rm_tum:
1378 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_xu_f_qf_rm_tum:
1379 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tumu:
1380 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tumu:
1381 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_tumu:
1382 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_tumu:
1383 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_tumu:
1384 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_tumu:
1385 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_tumu:
1386 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_tumu:
1387 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_tumu:
1388 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_tumu:
1389 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_tumu:
1390 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_tumu:
1391 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_tumu:
1392 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_tumu:
1393 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_tumu:
1394 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_tumu:
1395 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_tumu:
1396 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_tumu:
1397 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_tumu:
1398 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_tumu:
1399 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_tumu:
1400 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_tumu:
1401 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_tumu:
1402 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_tumu:
1403 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_tumu:
1404 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_tumu:
1405 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_tumu:
1406 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_tumu:
1407 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_tumu:
1408 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_tumu:
1409 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_tumu:
1410 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_tumu:
1411 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_tumu:
1412 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_tumu:
1413 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_tumu:
1414 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_tumu:
1415 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_tumu:
1416 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_tumu:
1417 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_tumu:
1418 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_tumu:
1419 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_tumu:
1420 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_tumu:
1421 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_tumu:
1422 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_tumu:
1423 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_tumu:
1424 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_tumu:
1425 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_x_f_qf_rm_tumu:
1426 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_xu_f_qf_rm_tumu:
1427 case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_mu:
1428 case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_mu:
1429 case RISCVVector::BI__builtin_rvv_vfsub_vv_rm_mu:
1430 case RISCVVector::BI__builtin_rvv_vfsub_vf_rm_mu:
1431 case RISCVVector::BI__builtin_rvv_vfrsub_vf_rm_mu:
1432 case RISCVVector::BI__builtin_rvv_vfwadd_vv_rm_mu:
1433 case RISCVVector::BI__builtin_rvv_vfwadd_vf_rm_mu:
1434 case RISCVVector::BI__builtin_rvv_vfwsub_vv_rm_mu:
1435 case RISCVVector::BI__builtin_rvv_vfwsub_vf_rm_mu:
1436 case RISCVVector::BI__builtin_rvv_vfwadd_wv_rm_mu:
1437 case RISCVVector::BI__builtin_rvv_vfwadd_wf_rm_mu:
1438 case RISCVVector::BI__builtin_rvv_vfwsub_wv_rm_mu:
1439 case RISCVVector::BI__builtin_rvv_vfwsub_wf_rm_mu:
1440 case RISCVVector::BI__builtin_rvv_vfmul_vv_rm_mu:
1441 case RISCVVector::BI__builtin_rvv_vfmul_vf_rm_mu:
1442 case RISCVVector::BI__builtin_rvv_vfdiv_vv_rm_mu:
1443 case RISCVVector::BI__builtin_rvv_vfdiv_vf_rm_mu:
1444 case RISCVVector::BI__builtin_rvv_vfrdiv_vf_rm_mu:
1445 case RISCVVector::BI__builtin_rvv_vfwmul_vv_rm_mu:
1446 case RISCVVector::BI__builtin_rvv_vfwmul_vf_rm_mu:
1447 case RISCVVector::BI__builtin_rvv_vfmacc_vv_rm_mu:
1448 case RISCVVector::BI__builtin_rvv_vfmacc_vf_rm_mu:
1449 case RISCVVector::BI__builtin_rvv_vfnmacc_vv_rm_mu:
1450 case RISCVVector::BI__builtin_rvv_vfnmacc_vf_rm_mu:
1451 case RISCVVector::BI__builtin_rvv_vfmsac_vv_rm_mu:
1452 case RISCVVector::BI__builtin_rvv_vfmsac_vf_rm_mu:
1453 case RISCVVector::BI__builtin_rvv_vfnmsac_vv_rm_mu:
1454 case RISCVVector::BI__builtin_rvv_vfnmsac_vf_rm_mu:
1455 case RISCVVector::BI__builtin_rvv_vfmadd_vv_rm_mu:
1456 case RISCVVector::BI__builtin_rvv_vfmadd_vf_rm_mu:
1457 case RISCVVector::BI__builtin_rvv_vfnmadd_vv_rm_mu:
1458 case RISCVVector::BI__builtin_rvv_vfnmadd_vf_rm_mu:
1459 case RISCVVector::BI__builtin_rvv_vfmsub_vv_rm_mu:
1460 case RISCVVector::BI__builtin_rvv_vfmsub_vf_rm_mu:
1461 case RISCVVector::BI__builtin_rvv_vfnmsub_vv_rm_mu:
1462 case RISCVVector::BI__builtin_rvv_vfnmsub_vf_rm_mu:
1463 case RISCVVector::BI__builtin_rvv_vfwmacc_vv_rm_mu:
1464 case RISCVVector::BI__builtin_rvv_vfwmacc_vf_rm_mu:
1465 case RISCVVector::BI__builtin_rvv_vfwnmacc_vv_rm_mu:
1466 case RISCVVector::BI__builtin_rvv_vfwnmacc_vf_rm_mu:
1467 case RISCVVector::BI__builtin_rvv_vfwmsac_vv_rm_mu:
1468 case RISCVVector::BI__builtin_rvv_vfwmsac_vf_rm_mu:
1469 case RISCVVector::BI__builtin_rvv_vfwnmsac_vv_rm_mu:
1470 case RISCVVector::BI__builtin_rvv_vfwnmsac_vf_rm_mu:
1471 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vv_rm_mu:
1472 case RISCVVector::BI__builtin_rvv_vfwmaccbf16_vf_rm_mu:
1473 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_x_f_qf_rm_mu:
1474 case RISCVVector::BI__builtin_rvv_sf_vfnrclip_xu_f_qf_rm_mu:
1475 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 4, Low: 0, High: 4);
1476 case RISCV::BI__builtin_riscv_ntl_load:
1477 case RISCV::BI__builtin_riscv_ntl_store:
1478 DeclRefExpr *DRE =
1479 cast<DeclRefExpr>(Val: TheCall->getCallee()->IgnoreParenCasts());
1480 assert((BuiltinID == RISCV::BI__builtin_riscv_ntl_store ||
1481 BuiltinID == RISCV::BI__builtin_riscv_ntl_load) &&
1482 "Unexpected RISC-V nontemporal load/store builtin!");
1483 bool IsStore = BuiltinID == RISCV::BI__builtin_riscv_ntl_store;
1484 unsigned NumArgs = IsStore ? 3 : 2;
1485
1486 if (SemaRef.checkArgCountAtLeast(Call: TheCall, MinArgCount: NumArgs - 1))
1487 return true;
1488
1489 if (SemaRef.checkArgCountAtMost(Call: TheCall, MaxArgCount: NumArgs))
1490 return true;
1491
1492 // Domain value should be compile-time constant.
1493 // 2 <= domain <= 5
1494 if (TheCall->getNumArgs() == NumArgs &&
1495 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: NumArgs - 1, Low: 2, High: 5))
1496 return true;
1497
1498 Expr *PointerArg = TheCall->getArg(Arg: 0);
1499 ExprResult PointerArgResult =
1500 SemaRef.DefaultFunctionArrayLvalueConversion(E: PointerArg);
1501
1502 if (PointerArgResult.isInvalid())
1503 return true;
1504 PointerArg = PointerArgResult.get();
1505
1506 const PointerType *PtrType = PointerArg->getType()->getAs<PointerType>();
1507 if (!PtrType) {
1508 Diag(Loc: DRE->getBeginLoc(), DiagID: diag::err_nontemporal_builtin_must_be_pointer)
1509 << PointerArg->getType() << PointerArg->getSourceRange();
1510 return true;
1511 }
1512
1513 QualType ValType = PtrType->getPointeeType();
1514 ValType = ValType.getUnqualifiedType();
1515 if (!ValType->isIntegerType() && !ValType->isAnyPointerType() &&
1516 !ValType->isBlockPointerType() && !ValType->isFloatingType() &&
1517 !ValType->isVectorType() && !ValType->isRVVSizelessBuiltinType()) {
1518 Diag(Loc: DRE->getBeginLoc(),
1519 DiagID: diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
1520 << PointerArg->getType() << PointerArg->getSourceRange();
1521 return true;
1522 }
1523
1524 if (!IsStore) {
1525 TheCall->setType(ValType);
1526 return false;
1527 }
1528
1529 ExprResult ValArg = TheCall->getArg(Arg: 1);
1530 InitializedEntity Entity = InitializedEntity::InitializeParameter(
1531 Context, Type: ValType, /*consume*/ Consumed: false);
1532 ValArg =
1533 SemaRef.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: ValArg);
1534 if (ValArg.isInvalid())
1535 return true;
1536
1537 TheCall->setArg(Arg: 1, ArgExpr: ValArg.get());
1538 TheCall->setType(Context.VoidTy);
1539 return false;
1540 }
1541
1542 return false;
1543}
1544
1545void SemaRISCV::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
1546 const llvm::StringMap<bool> &FeatureMap) {
1547 const BuiltinType *BT = Ty->castAs<BuiltinType>();
1548 ASTContext::BuiltinVectorTypeInfo Info =
1549 SemaRef.Context.getBuiltinVectorTypeInfo(VecTy: BT);
1550 unsigned EltSize = SemaRef.Context.getTypeSize(T: Info.ElementType);
1551 unsigned MinElts = Info.EC.getKnownMinValue();
1552
1553 auto IsOFP8Type = [](const BuiltinType *BT) {
1554 switch (BT->getKind()) {
1555#define RVV_VECTOR_TYPE_OFP8(Name, Id, SingletonId, NumEls, E5m2) \
1556 case BuiltinType::Id:
1557#include "clang/Basic/RISCVVTypes.def"
1558 return true;
1559 default:
1560 return false;
1561 }
1562 };
1563
1564 if (Info.ElementType->isSpecificBuiltinType(K: BuiltinType::Double) &&
1565 !FeatureMap.lookup(Key: "zve64d"))
1566 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension) << Ty << "zve64d";
1567 // (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at
1568 // least zve64x
1569 else if (((EltSize == 64 && Info.ElementType->isIntegerType()) ||
1570 MinElts == 1) &&
1571 !FeatureMap.lookup(Key: "zve64x"))
1572 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension) << Ty << "zve64x";
1573 else if (Info.ElementType->isFloat16Type() && !FeatureMap.lookup(Key: "zvfhmin") &&
1574 !FeatureMap.lookup(Key: "xandesvpackfph"))
1575 if (DeclareAndesVectorBuiltins) {
1576 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension)
1577 << Ty << "zvfh, zvfhmin or xandesvpackfph";
1578 } else {
1579 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension)
1580 << Ty << "zvfh or zvfhmin";
1581 }
1582 else if (Info.ElementType->isBFloat16Type() &&
1583 !FeatureMap.lookup(Key: "zvfbfmin") &&
1584 !FeatureMap.lookup(Key: "xandesvbfhcvt") &&
1585 !FeatureMap.lookup(Key: "experimental-zvfbfa"))
1586 if (DeclareAndesVectorBuiltins) {
1587 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension)
1588 << Ty << "zvfbfmin or xandesvbfhcvt";
1589 } else {
1590 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension) << Ty << "zvfbfmin";
1591 }
1592 else if (Info.ElementType->isSpecificBuiltinType(K: BuiltinType::Float) &&
1593 !FeatureMap.lookup(Key: "zve32f"))
1594 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension) << Ty << "zve32f";
1595 // Given that caller already checked isRVVType() before calling this function,
1596 // if we don't have at least zve32x supported, then we need to emit error.
1597 else if (!FeatureMap.lookup(Key: "zve32x"))
1598 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension) << Ty << "zve32x";
1599 else if (IsOFP8Type(BT) && !FeatureMap.lookup(Key: "experimental-zvfofp8min"))
1600 Diag(Loc, DiagID: diag::err_riscv_type_requires_extension) << Ty << "zvfofp8min";
1601}
1602
1603/// Are the two types RVV-bitcast-compatible types? I.e. is bitcasting from the
1604/// first RVV type (e.g. an RVV scalable type) to the second type (e.g. an RVV
1605/// VLS type) allowed?
1606///
1607/// This will also return false if the two given types do not make sense from
1608/// the perspective of RVV bitcasts.
1609bool SemaRISCV::isValidRVVBitcast(QualType srcTy, QualType destTy) {
1610 assert(srcTy->isVectorType() || destTy->isVectorType());
1611
1612 auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) {
1613 if (!FirstType->isRVVSizelessBuiltinType())
1614 return false;
1615
1616 const auto *VecTy = SecondType->getAs<VectorType>();
1617 return VecTy && VecTy->getVectorKind() == VectorKind::RVVFixedLengthData;
1618 };
1619
1620 return ValidScalableConversion(srcTy, destTy) ||
1621 ValidScalableConversion(destTy, srcTy);
1622}
1623
1624void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
1625 // Warn about repeated attributes.
1626 if (const auto *A = D->getAttr<RISCVInterruptAttr>()) {
1627 Diag(Loc: AL.getRange().getBegin(),
1628 DiagID: diag::warn_riscv_repeated_interrupt_attribute);
1629 Diag(Loc: A->getLocation(), DiagID: diag::note_riscv_repeated_interrupt_attribute);
1630 return;
1631 }
1632
1633 // Semantic checks for a function with the 'interrupt' attribute:
1634 // - Must be a function.
1635 // - Must have no parameters.
1636 // - Must have the 'void' return type.
1637 // - The attribute itself must have at most 3 arguments
1638 // - The attribute arguments must be string literals, and valid choices.
1639 // - The attribute arguments must be a valid combination
1640 // - The current target must support the right extensions for the combination.
1641
1642 if (D->getFunctionType() == nullptr) {
1643 Diag(Loc: D->getLocation(), DiagID: diag::warn_attribute_wrong_decl_type)
1644 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
1645 return;
1646 }
1647
1648 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
1649 Diag(Loc: D->getLocation(), DiagID: diag::warn_interrupt_signal_attribute_invalid)
1650 << /*RISC-V*/ 2 << /*interrupt*/ 0 << 0;
1651 return;
1652 }
1653
1654 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
1655 Diag(Loc: D->getLocation(), DiagID: diag::warn_interrupt_signal_attribute_invalid)
1656 << /*RISC-V*/ 2 << /*interrupt*/ 0 << 1;
1657 return;
1658 }
1659
1660 if (!AL.checkAtMostNumArgs(S&: SemaRef, Num: 3))
1661 return;
1662
1663 bool HasSiFiveCLICType = false;
1664 bool HasUnaryType = false;
1665 bool ReportedDuplicateType = false;
1666
1667 SmallSet<RISCVInterruptAttr::InterruptType, 3> Types;
1668 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1669 RISCVInterruptAttr::InterruptType Type;
1670 StringRef TypeString;
1671 SourceLocation Loc;
1672
1673 if (!SemaRef.checkStringLiteralArgumentAttr(Attr: AL, ArgNum: ArgIndex, Str&: TypeString, ArgLocation: &Loc))
1674 return;
1675
1676 if (!RISCVInterruptAttr::ConvertStrToInterruptType(Val: TypeString, Out&: Type)) {
1677 std::string TypeLiteral = ("\"" + TypeString + "\"").str();
1678 Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported)
1679 << AL << TypeLiteral << Loc;
1680 return;
1681 }
1682
1683 switch (Type) {
1684 case RISCVInterruptAttr::machine:
1685 // "machine" could be combined with the SiFive CLIC types, or could be
1686 // just "machine".
1687 break;
1688 case RISCVInterruptAttr::SiFiveCLICPreemptible:
1689 case RISCVInterruptAttr::SiFiveCLICStackSwap:
1690 // SiFive-CLIC types can be combined with each other and "machine"
1691 HasSiFiveCLICType = true;
1692 break;
1693 case RISCVInterruptAttr::supervisor:
1694 case RISCVInterruptAttr::rnmi:
1695 case RISCVInterruptAttr::qcinest:
1696 case RISCVInterruptAttr::qcinonest:
1697 // "supervisor", "rnmi" and "qci-(no)nest" cannot be combined with any
1698 // other types
1699 HasUnaryType = true;
1700 break;
1701 }
1702
1703 if (!Types.insert(V: Type).second && !ReportedDuplicateType) {
1704 Diag(Loc, DiagID: diag::warn_riscv_attribute_interrupt_duplicate_type)
1705 << TypeString;
1706 ReportedDuplicateType = true;
1707 }
1708 }
1709
1710 if (HasUnaryType && Types.size() > 1) {
1711 Diag(Loc: AL.getLoc(), DiagID: diag::err_riscv_attribute_interrupt_invalid_combination);
1712 return;
1713 }
1714
1715 if (HasUnaryType && HasSiFiveCLICType) {
1716 Diag(Loc: AL.getLoc(), DiagID: diag::err_riscv_attribute_interrupt_invalid_combination);
1717 return;
1718 }
1719
1720 // "machine" is the default, if nothing is specified.
1721 if (AL.getNumArgs() == 0)
1722 Types.insert(V: RISCVInterruptAttr::machine);
1723
1724 const TargetInfo &TI = getASTContext().getTargetInfo();
1725 llvm::StringMap<bool> FunctionFeatureMap;
1726 getASTContext().getFunctionFeatureMap(FeatureMap&: FunctionFeatureMap,
1727 dyn_cast<FunctionDecl>(Val: D));
1728
1729 auto HasFeature = [&](StringRef FeatureName) -> bool {
1730 return TI.hasFeature(Feature: FeatureName) || FunctionFeatureMap.lookup(Key: FeatureName);
1731 };
1732
1733 for (RISCVInterruptAttr::InterruptType Type : Types) {
1734 switch (Type) {
1735 // The QCI interrupt types require Xqciint
1736 case RISCVInterruptAttr::qcinest:
1737 case RISCVInterruptAttr::qcinonest: {
1738 if (!HasFeature("xqciint")) {
1739 Diag(Loc: AL.getLoc(),
1740 DiagID: diag::err_riscv_attribute_interrupt_requires_extension)
1741 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Val: Type) << "Xqciint";
1742 return;
1743 }
1744 } break;
1745 // The SiFive CLIC interrupt types require Xsfmclic
1746 case RISCVInterruptAttr::SiFiveCLICPreemptible:
1747 case RISCVInterruptAttr::SiFiveCLICStackSwap: {
1748 if (!HasFeature("experimental-xsfmclic")) {
1749 Diag(Loc: AL.getLoc(),
1750 DiagID: diag::err_riscv_attribute_interrupt_requires_extension)
1751 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Val: Type)
1752 << "XSfmclic";
1753 return;
1754 }
1755 } break;
1756 case RISCVInterruptAttr::rnmi: {
1757 if (!HasFeature("smrnmi")) {
1758 Diag(Loc: AL.getLoc(),
1759 DiagID: diag::err_riscv_attribute_interrupt_requires_extension)
1760 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Val: Type) << "Smrnmi";
1761 return;
1762 }
1763 } break;
1764 default:
1765 break;
1766 }
1767 }
1768
1769 SmallVector<RISCVInterruptAttr::InterruptType, 3> TypesVec(Types.begin(),
1770 Types.end());
1771
1772 D->addAttr(A: ::new (getASTContext()) RISCVInterruptAttr(
1773 getASTContext(), AL, TypesVec.data(), TypesVec.size()));
1774}
1775
1776bool SemaRISCV::isAliasValid(unsigned BuiltinID, StringRef AliasName) {
1777 return BuiltinID >= RISCV::FirstRVVBuiltin &&
1778 BuiltinID <= RISCV::LastRVVBuiltin;
1779}
1780
1781bool SemaRISCV::isValidFMVExtension(StringRef Ext) {
1782 if (Ext.empty())
1783 return false;
1784
1785 if (!Ext.consume_front(Prefix: "+"))
1786 return false;
1787
1788 return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second;
1789}
1790
1791bool SemaRISCV::checkTargetVersionAttr(const StringRef Param,
1792 const SourceLocation Loc,
1793 SmallString<64> &NewParam) {
1794 using namespace DiagAttrParams;
1795
1796 llvm::SmallVector<StringRef, 8> AttrStrs;
1797 Param.split(A&: AttrStrs, Separator: ';');
1798
1799 bool HasArch = false;
1800 bool HasPriority = false;
1801 bool HasDefault = false;
1802 bool DuplicateAttr = false;
1803 for (StringRef AttrStr : AttrStrs) {
1804 AttrStr = AttrStr.trim();
1805 // Only support arch=+ext,... syntax.
1806 if (AttrStr.starts_with(Prefix: "arch=+")) {
1807 DuplicateAttr = HasArch;
1808 HasArch = true;
1809 ParsedTargetAttr TargetAttr =
1810 getASTContext().getTargetInfo().parseTargetAttr(Str: AttrStr);
1811
1812 if (TargetAttr.Features.empty() ||
1813 llvm::any_of(Range&: TargetAttr.Features, P: [&](const StringRef Ext) {
1814 return !isValidFMVExtension(Ext);
1815 }))
1816 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1817 << Unsupported << None << AttrStr << TargetVersion;
1818 } else if (AttrStr == "default") {
1819 DuplicateAttr = HasDefault;
1820 HasDefault = true;
1821 } else if (AttrStr.consume_front(Prefix: "priority=")) {
1822 DuplicateAttr = HasPriority;
1823 HasPriority = true;
1824 unsigned Digit;
1825 if (AttrStr.getAsInteger(Radix: 0, Result&: Digit))
1826 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1827 << Unsupported << None << AttrStr << TargetVersion;
1828 } else {
1829 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1830 << Unsupported << None << AttrStr << TargetVersion;
1831 }
1832 }
1833
1834 if (((HasPriority || HasArch) && HasDefault) || DuplicateAttr ||
1835 (HasPriority && !HasArch))
1836 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1837 << Unsupported << None << Param << TargetVersion;
1838
1839 NewParam = Param;
1840 return false;
1841}
1842
1843bool SemaRISCV::checkTargetClonesAttr(
1844 const SmallVectorImpl<StringRef> &Params,
1845 const SmallVectorImpl<SourceLocation> &Locs,
1846 SmallVectorImpl<SmallString<64>> &NewParams, SourceLocation AttrLoc) {
1847 using namespace DiagAttrParams;
1848
1849 assert(Params.size() == Locs.size() &&
1850 "Mismatch between number of string parameters and locations");
1851
1852 bool HasDefault = false;
1853 for (unsigned I = 0, E = Params.size(); I < E; ++I) {
1854 const StringRef Param = Params[I].trim();
1855 const SourceLocation &Loc = Locs[I];
1856
1857 llvm::SmallVector<StringRef, 8> AttrStrs;
1858 Param.split(A&: AttrStrs, Separator: ';');
1859
1860 bool IsPriority = false;
1861 bool IsDefault = false;
1862 for (StringRef AttrStr : AttrStrs) {
1863 AttrStr = AttrStr.trim();
1864 // Only support arch=+ext,... syntax.
1865 if (AttrStr.starts_with(Prefix: "arch=+")) {
1866 ParsedTargetAttr TargetAttr =
1867 getASTContext().getTargetInfo().parseTargetAttr(Str: AttrStr);
1868
1869 if (TargetAttr.Features.empty() ||
1870 llvm::any_of(Range&: TargetAttr.Features, P: [&](const StringRef Ext) {
1871 return !isValidFMVExtension(Ext);
1872 }))
1873 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1874 << Unsupported << None << Param << TargetClones;
1875 } else if (AttrStr == "default") {
1876 IsDefault = true;
1877 HasDefault = true;
1878 } else if (AttrStr.consume_front(Prefix: "priority=")) {
1879 IsPriority = true;
1880 unsigned Digit;
1881 if (AttrStr.getAsInteger(Radix: 0, Result&: Digit))
1882 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1883 << Unsupported << None << Param << TargetClones;
1884 } else {
1885 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1886 << Unsupported << None << Param << TargetClones;
1887 }
1888 }
1889
1890 if (IsPriority && IsDefault)
1891 return Diag(Loc, DiagID: diag::warn_unsupported_target_attribute)
1892 << Unsupported << None << Param << TargetClones;
1893
1894 if (llvm::is_contained(Range&: NewParams, Element: Param))
1895 Diag(Loc, DiagID: diag::warn_target_clone_duplicate_options);
1896 NewParams.push_back(Elt: Param);
1897 }
1898 if (!HasDefault)
1899 return Diag(Loc: AttrLoc, DiagID: diag::err_target_clone_must_have_default);
1900
1901 return false;
1902}
1903
1904SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {}
1905
1906} // namespace clang
1907