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