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