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
36using namespace llvm;
37using namespace clang;
38using namespace clang::RISCV;
39
40using IntrinsicKind = sema::RISCVIntrinsicManager::IntrinsicKind;
41
42namespace {
43
44// Function definition of a RVV intrinsic.
45struct 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 std::string RequiredExtensions;
51
52 /// Function signature, first element is return type.
53 RVVTypes Signature;
54};
55
56struct RVVOverloadIntrinsicDef {
57 // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList.
58 SmallVector<uint32_t, 8> Indexes;
59};
60
61} // namespace
62
63static const PrototypeDescriptor RVVSignatureTable[] = {
64#define DECL_SIGNATURE_TABLE
65#include "clang/Basic/riscv_vector_builtin_sema.inc"
66#undef DECL_SIGNATURE_TABLE
67};
68
69static 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
75static 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
81static const RVVIntrinsicRecord RVVIntrinsicRecords[] = {
82#define DECL_INTRINSIC_RECORDS
83#include "clang/Basic/riscv_vector_builtin_sema.inc"
84#undef DECL_INTRINSIC_RECORDS
85};
86
87static 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
93static 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.
100static ArrayRef<PrototypeDescriptor>
101ProtoSeq2ArrayRef(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
113static 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(DestWidth: Type->getElementBitwidth(), Signed: true);
136 break;
137 case ScalarTypeKind::UnsignedInteger:
138 QT = Context.getIntTypeForBitwidth(DestWidth: Type->getElementBitwidth(), Signed: 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(EltTy: QT, NumElts: *Type->getScale(), NumFields: Type->getNF());
165 else
166 QT = Context.getScalableVectorType(EltTy: QT, NumElts: *Type->getScale());
167 }
168
169 if (Type->isConstant())
170 QT = Context.getConstType(T: QT);
171
172 // Transform the type to a pointer as the last step, if necessary.
173 if (Type->isPointer())
174 QT = Context.getPointerType(T: QT);
175
176 return QT;
177}
178
179namespace {
180class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
181private:
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
208public:
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
225void 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, Index: Record.PrototypeIndex, Length: Record.PrototypeLength);
234 ArrayRef<PrototypeDescriptor> SuffixProto =
235 ProtoSeq2ArrayRef(K, Index: Record.SuffixIndex, Length: Record.SuffixLength);
236 ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
237 K, Index: Record.OverloadedSuffixIndex, Length: 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 Prototype: BasicProtoSeq, /*IsMasked=*/false,
249 /*HasMaskedOffOperand=*/false, HasVL: Record.HasVL, NF: Record.NF,
250 DefaultScheme: UnMaskedPolicyScheme, PolicyAttrs: DefaultPolicy, IsTuple: Record.IsTuple);
251
252 llvm::SmallVector<PrototypeDescriptor> ProtoMaskSeq;
253 if (Record.HasMasked)
254 ProtoMaskSeq = RVVIntrinsic::computeBuiltinTypes(
255 Prototype: BasicProtoSeq, /*IsMasked=*/true, HasMaskedOffOperand: Record.HasMaskedOffOperand,
256 HasVL: Record.HasVL, NF: Record.NF, DefaultScheme: MaskedPolicyScheme, PolicyAttrs: DefaultPolicy,
257 IsTuple: 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(HasTailPolicy: Record.HasTailPolicy,
265 HasMaskPolicy: 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(BT: BaseType, Log2LMUL, NF: Record.NF, Prototype: 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, Type: BaseType, Log2LMUL, PrototypeDescriptors: SuffixProto);
290 std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
291 TypeCache, Type: BaseType, Log2LMUL, PrototypeDescriptors: OverloadedSuffixProto);
292
293 // Create non-masked intrinsic.
294 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, IsMask: false, Types&: *Types,
295 HasPolicy: UnMaskedHasPolicy, PolicyAttrs: 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 Prototype: BasicProtoSeq, /*IsMasked=*/false,
303 /*HasMaskedOffOperand=*/false, HasVL: Record.HasVL, NF: Record.NF,
304 DefaultScheme: UnMaskedPolicyScheme, PolicyAttrs: P, IsTuple: Record.IsTuple);
305 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
306 BT: BaseType, Log2LMUL, NF: Record.NF, Prototype: PolicyPrototype);
307 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
308 /*IsMask=*/false, Types&: *PolicyTypes, HasPolicy: UnMaskedHasPolicy,
309 PolicyAttrs: P);
310 }
311 }
312 if (!Record.HasMasked)
313 continue;
314 // Create masked intrinsic.
315 std::optional<RVVTypes> MaskTypes =
316 TypeCache.computeTypes(BT: BaseType, Log2LMUL, NF: Record.NF, Prototype: ProtoMaskSeq);
317 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, IsMask: true,
318 Types&: *MaskTypes, HasPolicy: MaskedHasPolicy, PolicyAttrs: 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 Prototype: BasicProtoSeq, /*IsMasked=*/true, HasMaskedOffOperand: Record.HasMaskedOffOperand,
326 HasVL: Record.HasVL, NF: Record.NF, DefaultScheme: MaskedPolicyScheme, PolicyAttrs: P,
327 IsTuple: Record.IsTuple);
328 std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
329 BT: BaseType, Log2LMUL, NF: Record.NF, Prototype: PolicyPrototype);
330 InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
331 /*IsMask=*/true, Types&: *PolicyTypes, HasPolicy: MaskedHasPolicy, PolicyAttrs: P);
332 }
333 } // End for different LMUL
334 } // End for different TypeRange
335 }
336}
337
338void 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.
359void 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(Separator: "_").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 HasFRMRoundModeOp: 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(x: {.BuiltinName: BuiltinName, .RequiredExtensions: Record.RequiredExtensions, .Signature: Signature});
389
390 // Creating mapping to Intrinsics.
391 Intrinsics.insert(KV: {Name, Index});
392
393 // Get the RVVOverloadIntrinsicDef.
394 RVVOverloadIntrinsicDef &OverloadIntrinsicDef =
395 OverloadIntrinsics[OverloadedName];
396
397 // And added the index.
398 OverloadIntrinsicDef.Indexes.push_back(Elt: Index);
399}
400
401void 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, Type: 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(Elt: RVVType2Qual(Context, Type: Sigs[i]));
418
419 FunctionProtoType::ExtProtoInfo PI(
420 Context.getDefaultCallingConvention(IsVariadic: false, IsCXXMethod: false, IsBuiltin: true));
421
422 PI.Variadic = false;
423
424 SourceLocation Loc = LR.getNameLoc();
425 BuiltinFuncType = Context.getFunctionType(ResultTy: RetType, Args: ArgTypes, EPI: PI);
426 DeclContext *Parent = Context.getTranslationUnitDecl();
427
428 FunctionDecl *RVVIntrinsicDecl = FunctionDecl::Create(
429 C&: Context, DC: Parent, StartLoc: Loc, NLoc: Loc, N: II, T: BuiltinFuncType, /*TInfo=*/nullptr,
430 SC: SC_Extern, UsesFPIntrin: 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>(Val&: 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(i: IParm), nullptr, SC_None, nullptr);
442 Parm->setScopeInfo(scopeDepth: 0, parameterIndex: IParm);
443 ParmList.push_back(Elt: 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(Name: "__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
464bool RISCVIntrinsicManagerImpl::CreateIntrinsicIfFound(LookupResult &LR,
465 IdentifierInfo *II,
466 Preprocessor &PP) {
467 StringRef Name = II->getName();
468 if (!Name.consume_front(Prefix: "__riscv_"))
469 return false;
470
471 // Lookup the function name from the overload intrinsics first.
472 auto OvIItr = OverloadIntrinsics.find(Key: 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(Key: Name);
486 if (Itr != Intrinsics.end()) {
487 CreateRVVIntrinsicDecl(LR, II, PP, Index: Itr->second,
488 /*IsOverload*/ false);
489 return true;
490 }
491
492 // It's not an RVV intrinsics.
493 return false;
494}
495
496namespace clang {
497std::unique_ptr<clang::sema::RISCVIntrinsicManager>
498CreateRISCVIntrinsicManager(Sema &S) {
499 return std::make_unique<RISCVIntrinsicManagerImpl>(args&: S);
500}
501
502bool 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(Arg: 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
522static 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(VecTy: 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(val: 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
554bool 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(A&: RequiredFeatures, Separator: ',');
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 VecTy: 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, ArgNum: SEWOffset, Result&: SEWResult) ||
646 SemaRef.BuiltinConstantArg(TheCall, ArgNum: LMULOffset, Result&: 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, ArgNum: SEWOffset, Low: 0, High: 3) ||
660 CheckLMUL(TheCall, ArgNum: 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(VecTy: cast<BuiltinType>(
670 TheCall->getType().getCanonicalType().getTypePtr()));
671 ASTContext::BuiltinVectorTypeInfo VecInfo =
672 Context.getBuiltinVectorTypeInfo(VecTy: cast<BuiltinType>(
673 Val: TheCall->getArg(Arg: 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, ArgNum: 1, Low: 0, High: MaxIndex - 1);
681 }
682 case RISCVVector::BI__builtin_rvv_vset_v: {
683 ASTContext::BuiltinVectorTypeInfo ResVecInfo =
684 Context.getBuiltinVectorTypeInfo(VecTy: cast<BuiltinType>(
685 TheCall->getType().getCanonicalType().getTypePtr()));
686 ASTContext::BuiltinVectorTypeInfo VecInfo =
687 Context.getBuiltinVectorTypeInfo(VecTy: cast<BuiltinType>(
688 Val: TheCall->getArg(Arg: 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, ArgNum: 1, Low: 0, High: 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(Arg: 0)->getType();
703 QualType Arg1Type = TheCall->getArg(Arg: 1)->getType();
704 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
705 Type: Arg0Type, EGW: 128) ||
706 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
707 Type: Arg1Type, EGW: 128) ||
708 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 31);
709 }
710 case RISCVVector::BI__builtin_rvv_vsm3c_vi_tu:
711 case RISCVVector::BI__builtin_rvv_vsm3c_vi: {
712 QualType Arg0Type = TheCall->getArg(Arg: 0)->getType();
713 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
714 Type: Arg0Type, EGW: 256) ||
715 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 31);
716 }
717 case RISCVVector::BI__builtin_rvv_vaeskf1_vi:
718 case RISCVVector::BI__builtin_rvv_vsm4k_vi: {
719 QualType Arg0Type = TheCall->getArg(Arg: 0)->getType();
720 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
721 Type: Arg0Type, EGW: 128) ||
722 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 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(Arg: 0)->getType();
747 QualType Arg1Type = TheCall->getArg(Arg: 1)->getType();
748 return CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
749 Type: Arg0Type, EGW: 128) ||
750 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
751 Type: Arg1Type, EGW: 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(Arg: 0)->getType();
760 QualType Arg1Type = TheCall->getArg(Arg: 1)->getType();
761 QualType Arg2Type = TheCall->getArg(Arg: 2)->getType();
762 ASTContext::BuiltinVectorTypeInfo Info =
763 Context.getBuiltinVectorTypeInfo(VecTy: 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, S&: SemaRef,
779 Type: Arg0Type, EGW: ElemSize * 4) ||
780 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
781 Type: Arg1Type, EGW: ElemSize * 4) ||
782 CheckInvalidVLENandLMUL(TI, FunctionFeatureMap, TheCall, S&: SemaRef,
783 Type: Arg2Type, EGW: 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, ArgNum: 0, Low: 0, High: 3) ||
789 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 31) ||
790 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 31) ||
791 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 3, Low: -16, High: 15) ||
792 CheckLMUL(TheCall, ArgNum: 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, ArgNum: 0, Low: 0, High: 3) ||
796 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 31) ||
797 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 3, Low: -16, High: 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, ArgNum: 0, Low: 0, High: 3) ||
802 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 31) ||
803 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: -16, High: 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, ArgNum: 0, Low: 0, High: 3) ||
808 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: -16, High: 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, ArgNum: 0, Low: 0, High: 3) ||
817 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 3, Low: -16, High: 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, ArgNum: 0, Low: 0, High: 3) ||
821 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 31) ||
822 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 2, Low: 0, High: 31) ||
823 CheckLMUL(TheCall, ArgNum: 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, ArgNum: 0, Low: 0, High: 3) ||
831 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 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, ArgNum: 0, Low: 0, High: 3);
852 case RISCVVector::BI__builtin_rvv_sf_vc_fv_se:
853 // bit_26, bit_11_7, vs2, fs1
854 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 0, Low: 0, High: 1) ||
855 SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 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, ArgNum: 0, Low: 0, High: 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, ArgNum: 2, Low: 0, High: 3);
875 // Check if rnum is in [0, 10]
876 case RISCV::BI__builtin_riscv_aes64ks1i:
877 return SemaRef.BuiltinConstantArgRange(TheCall, ArgNum: 1, Low: 0, High: 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, ArgNum: 2, Low: 0, High: 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, ArgNum: 3, Low: 0, High: 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, ArgNum: 4, Low: 0, High: 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, ArgNum: 1, Low: 0, High: 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, ArgNum: 2, Low: 0, High: 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, ArgNum: 3, Low: 0, High: 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, ArgNum: 4, Low: 0, High: 4);
1352 case RISCV::BI__builtin_riscv_ntl_load:
1353 case RISCV::BI__builtin_riscv_ntl_store:
1354 DeclRefExpr *DRE =
1355 cast<DeclRefExpr>(Val: 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(Call: TheCall, MinArgCount: NumArgs - 1))
1363 return true;
1364
1365 if (SemaRef.checkArgCountAtMost(Call: TheCall, MaxArgCount: 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, ArgNum: NumArgs - 1, Low: 2, High: 5))
1372 return true;
1373
1374 Expr *PointerArg = TheCall->getArg(Arg: 0);
1375 ExprResult PointerArgResult =
1376 SemaRef.DefaultFunctionArrayLvalueConversion(E: 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(Arg: 1);
1406 InitializedEntity Entity = InitializedEntity::InitializeParameter(
1407 Context, Type: ValType, /*consume*/ Consumed: false);
1408 ValArg =
1409 SemaRef.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: ValArg);
1410 if (ValArg.isInvalid())
1411 return true;
1412
1413 TheCall->setArg(Arg: 1, ArgExpr: ValArg.get());
1414 TheCall->setType(Context.VoidTy);
1415 return false;
1416 }
1417
1418 return false;
1419}
1420
1421void SemaRISCV::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
1422 const llvm::StringMap<bool> &FeatureMap) {
1423 ASTContext::BuiltinVectorTypeInfo Info =
1424 SemaRef.Context.getBuiltinVectorTypeInfo(VecTy: 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 Diag(Loc, diag::err_riscv_type_requires_extension, D)
1440 << Ty << "zvfh or zvfhmin";
1441 else if (Info.ElementType->isBFloat16Type() && !FeatureMap.lookup("zvfbfmin"))
1442 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin";
1443 else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) &&
1444 !FeatureMap.lookup("zve32f"))
1445 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f";
1446 // Given that caller already checked isRVVType() before calling this function,
1447 // if we don't have at least zve32x supported, then we need to emit error.
1448 else if (!FeatureMap.lookup("zve32x"))
1449 Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x";
1450}
1451
1452/// Are the two types RVV-bitcast-compatible types? I.e. is bitcasting from the
1453/// first RVV type (e.g. an RVV scalable type) to the second type (e.g. an RVV
1454/// VLS type) allowed?
1455///
1456/// This will also return false if the two given types do not make sense from
1457/// the perspective of RVV bitcasts.
1458bool SemaRISCV::isValidRVVBitcast(QualType srcTy, QualType destTy) {
1459 assert(srcTy->isVectorType() || destTy->isVectorType());
1460
1461 auto ValidScalableConversion = [](QualType FirstType, QualType SecondType) {
1462 if (!FirstType->isRVVSizelessBuiltinType())
1463 return false;
1464
1465 const auto *VecTy = SecondType->getAs<VectorType>();
1466 return VecTy && VecTy->getVectorKind() == VectorKind::RVVFixedLengthData;
1467 };
1468
1469 return ValidScalableConversion(srcTy, destTy) ||
1470 ValidScalableConversion(destTy, srcTy);
1471}
1472
1473void SemaRISCV::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
1474 // Warn about repeated attributes.
1475 if (const auto *A = D->getAttr<RISCVInterruptAttr>()) {
1476 Diag(AL.getRange().getBegin(),
1477 diag::warn_riscv_repeated_interrupt_attribute);
1478 Diag(A->getLocation(), diag::note_riscv_repeated_interrupt_attribute);
1479 return;
1480 }
1481
1482 // Semantic checks for a function with the 'interrupt' attribute:
1483 // - Must be a function.
1484 // - Must have no parameters.
1485 // - Must have the 'void' return type.
1486 // - The attribute itself must have at most 2 arguments
1487 // - The attribute arguments must be string literals, and valid choices.
1488 // - The attribute arguments must be a valid combination
1489 // - The current target must support the right extensions for the combination.
1490
1491 if (D->getFunctionType() == nullptr) {
1492 Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
1493 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction;
1494 return;
1495 }
1496
1497 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) {
1498 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
1499 << /*RISC-V*/ 2 << /*interrupt*/ 0 << 0;
1500 return;
1501 }
1502
1503 if (!getFunctionOrMethodResultType(D)->isVoidType()) {
1504 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid)
1505 << /*RISC-V*/ 2 << /*interrupt*/ 0 << 1;
1506 return;
1507 }
1508
1509 if (!AL.checkAtMostNumArgs(S&: SemaRef, Num: 2))
1510 return;
1511
1512 bool HasSiFiveCLICType = false;
1513 bool HasUnaryType = false;
1514
1515 SmallSet<RISCVInterruptAttr::InterruptType, 2> Types;
1516 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1517 RISCVInterruptAttr::InterruptType Type;
1518 StringRef TypeString;
1519 SourceLocation Loc;
1520
1521 if (!SemaRef.checkStringLiteralArgumentAttr(Attr: AL, ArgNum: ArgIndex, Str&: TypeString, ArgLocation: &Loc))
1522 return;
1523
1524 if (!RISCVInterruptAttr::ConvertStrToInterruptType(TypeString, Type)) {
1525 std::string TypeLiteral = ("\"" + TypeString + "\"").str();
1526 Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
1527 << AL << TypeLiteral << Loc;
1528 return;
1529 }
1530
1531 switch (Type) {
1532 case RISCVInterruptAttr::machine:
1533 // "machine" could be combined with the SiFive CLIC types, or could be
1534 // just "machine".
1535 break;
1536 case RISCVInterruptAttr::SiFiveCLICPreemptible:
1537 case RISCVInterruptAttr::SiFiveCLICStackSwap:
1538 // SiFive-CLIC types can be combined with each other and "machine"
1539 HasSiFiveCLICType = true;
1540 break;
1541 case RISCVInterruptAttr::supervisor:
1542 case RISCVInterruptAttr::qcinest:
1543 case RISCVInterruptAttr::qcinonest:
1544 // "supervisor" and "qci-(no)nest" cannot be combined with any other types
1545 HasUnaryType = true;
1546 break;
1547 }
1548
1549 Types.insert(Type);
1550 }
1551
1552 if (HasUnaryType && Types.size() > 1) {
1553 Diag(AL.getLoc(), diag::err_riscv_attribute_interrupt_invalid_combination);
1554 return;
1555 }
1556
1557 if (HasUnaryType && HasSiFiveCLICType) {
1558 Diag(AL.getLoc(), diag::err_riscv_attribute_interrupt_invalid_combination);
1559 return;
1560 }
1561
1562 // "machine" is the default, if nothing is specified.
1563 if (AL.getNumArgs() == 0)
1564 Types.insert(RISCVInterruptAttr::machine);
1565
1566 const TargetInfo &TI = getASTContext().getTargetInfo();
1567 llvm::StringMap<bool> FunctionFeatureMap;
1568 getASTContext().getFunctionFeatureMap(FunctionFeatureMap,
1569 dyn_cast<FunctionDecl>(Val: D));
1570
1571 auto HasFeature = [&](StringRef FeatureName) -> bool {
1572 return TI.hasFeature(Feature: FeatureName) || FunctionFeatureMap.lookup(Key: FeatureName);
1573 };
1574
1575 for (RISCVInterruptAttr::InterruptType Type : Types) {
1576 switch (Type) {
1577 // The QCI interrupt types require Xqciint
1578 case RISCVInterruptAttr::qcinest:
1579 case RISCVInterruptAttr::qcinonest: {
1580 if (!HasFeature("experimental-xqciint")) {
1581 Diag(AL.getLoc(),
1582 diag::err_riscv_attribute_interrupt_requires_extension)
1583 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Type) << "Xqciint";
1584 return;
1585 }
1586 } break;
1587 // The SiFive CLIC interrupt types require Xsfmclic
1588 case RISCVInterruptAttr::SiFiveCLICPreemptible:
1589 case RISCVInterruptAttr::SiFiveCLICStackSwap: {
1590 if (!HasFeature("experimental-xsfmclic")) {
1591 Diag(AL.getLoc(),
1592 diag::err_riscv_attribute_interrupt_requires_extension)
1593 << RISCVInterruptAttr::ConvertInterruptTypeToStr(Type)
1594 << "XSfmclic";
1595 return;
1596 }
1597 } break;
1598 default:
1599 break;
1600 }
1601 }
1602
1603 SmallVector<RISCVInterruptAttr::InterruptType, 2> TypesVec(Types.begin(),
1604 Types.end());
1605
1606 D->addAttr(::new (getASTContext()) RISCVInterruptAttr(
1607 getASTContext(), AL, TypesVec.data(), TypesVec.size()));
1608}
1609
1610bool SemaRISCV::isAliasValid(unsigned BuiltinID, StringRef AliasName) {
1611 return BuiltinID >= RISCV::FirstRVVBuiltin &&
1612 BuiltinID <= RISCV::LastRVVBuiltin;
1613}
1614
1615bool SemaRISCV::isValidFMVExtension(StringRef Ext) {
1616 if (Ext.empty())
1617 return false;
1618
1619 if (!Ext.consume_front(Prefix: "+"))
1620 return false;
1621
1622 return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second;
1623}
1624
1625SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {}
1626
1627} // namespace clang
1628

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/lib/Sema/SemaRISCV.cpp