1 | //===------ SemaRISCV.cpp ------- RISC-V target-specific routines ---------===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements semantic analysis functions specific to RISC-V. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/Sema/SemaRISCV.h" |
14 | #include "clang/AST/ASTContext.h" |
15 | #include "clang/AST/Attr.h" |
16 | #include "clang/AST/Attrs.inc" |
17 | #include "clang/AST/Decl.h" |
18 | #include "clang/Basic/Builtins.h" |
19 | #include "clang/Basic/TargetBuiltins.h" |
20 | #include "clang/Basic/TargetInfo.h" |
21 | #include "clang/Lex/Preprocessor.h" |
22 | #include "clang/Sema/Attr.h" |
23 | #include "clang/Sema/Initialization.h" |
24 | #include "clang/Sema/Lookup.h" |
25 | #include "clang/Sema/ParsedAttr.h" |
26 | #include "clang/Sema/RISCVIntrinsicManager.h" |
27 | #include "clang/Sema/Sema.h" |
28 | #include "clang/Support/RISCVVIntrinsicUtils.h" |
29 | #include "llvm/ADT/SmallVector.h" |
30 | #include "llvm/TargetParser/RISCVISAInfo.h" |
31 | #include "llvm/TargetParser/RISCVTargetParser.h" |
32 | #include <optional> |
33 | #include <string> |
34 | #include <vector> |
35 | |
36 | using namespace llvm; |
37 | using namespace clang; |
38 | using namespace clang::RISCV; |
39 | |
40 | using IntrinsicKind = sema::RISCVIntrinsicManager::IntrinsicKind; |
41 | |
42 | namespace { |
43 | |
44 | // Function definition of a RVV intrinsic. |
45 | struct RVVIntrinsicDef { |
46 | /// Mapping to which clang built-in function, e.g. __builtin_rvv_vadd. |
47 | std::string BuiltinName; |
48 | |
49 | /// Mapping to RequiredFeatures in riscv_vector.td |
50 | std::string RequiredExtensions; |
51 | |
52 | /// Function signature, first element is return type. |
53 | RVVTypes Signature; |
54 | }; |
55 | |
56 | struct RVVOverloadIntrinsicDef { |
57 | // Indexes of RISCVIntrinsicManagerImpl::IntrinsicList. |
58 | SmallVector<uint32_t, 8> Indexes; |
59 | }; |
60 | |
61 | } // namespace |
62 | |
63 | static const PrototypeDescriptor RVVSignatureTable[] = { |
64 | #define DECL_SIGNATURE_TABLE |
65 | #include "clang/Basic/riscv_vector_builtin_sema.inc" |
66 | #undef DECL_SIGNATURE_TABLE |
67 | }; |
68 | |
69 | static const PrototypeDescriptor RVSiFiveVectorSignatureTable[] = { |
70 | #define DECL_SIGNATURE_TABLE |
71 | #include "clang/Basic/riscv_sifive_vector_builtin_sema.inc" |
72 | #undef DECL_SIGNATURE_TABLE |
73 | }; |
74 | |
75 | static const PrototypeDescriptor RVAndesVectorSignatureTable[] = { |
76 | #define DECL_SIGNATURE_TABLE |
77 | #include "clang/Basic/riscv_andes_vector_builtin_sema.inc" |
78 | #undef DECL_SIGNATURE_TABLE |
79 | }; |
80 | |
81 | static const RVVIntrinsicRecord RVVIntrinsicRecords[] = { |
82 | #define DECL_INTRINSIC_RECORDS |
83 | #include "clang/Basic/riscv_vector_builtin_sema.inc" |
84 | #undef DECL_INTRINSIC_RECORDS |
85 | }; |
86 | |
87 | static const RVVIntrinsicRecord RVSiFiveVectorIntrinsicRecords[] = { |
88 | #define DECL_INTRINSIC_RECORDS |
89 | #include "clang/Basic/riscv_sifive_vector_builtin_sema.inc" |
90 | #undef DECL_INTRINSIC_RECORDS |
91 | }; |
92 | |
93 | static const RVVIntrinsicRecord RVAndesVectorIntrinsicRecords[] = { |
94 | #define DECL_INTRINSIC_RECORDS |
95 | #include "clang/Basic/riscv_andes_vector_builtin_sema.inc" |
96 | #undef DECL_INTRINSIC_RECORDS |
97 | }; |
98 | |
99 | // Get subsequence of signature table. |
100 | static ArrayRef<PrototypeDescriptor> |
101 | ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length) { |
102 | switch (K) { |
103 | case IntrinsicKind::RVV: |
104 | return ArrayRef(&RVVSignatureTable[Index], Length); |
105 | case IntrinsicKind::SIFIVE_VECTOR: |
106 | return ArrayRef(&RVSiFiveVectorSignatureTable[Index], Length); |
107 | case IntrinsicKind::ANDES_VECTOR: |
108 | return ArrayRef(&RVAndesVectorSignatureTable[Index], Length); |
109 | } |
110 | llvm_unreachable("Unhandled IntrinsicKind"); |
111 | } |
112 | |
113 | static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type) { |
114 | QualType QT; |
115 | switch (Type->getScalarType()) { |
116 | case ScalarTypeKind::Void: |
117 | QT = Context.VoidTy; |
118 | break; |
119 | case ScalarTypeKind::Size_t: |
120 | QT = Context.getSizeType(); |
121 | break; |
122 | case ScalarTypeKind::Ptrdiff_t: |
123 | QT = Context.getPointerDiffType(); |
124 | break; |
125 | case ScalarTypeKind::UnsignedLong: |
126 | QT = Context.UnsignedLongTy; |
127 | break; |
128 | case ScalarTypeKind::SignedLong: |
129 | QT = Context.LongTy; |
130 | break; |
131 | case ScalarTypeKind::Boolean: |
132 | QT = Context.BoolTy; |
133 | break; |
134 | case ScalarTypeKind::SignedInteger: |
135 | QT = Context.getIntTypeForBitwidth(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 | |
179 | namespace { |
180 | class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager { |
181 | private: |
182 | Sema &S; |
183 | RVVTypeCache TypeCache; |
184 | bool ConstructedRISCVVBuiltins; |
185 | bool ConstructedRISCVSiFiveVectorBuiltins; |
186 | bool ConstructedRISCVAndesVectorBuiltins; |
187 | |
188 | // List of all RVV intrinsic. |
189 | std::vector<RVVIntrinsicDef> IntrinsicList; |
190 | // Mapping function name to index of IntrinsicList. |
191 | StringMap<uint32_t> Intrinsics; |
192 | // Mapping function name to RVVOverloadIntrinsicDef. |
193 | StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics; |
194 | |
195 | // Create RVVIntrinsicDef. |
196 | void InitRVVIntrinsic(const RVVIntrinsicRecord &Record, StringRef SuffixStr, |
197 | StringRef OverloadedSuffixStr, bool IsMask, |
198 | RVVTypes &Types, bool HasPolicy, Policy PolicyAttrs); |
199 | |
200 | // Create FunctionDecl for a vector intrinsic. |
201 | void CreateRVVIntrinsicDecl(LookupResult &LR, IdentifierInfo *II, |
202 | Preprocessor &PP, uint32_t Index, |
203 | bool IsOverload); |
204 | |
205 | void ConstructRVVIntrinsics(ArrayRef<RVVIntrinsicRecord> Recs, |
206 | IntrinsicKind K); |
207 | |
208 | public: |
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 | |
225 | void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics( |
226 | ArrayRef<RVVIntrinsicRecord> Recs, IntrinsicKind K) { |
227 | // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics |
228 | // in RISCVVEmitter.cpp. |
229 | for (auto &Record : Recs) { |
230 | // Create Intrinsics for each type and LMUL. |
231 | BasicType BaseType = BasicType::Unknown; |
232 | ArrayRef<PrototypeDescriptor> BasicProtoSeq = |
233 | ProtoSeq2ArrayRef(K, 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 | |
338 | void RISCVIntrinsicManagerImpl::InitIntrinsicList() { |
339 | |
340 | if (S.RISCV().DeclareRVVBuiltins && !ConstructedRISCVVBuiltins) { |
341 | ConstructedRISCVVBuiltins = true; |
342 | ConstructRVVIntrinsics(RVVIntrinsicRecords, IntrinsicKind::RVV); |
343 | } |
344 | if (S.RISCV().DeclareSiFiveVectorBuiltins && |
345 | !ConstructedRISCVSiFiveVectorBuiltins) { |
346 | ConstructedRISCVSiFiveVectorBuiltins = true; |
347 | ConstructRVVIntrinsics(RVSiFiveVectorIntrinsicRecords, |
348 | IntrinsicKind::SIFIVE_VECTOR); |
349 | } |
350 | if (S.RISCV().DeclareAndesVectorBuiltins && |
351 | !ConstructedRISCVAndesVectorBuiltins) { |
352 | ConstructedRISCVAndesVectorBuiltins = true; |
353 | ConstructRVVIntrinsics(RVAndesVectorIntrinsicRecords, |
354 | IntrinsicKind::ANDES_VECTOR); |
355 | } |
356 | } |
357 | |
358 | // Compute name and signatures for intrinsic with practical types. |
359 | void RISCVIntrinsicManagerImpl::InitRVVIntrinsic( |
360 | const RVVIntrinsicRecord &Record, StringRef SuffixStr, |
361 | StringRef OverloadedSuffixStr, bool IsMasked, RVVTypes &Signature, |
362 | bool HasPolicy, Policy PolicyAttrs) { |
363 | // Function name, e.g. vadd_vv_i32m1. |
364 | std::string Name = Record.Name; |
365 | if (!SuffixStr.empty()) |
366 | Name += "_"+ SuffixStr.str(); |
367 | |
368 | // Overloaded function name, e.g. vadd. |
369 | std::string OverloadedName; |
370 | if (!Record.OverloadedName) |
371 | OverloadedName = StringRef(Record.Name).split(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 | |
401 | void RISCVIntrinsicManagerImpl::CreateRVVIntrinsicDecl(LookupResult &LR, |
402 | IdentifierInfo *II, |
403 | Preprocessor &PP, |
404 | uint32_t Index, |
405 | bool IsOverload) { |
406 | ASTContext &Context = S.Context; |
407 | RVVIntrinsicDef &IDef = IntrinsicList[Index]; |
408 | RVVTypes Sigs = IDef.Signature; |
409 | size_t SigLength = Sigs.size(); |
410 | RVVType *ReturnType = Sigs[0]; |
411 | QualType RetType = RVVType2Qual(Context, 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 | |
464 | bool 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 | |
496 | namespace clang { |
497 | std::unique_ptr<clang::sema::RISCVIntrinsicManager> |
498 | CreateRISCVIntrinsicManager(Sema &S) { |
499 | return std::make_unique<RISCVIntrinsicManagerImpl>(args&: S); |
500 | } |
501 | |
502 | bool SemaRISCV::CheckLMUL(CallExpr *TheCall, unsigned ArgNum) { |
503 | llvm::APSInt Result; |
504 | |
505 | // We can't check the value of a dependent argument. |
506 | Expr *Arg = TheCall->getArg(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 | |
522 | static bool CheckInvalidVLENandLMUL(const TargetInfo &TI, |
523 | llvm::StringMap<bool> &FunctionFeatureMap, |
524 | CallExpr *TheCall, Sema &S, QualType Type, |
525 | int EGW) { |
526 | assert((EGW == 128 || EGW == 256) && "EGW can only be 128 or 256 bits"); |
527 | |
528 | // LMUL * VLEN >= EGW |
529 | ASTContext::BuiltinVectorTypeInfo Info = |
530 | S.Context.getBuiltinVectorTypeInfo(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 | |
554 | bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI, |
555 | unsigned BuiltinID, |
556 | CallExpr *TheCall) { |
557 | ASTContext &Context = getASTContext(); |
558 | const FunctionDecl *FD = SemaRef.getCurFunctionDecl(); |
559 | llvm::StringMap<bool> FunctionFeatureMap; |
560 | Context.getFunctionFeatureMap(FunctionFeatureMap, FD); |
561 | |
562 | if (const auto *A = TheCall->getCalleeDecl()->getAttr<TargetAttr>()) { |
563 | StringRef FeaturesStr = A->getFeaturesStr(); |
564 | llvm::SmallVector<StringRef> RequiredFeatures; |
565 | FeaturesStr.split(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 | |
1421 | void 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. |
1458 | bool 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 | |
1473 | void 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 | |
1610 | bool SemaRISCV::isAliasValid(unsigned BuiltinID, StringRef AliasName) { |
1611 | return BuiltinID >= RISCV::FirstRVVBuiltin && |
1612 | BuiltinID <= RISCV::LastRVVBuiltin; |
1613 | } |
1614 | |
1615 | bool 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 | |
1625 | SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {} |
1626 | |
1627 | } // namespace clang |
1628 |
Definitions
- RVVIntrinsicDef
- RVVOverloadIntrinsicDef
- RVVSignatureTable
- RVSiFiveVectorSignatureTable
- RVAndesVectorSignatureTable
- RVVIntrinsicRecords
- RVSiFiveVectorIntrinsicRecords
- RVAndesVectorIntrinsicRecords
- ProtoSeq2ArrayRef
- RVVType2Qual
- RISCVIntrinsicManagerImpl
- RISCVIntrinsicManagerImpl
- ConstructRVVIntrinsics
- InitIntrinsicList
- InitRVVIntrinsic
- CreateRVVIntrinsicDecl
- CreateIntrinsicIfFound
- CreateRISCVIntrinsicManager
- CheckLMUL
- CheckInvalidVLENandLMUL
- CheckBuiltinFunctionCall
- checkRVVTypeSupport
- isValidRVVBitcast
- handleInterruptAttr
- isAliasValid
- isValidFMVExtension
Learn to use CMake with our Intro Training
Find out more