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