clang 24.0.0git
RISCV.cpp
Go to the documentation of this file.
1//===- RISCV.cpp ----------------------------------------------------------===//
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#include "ABIInfoImpl.h"
10#include "TargetInfo.h"
11#include "llvm/IR/IntrinsicsRISCV.h"
12#include "llvm/TargetParser/RISCVTargetParser.h"
13
14using namespace clang;
15using namespace clang::CodeGen;
16
17//===----------------------------------------------------------------------===//
18// RISC-V ABI Implementation
19//===----------------------------------------------------------------------===//
20
21namespace {
22class RISCVABIInfo : public DefaultABIInfo {
23private:
24 // Size of the integer ('x') registers in bits.
25 unsigned XLen;
26 // Size of the floating point ('f') registers in bits. Note that the target
27 // ISA might have a wider FLen than the selected ABI (e.g. an RV32IF target
28 // with soft float ABI has FLen==0).
29 unsigned FLen;
30 const int NumArgGPRs;
31 const int NumArgFPRs;
32 const bool EABI;
33 bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
34 llvm::Type *&Field1Ty,
35 CharUnits &Field1Off,
36 llvm::Type *&Field2Ty,
37 CharUnits &Field2Off) const;
38
39 llvm::Type *detectVLSCCEligibleStruct(QualType Ty, unsigned ABIVLen) const;
40
41 llvm::Type *detectHomogeneousRVVFixedLengthStruct(QualType Ty) const;
42
43 unsigned getRVVFixedLengthMinElts(const VectorType *VT) const;
44
45public:
46 RISCVABIInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen, unsigned FLen,
47 bool EABI)
48 : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8),
49 NumArgFPRs(FLen != 0 ? 8 : 0), EABI(EABI) {}
50
51 // DefaultABIInfo's classifyReturnType and classifyArgumentType are
52 // non-virtual, but computeInfo is virtual, so we overload it.
53 void computeInfo(CGFunctionInfo &FI) const override;
54
55 ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &ArgGPRsLeft,
56 int &ArgFPRsLeft, unsigned ABIVLen) const;
57 ABIArgInfo classifyReturnType(QualType RetTy, unsigned ABIVLen) const;
58
59 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
60 AggValueSlot Slot) const override;
61
62 ABIArgInfo extendType(QualType Ty, llvm::Type *CoerceTy = nullptr) const;
63
64 bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
65 CharUnits &Field1Off, llvm::Type *&Field2Ty,
66 CharUnits &Field2Off, int &NeededArgGPRs,
67 int &NeededArgFPRs) const;
68 ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty,
69 CharUnits Field1Off,
70 llvm::Type *Field2Ty,
71 CharUnits Field2Off) const;
72
73 ABIArgInfo coerceVLSVector(QualType Ty, unsigned ABIVLen = 0) const;
74 // Some unsupported type e.g. bf16 without zvfbfmin or zvfbfa, should be
75 // passed as same size i8 type. This function check and return the appropriate
76 // fixed vector type.
77 llvm::FixedVectorType *
78 getVLSCCCompatibleType(llvm::FixedVectorType *FixedVecTy) const;
79
81 void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
82 raw_ostream &Out) const override;
83 void appendAttributeMangling(StringRef AttrStr,
84 raw_ostream &Out) const override;
85 llvm::Value *createCoercedLoad(Address SrcAddr, const ABIArgInfo &AI,
86 CodeGenFunction &CGF) const override;
87 void createCoercedStore(llvm::Value *Val, Address DstAddr,
88 const ABIArgInfo &AI, bool DestIsVolatile,
89 CodeGenFunction &CGF) const override;
90};
91} // end anonymous namespace
92
93void RISCVABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
94 unsigned Index,
95 raw_ostream &Out) const {
96 appendAttributeMangling(Attr->getFeatureStr(Index), Out);
97}
98
99void RISCVABIInfo::appendAttributeMangling(StringRef AttrStr,
100 raw_ostream &Out) const {
101 if (AttrStr == "default") {
102 Out << ".default";
103 return;
104 }
105
106 Out << '.';
107
108 SmallVector<StringRef, 8> Attrs;
109 AttrStr.split(Attrs, ';');
110
111 // Only consider the arch string.
112 StringRef ArchStr;
113 for (auto &Attr : Attrs) {
114 if (Attr.starts_with("arch="))
115 ArchStr = Attr;
116 }
117
118 // Extract features string.
119 SmallVector<StringRef, 8> Features;
120 ArchStr.consume_front("arch=");
121 ArchStr.split(Features, ',');
122
123 llvm::stable_sort(Features);
124
125 for (auto Feat : Features) {
126 Feat.consume_front("+");
127 Out << "_" << Feat;
128 }
129}
130
131void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const {
132 unsigned ABIVLen;
133 switch (FI.getExtInfo().getCC()) {
134 default:
135 ABIVLen = 0;
136 break;
137#define CC_VLS_CASE(ABI_VLEN) \
138 case CallingConv::CC_RISCVVLSCall_##ABI_VLEN: \
139 ABIVLen = ABI_VLEN; \
140 break;
141 CC_VLS_CASE(32)
142 CC_VLS_CASE(64)
143 CC_VLS_CASE(128)
144 CC_VLS_CASE(256)
145 CC_VLS_CASE(512)
146 CC_VLS_CASE(1024)
147 CC_VLS_CASE(2048)
148 CC_VLS_CASE(4096)
149 CC_VLS_CASE(8192)
150 CC_VLS_CASE(16384)
151 CC_VLS_CASE(32768)
152 CC_VLS_CASE(65536)
153#undef CC_VLS_CASE
154 }
155 QualType RetTy = FI.getReturnType();
156 if (!getCXXABI().classifyReturnType(FI))
157 FI.getReturnInfo() = classifyReturnType(RetTy, ABIVLen);
158
159 // IsRetIndirect is true if classifyArgumentType indicated the value should
160 // be passed indirect, or if the type size is a scalar greater than 2*XLen
161 // and not a complex type with elements <= FLen. e.g. fp128 is passed direct
162 // in LLVM IR, relying on the backend lowering code to rewrite the argument
163 // list and pass indirectly on RV32.
164 bool IsRetIndirect = FI.getReturnInfo().getKind() == ABIArgInfo::Indirect;
165 if (!IsRetIndirect && RetTy->isScalarType() &&
166 getContext().getTypeSize(RetTy) > (2 * XLen)) {
167 if (RetTy->isComplexType() && FLen) {
168 QualType EltTy = RetTy->castAs<ComplexType>()->getElementType();
169 IsRetIndirect = getContext().getTypeSize(EltTy) > FLen;
170 } else {
171 // This is a normal scalar > 2*XLen, such as fp128 on RV32.
172 IsRetIndirect = true;
173 }
174 }
175
176 int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs;
177 int ArgFPRsLeft = NumArgFPRs;
178 int NumFixedArgs = FI.getNumRequiredArgs();
179
180 int ArgNum = 0;
181 for (auto &ArgInfo : FI.arguments()) {
182 bool IsFixed = ArgNum < NumFixedArgs;
183 ArgInfo.info = classifyArgumentType(ArgInfo.type, IsFixed, ArgGPRsLeft,
184 ArgFPRsLeft, ABIVLen);
185 ArgNum++;
186 }
187}
188
189// Returns true if the struct is a potential candidate for the floating point
190// calling convention. If this function returns true, the caller is
191// responsible for checking that if there is only a single field then that
192// field is a float.
193bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
194 llvm::Type *&Field1Ty,
195 CharUnits &Field1Off,
196 llvm::Type *&Field2Ty,
197 CharUnits &Field2Off) const {
198 bool IsInt = Ty->isIntegralOrEnumerationType();
199 bool IsFloat = Ty->isRealFloatingType();
200
201 if (IsInt || IsFloat) {
202 uint64_t Size = getContext().getTypeSize(Ty);
203 if (IsInt && Size > XLen)
204 return false;
205 // Can't be eligible if larger than the FP registers. Handling of half
206 // precision values has been specified in the ABI, so don't block those.
207 if (IsFloat && Size > FLen)
208 return false;
209 // Can't be eligible if an integer type was already found (int+int pairs
210 // are not eligible).
211 if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
212 return false;
213 if (!Field1Ty) {
214 Field1Ty = CGT.ConvertType(Ty);
215 Field1Off = CurOff;
216 return true;
217 }
218 if (!Field2Ty) {
219 Field2Ty = CGT.ConvertType(Ty);
220 Field2Off = CurOff;
221 return true;
222 }
223 return false;
224 }
225
226 if (auto CTy = Ty->getAs<ComplexType>()) {
227 if (Field1Ty)
228 return false;
229 QualType EltTy = CTy->getElementType();
230 // Only floating-point complex types (e.g. _Complex float/double) are
231 // eligible to be passed in floating-point argument registers. Complex
232 // integer types (a GNU extension) should be treated like a normal
233 // aggregate and packed into GPRs instead.
234 if (!EltTy->isRealFloatingType())
235 return false;
236 if (getContext().getTypeSize(EltTy) > FLen)
237 return false;
238 Field1Ty = CGT.ConvertType(EltTy);
239 Field1Off = CurOff;
240 Field2Ty = Field1Ty;
241 Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
242 return true;
243 }
244
245 if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
246 uint64_t ArraySize = ATy->getZExtSize();
247 QualType EltTy = ATy->getElementType();
248 // Non-zero-length arrays of empty records make the struct ineligible for
249 // the FP calling convention in C++.
250 if (const auto *RTy = EltTy->getAsCanonical<RecordType>()) {
251 if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
252 isEmptyRecord(getContext(), EltTy, true, true))
253 return false;
254 }
255 CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
256 for (uint64_t i = 0; i < ArraySize; ++i) {
257 bool Ret = detectFPCCEligibleStructHelper(EltTy, CurOff, Field1Ty,
258 Field1Off, Field2Ty, Field2Off);
259 if (!Ret)
260 return false;
261 CurOff += EltSize;
262 }
263 return true;
264 }
265
266 if (const auto *RTy = Ty->getAsCanonical<RecordType>()) {
267 // Structures with either a non-trivial destructor or a non-trivial
268 // copy constructor are not eligible for the FP calling convention.
269 if (getRecordArgABI(Ty, CGT.getCXXABI()))
270 return false;
271 if (isEmptyRecord(getContext(), Ty, true, true))
272 return true;
273 const RecordDecl *RD = RTy->getDecl()->getDefinitionOrSelf();
274 // Unions aren't eligible unless they're empty (which is caught above).
275 if (RD->isUnion())
276 return false;
277 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
278 // If this is a C++ record, check the bases first.
279 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
280 for (const CXXBaseSpecifier &B : CXXRD->bases()) {
281 const auto *BDecl = B.getType()->castAsCXXRecordDecl();
282 CharUnits BaseOff = Layout.getBaseClassOffset(BDecl);
283 bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff,
284 Field1Ty, Field1Off, Field2Ty,
285 Field2Off);
286 if (!Ret)
287 return false;
288 }
289 }
290 int ZeroWidthBitFieldCount = 0;
291 for (const FieldDecl *FD : RD->fields()) {
292 uint64_t FieldOffInBits = Layout.getFieldOffset(FD->getFieldIndex());
293 QualType QTy = FD->getType();
294 if (FD->isBitField()) {
295 unsigned BitWidth = FD->getBitWidthValue();
296 // Allow a bitfield with a type greater than XLen as long as the
297 // bitwidth is XLen or less.
298 if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen)
299 QTy = getContext().getIntTypeForBitwidth(XLen, false);
300 // Trim type to bitwidth if possible
301 else if (getContext().getTypeSize(QTy) > BitWidth) {
302 bool IsSigned =
303 FD->getType().getTypePtr()->hasSignedIntegerRepresentation();
304 unsigned Bits = std::max(8U, (unsigned)llvm::PowerOf2Ceil(BitWidth));
305 QTy = getContext().getIntTypeForBitwidth(Bits, IsSigned);
306 }
307 if (BitWidth == 0) {
308 ZeroWidthBitFieldCount++;
309 continue;
310 }
311 }
312
313 bool Ret = detectFPCCEligibleStructHelper(
314 QTy, CurOff + getContext().toCharUnitsFromBits(FieldOffInBits),
315 Field1Ty, Field1Off, Field2Ty, Field2Off);
316 if (!Ret)
317 return false;
318
319 // As a quirk of the ABI, zero-width bitfields aren't ignored for fp+fp
320 // or int+fp structs, but are ignored for a struct with an fp field and
321 // any number of zero-width bitfields.
322 if (Field2Ty && ZeroWidthBitFieldCount > 0)
323 return false;
324 }
325 return Field1Ty != nullptr;
326 }
327
328 return false;
329}
330
331// Determine if a struct is eligible for passing according to the floating
332// point calling convention (i.e., when flattened it contains a single fp
333// value, fp+fp, or int+fp of appropriate size). If so, NeededArgFPRs and
334// NeededArgGPRs are incremented appropriately.
335bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
336 CharUnits &Field1Off,
337 llvm::Type *&Field2Ty,
338 CharUnits &Field2Off,
339 int &NeededArgGPRs,
340 int &NeededArgFPRs) const {
341 Field1Ty = nullptr;
342 Field2Ty = nullptr;
343 NeededArgGPRs = 0;
344 NeededArgFPRs = 0;
345 bool IsCandidate = detectFPCCEligibleStructHelper(
346 Ty, CharUnits::Zero(), Field1Ty, Field1Off, Field2Ty, Field2Off);
347 if (!Field1Ty)
348 return false;
349 // Not really a candidate if we have a single int but no float.
350 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
351 return false;
352 if (!IsCandidate)
353 return false;
354 if (Field1Ty && Field1Ty->isFloatingPointTy())
355 NeededArgFPRs++;
356 else if (Field1Ty)
357 NeededArgGPRs++;
358 if (Field2Ty && Field2Ty->isFloatingPointTy())
359 NeededArgFPRs++;
360 else if (Field2Ty)
361 NeededArgGPRs++;
362 return true;
363}
364
365// Call getCoerceAndExpand for the two-element flattened struct described by
366// Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an
367// appropriate coerceToType and unpaddedCoerceToType.
368ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct(
369 llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty,
370 CharUnits Field2Off) const {
371 SmallVector<llvm::Type *, 3> CoerceElts;
372 SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
373 if (!Field1Off.isZero())
374 CoerceElts.push_back(llvm::ArrayType::get(
375 llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity()));
376
377 CoerceElts.push_back(Field1Ty);
378 UnpaddedCoerceElts.push_back(Field1Ty);
379
380 if (!Field2Ty) {
382 llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()),
383 UnpaddedCoerceElts[0]);
384 }
385
386 CharUnits Field2Align =
387 CharUnits::fromQuantity(getDataLayout().getABITypeAlign(Field2Ty));
388 CharUnits Field1End = Field1Off +
389 CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty));
390 CharUnits Field2OffNoPadNoPack = Field1End.alignTo(Field2Align);
391
392 CharUnits Padding = CharUnits::Zero();
393 if (Field2Off > Field2OffNoPadNoPack)
394 Padding = Field2Off - Field2OffNoPadNoPack;
395 else if (Field2Off != Field2Align && Field2Off > Field1End)
396 Padding = Field2Off - Field1End;
397
398 bool IsPacked = !Field2Off.isMultipleOf(Field2Align);
399
400 if (!Padding.isZero())
401 CoerceElts.push_back(llvm::ArrayType::get(
402 llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity()));
403
404 CoerceElts.push_back(Field2Ty);
405 UnpaddedCoerceElts.push_back(Field2Ty);
406
407 auto CoerceToType =
408 llvm::StructType::get(getVMContext(), CoerceElts, IsPacked);
409 auto UnpaddedCoerceToType =
410 llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked);
411
412 return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType);
413}
414
415/// Minimum element count of the scalable vector an RVV fixed-length *data*
416/// vector is coerced to, i.e. the N in <vscale x N x T>. The LMUL comes from
417/// the vector kind - the type the typedef was written against - rather than
418/// from VLEN and the element count.
420 unsigned EltSizeInBits) {
421 // The underlying scalable type holds LMUL * RVVBitsPerBlock bits at
422 // vscale=1.
423 int LMulLog2 = getRVVFixedLengthDataLMulLog2(VK);
424 unsigned SizeAtVScale1 = LMulLog2 >= 0
425 ? llvm::RISCV::RVVBitsPerBlock << LMulLog2
426 : llvm::RISCV::RVVBitsPerBlock >> -LMulLog2;
427 assert(SizeAtVScale1 >= EltSizeInBits && "LMUL too small for element type");
428 return SizeAtVScale1 / EltSizeInBits;
429}
430
431/// Minimum element count of the scalable vector a vbool<R>_t mask is coerced
432/// to, i.e. the N in <vscale x N x i1>.
434 return llvm::RISCV::RVVBitsPerBlock >> getRVVFixedLengthMaskRatioLog2(VK);
435}
436
437/// Minimum element count of the scalable vector \p VT is coerced to, in units
438/// of \p VT's own Clang element type. Masks are modelled as i8 vectors, so
439/// their i1 lane count is rounded up to whole bytes.
440unsigned RISCVABIInfo::getRVVFixedLengthMinElts(const VectorType *VT) const {
441 unsigned EltSizeInBits = getContext().getTypeSize(VT->getElementType());
443 return getRVVFixedLengthDataMinElts(VT->getVectorKind(), EltSizeInBits);
445 "not an RVV fixed-length vector");
446 return llvm::divideCeil(getRVVFixedLengthMaskMinElts(VT->getVectorKind()),
447 EltSizeInBits);
448}
449
450llvm::Type *RISCVABIInfo::detectVLSCCEligibleStruct(QualType Ty,
451 unsigned ABIVLen) const {
452 // No riscv_vls_cc attribute.
453 if (ABIVLen == 0)
454 return nullptr;
455
456 // Legal struct for VLS calling convention should fulfill following rules:
457 // 1. Struct element should be either "homogeneous fixed-length vectors" or "a
458 // fixed-length vector array".
459 // 2. Number of struct elements or array elements should be greater or equal
460 // to 1 and less or equal to 8
461 // 3. Total number of vector registers needed should not exceed 8.
462 //
463 // Examples: Assume ABI_VLEN = 128.
464 // These are legal structs:
465 // a. Structs with 1~8 "same" fixed-length vectors, e.g.
466 // struct {
467 // __attribute__((vector_size(16))) int a;
468 // __attribute__((vector_size(16))) int b;
469 // }
470 //
471 // b. Structs with "single" fixed-length vector array with lengh 1~8, e.g.
472 // struct {
473 // __attribute__((vector_size(16))) int a[3];
474 // }
475 // These are illegal structs:
476 // a. Structs with 9 fixed-length vectors, e.g.
477 // struct {
478 // __attribute__((vector_size(16))) int a;
479 // __attribute__((vector_size(16))) int b;
480 // __attribute__((vector_size(16))) int c;
481 // __attribute__((vector_size(16))) int d;
482 // __attribute__((vector_size(16))) int e;
483 // __attribute__((vector_size(16))) int f;
484 // __attribute__((vector_size(16))) int g;
485 // __attribute__((vector_size(16))) int h;
486 // __attribute__((vector_size(16))) int i;
487 // }
488 //
489 // b. Structs with "multiple" fixed-length vector array, e.g.
490 // struct {
491 // __attribute__((vector_size(16))) int a[2];
492 // __attribute__((vector_size(16))) int b[2];
493 // }
494 //
495 // c. Vector registers needed exceeds 8, e.g.
496 // struct {
497 // // Registers needed for single fixed-length element:
498 // // 64 * 8 / ABI_VLEN = 4
499 // __attribute__((vector_size(64))) int a;
500 // __attribute__((vector_size(64))) int b;
501 // __attribute__((vector_size(64))) int c;
502 // __attribute__((vector_size(64))) int d;
503 // }
504 //
505 // 1. Struct of 1 fixed-length vector is passed as a scalable vector.
506 // 2. Struct of >1 fixed-length vectors are passed as vector tuple.
507 // 3. Struct of an array with 1 element of fixed-length vectors is passed as a
508 // scalable vector.
509 // 4. Struct of an array with >1 elements of fixed-length vectors is passed as
510 // vector tuple.
511 // 5. Otherwise, pass the struct indirectly.
512
513 llvm::StructType *STy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
514 if (!STy)
515 return nullptr;
516
517 unsigned NumElts = STy->getStructNumElements();
518 if (NumElts > 8)
519 return nullptr;
520
521 auto *FirstEltTy = STy->getElementType(0);
522 if (!STy->containsHomogeneousTypes())
523 return nullptr;
524
525 if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(FirstEltTy)) {
526 // Only struct of single array is accepted
527 if (NumElts != 1)
528 return nullptr;
529 FirstEltTy = ArrayTy->getArrayElementType();
530 NumElts = ArrayTy->getNumElements();
531 }
532
533 auto *FixedVecTy = dyn_cast<llvm::FixedVectorType>(FirstEltTy);
534 if (!FixedVecTy)
535 return nullptr;
536
537 // Check registers needed <= 8.
538 if (NumElts * llvm::divideCeil(
539 FixedVecTy->getNumElements() *
540 FixedVecTy->getElementType()->getScalarSizeInBits(),
541 ABIVLen) >
542 8)
543 return nullptr;
544
545 // Turn them into scalable vector type or vector tuple type if legal.
546 if (NumElts == 1) {
547 // Handle single fixed-length vector.
548 llvm::FixedVectorType *VLSTy = getVLSCCCompatibleType(FixedVecTy);
549 return llvm::ScalableVectorType::get(
550 VLSTy->getElementType(),
551 llvm::divideCeil(VLSTy->getNumElements() * llvm::RISCV::RVVBitsPerBlock,
552 ABIVLen));
553 }
554
555 // LMUL
556 // = fixed-length vector size / ABIVLen
557 // = 8 * I8EltCount / RVVBitsPerBlock
558 // =>
559 // I8EltCount
560 // = (fixed-length vector size * RVVBitsPerBlock) / (ABIVLen * 8)
561 unsigned I8EltCount =
562 llvm::divideCeil(FixedVecTy->getNumElements() *
563 FixedVecTy->getElementType()->getScalarSizeInBits() *
564 llvm::RISCV::RVVBitsPerBlock,
565 ABIVLen * 8);
566 return llvm::TargetExtType::get(
567 getVMContext(), "riscv.vector.tuple",
568 llvm::ScalableVectorType::get(llvm::Type::getInt8Ty(getVMContext()),
569 I8EltCount),
570 NumElts);
571}
572
573llvm::Type *
574RISCVABIInfo::detectHomogeneousRVVFixedLengthStruct(QualType Ty) const {
575 const auto *RT = Ty->getAsCanonical<RecordType>();
576 if (!RT)
577 return nullptr;
578
579 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
580 if (RD->isUnion())
581 return nullptr;
582 if (getRecordArgABI(Ty, getCXXABI()))
583 return nullptr;
584
585 // Reject C++ types with base classes.
586 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
587 if (CXXRD->getNumBases() != 0)
588 return nullptr;
589
590 SmallVector<const FieldDecl *, 8> Fields(RD->fields());
591
592 if (Fields.empty())
593 return nullptr;
594
595 auto IsFixedLengthRVVVector = [](const VectorType *VT) {
597 };
598
599 QualType CommonTy;
600 unsigned Count = 0;
601
602 // Single array field: struct { fixed-length RVV T a[N]; }
603 if (Fields.size() == 1) {
604 QualType FieldTy = Fields[0]->getType().getCanonicalType();
605 if (const ConstantArrayType *AT =
606 getContext().getAsConstantArrayType(FieldTy)) {
607 QualType EltTy = AT->getElementType().getCanonicalType();
608 if (const auto *VT = EltTy->getAs<VectorType>();
609 VT && IsFixedLengthRVVVector(VT)) {
610 CommonTy = EltTy;
611 Count = AT->getZExtSize();
612 }
613 }
614 }
615
616 // All fields are the same fixed-length RVV vector type (data or mask).
617 if (CommonTy.isNull()) {
618 if (Fields.size() > 8)
619 return nullptr;
620 for (const FieldDecl *FD : Fields) {
621 QualType FieldTy = FD->getType().getCanonicalType();
622 const auto *VT = FieldTy->getAs<VectorType>();
623 if (!VT || !IsFixedLengthRVVVector(VT))
624 return nullptr;
625 if (CommonTy.isNull())
626 CommonTy = FieldTy;
627 else if (!getContext().hasSameType(CommonTy, FieldTy))
628 return nullptr;
629 }
630 Count = Fields.size();
631 }
632
633 if (Count == 0 || Count > 8)
634 return nullptr;
635
636 const auto *VT = CommonTy->castAs<VectorType>();
637 llvm::Type *EltType = CGT.ConvertType(VT->getElementType());
638 unsigned MinElts = getRVVFixedLengthMinElts(VT);
639
640 // Ensure total register usage does not exceed 8. Each vector occupies
641 // max(1, LMUL) registers.
642 uint64_t RegsPerVec =
643 llvm::divideCeil((uint64_t)MinElts * EltType->getScalarSizeInBits(),
644 llvm::RISCV::RVVBitsPerBlock);
645 if (Count > 1 && Count * RegsPerVec > 8)
646 return nullptr;
647
648 if (Count == 1)
649 return llvm::ScalableVectorType::get(EltType, MinElts);
650
651 unsigned I8EltCount =
652 llvm::divideCeil((uint64_t)MinElts * EltType->getScalarSizeInBits(), 8);
653 auto *I8Vec = llvm::ScalableVectorType::get(
654 llvm::Type::getInt8Ty(getVMContext()), I8EltCount);
655 return llvm::TargetExtType::get(getVMContext(), "riscv.vector.tuple", I8Vec,
656 Count);
657}
658
659llvm::FixedVectorType *
660RISCVABIInfo::getVLSCCCompatibleType(llvm::FixedVectorType *FixedVecTy) const {
661 llvm::Type *EltType = FixedVecTy->getElementType();
662 const TargetInfo &TI = getContext().getTargetInfo();
663 if ((EltType->isHalfTy() && !TI.hasFeature("zvfhmin")) ||
664 (EltType->isBFloatTy() &&
665 !(TI.hasFeature("zvfbfmin") || TI.hasFeature("experimental-zvfbfa"))) ||
666 (EltType->isFloatTy() && !TI.hasFeature("zve32f")) ||
667 (EltType->isDoubleTy() && !TI.hasFeature("zve64d")) ||
668 (EltType->isIntegerTy(64) && !TI.hasFeature("zve64x")) ||
669 EltType->isIntegerTy(128))
670 return llvm::FixedVectorType::get(llvm::Type::getInt8Ty(getVMContext()),
671 FixedVecTy->getNumElements() *
672 EltType->getScalarSizeInBits() / 8);
673 return FixedVecTy;
674}
675
676// Fixed-length RVV vectors are represented as scalable vectors in function
677// args/return and must be coerced from fixed vectors.
678ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty, unsigned ABIVLen) const {
679 assert(Ty->isVectorType() && "expected vector type!");
680
681 const auto *VT = Ty->castAs<VectorType>();
682 assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
683
684 auto VScale = getContext().getTargetInfo().getVScaleRange(
685 getContext().getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming);
686
687 unsigned NumElts;
688 llvm::Type *EltType;
690 NumElts = VT->getRVVFixedLengthMaskLanes();
691 EltType = llvm::Type::getInt1Ty(getVMContext());
692 } else {
693 assert((VT->getVectorKind() == VectorKind::Generic ||
695 "Unexpected vector kind");
696 NumElts = VT->getNumElements();
697 EltType = CGT.ConvertType(VT->getElementType());
698 }
699
700 llvm::ScalableVectorType *ResType;
701
702 if (ABIVLen == 0) {
703 unsigned MinScalableElts;
705 // Use the LMUL of the type the typedef was written against.
706 MinScalableElts = getRVVFixedLengthDataMinElts(
707 VT->getVectorKind(), EltType->getScalarSizeInBits());
709 // Use the ratio of the vbool<R>_t type the typedef was written against.
710 MinScalableElts = getRVVFixedLengthMaskMinElts(VT->getVectorKind());
711 } else {
712 // The MinNumElts is simplified from equation:
713 // NumElts / VScale =
714 // (EltSize * NumElts / (VScale * RVVBitsPerBlock))
715 // * (RVVBitsPerBlock / EltSize)
716 MinScalableElts = NumElts / VScale->first;
717 }
718 ResType = llvm::ScalableVectorType::get(EltType, MinScalableElts);
719 } else {
720 // Check registers needed <= 8.
721 if ((EltType->getScalarSizeInBits() * NumElts / ABIVLen) > 8)
722 return getNaturalAlignIndirect(
723 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
724 /*ByVal=*/false);
725
726 // Generic vector
727 // The number of elements needs to be at least 1.
728 llvm::FixedVectorType *VLSTy =
729 getVLSCCCompatibleType(llvm::FixedVectorType::get(EltType, NumElts));
730 ResType = llvm::ScalableVectorType::get(
731 VLSTy->getElementType(),
732 llvm::divideCeil(VLSTy->getNumElements() * llvm::RISCV::RVVBitsPerBlock,
733 ABIVLen));
734 }
735
736 return ABIArgInfo::getDirect(ResType);
737}
738
739ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
740 int &ArgGPRsLeft,
741 int &ArgFPRsLeft,
742 unsigned ABIVLen) const {
743 assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
745
746 // Structures with either a non-trivial destructor or a non-trivial
747 // copy constructor are always passed indirectly.
748 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
749 if (ArgGPRsLeft)
750 ArgGPRsLeft -= 1;
751 return getNaturalAlignIndirect(
752 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
753 /*ByVal=*/RAA == CGCXXABI::RAA_DirectInMemory);
754 }
755
756 uint64_t Size = getContext().getTypeSize(Ty);
757
758 // Ignore empty structs/unions whose size is zero. According to the calling
759 // convention empty structs/unions are required to be sized types in C++.
760 if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
761 return ABIArgInfo::getIgnore();
762
763 // Pass floating point values via FPRs if possible.
764 if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
765 FLen >= Size && ArgFPRsLeft) {
766 ArgFPRsLeft--;
767 return ABIArgInfo::getDirect();
768 }
769
770 // Complex types for the hard float ABI must be passed direct rather than
771 // using CoerceAndExpand.
772 if (IsFixed && Ty->isComplexType() && FLen && ArgFPRsLeft >= 2) {
773 QualType EltTy = Ty->castAs<ComplexType>()->getElementType();
774 if (getContext().getTypeSize(EltTy) <= FLen) {
775 ArgFPRsLeft -= 2;
776 return ABIArgInfo::getDirect();
777 }
778 }
779
780 if (IsFixed && FLen && Ty->isStructureOrClassType()) {
781 llvm::Type *Field1Ty = nullptr;
782 llvm::Type *Field2Ty = nullptr;
783 CharUnits Field1Off = CharUnits::Zero();
784 CharUnits Field2Off = CharUnits::Zero();
785 int NeededArgGPRs = 0;
786 int NeededArgFPRs = 0;
787 bool IsCandidate =
788 detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off,
789 NeededArgGPRs, NeededArgFPRs);
790 if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft &&
791 NeededArgFPRs <= ArgFPRsLeft) {
792 ArgGPRsLeft -= NeededArgGPRs;
793 ArgFPRsLeft -= NeededArgFPRs;
794 return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty,
795 Field2Off);
796 }
797 }
798
799 if (IsFixed && Ty->isStructureOrClassType()) {
800 if (llvm::Type *CoerceTy = detectHomogeneousRVVFixedLengthStruct(Ty))
801 return ABIArgInfo::getTargetSpecific(CoerceTy);
802
803 if (llvm::Type *VLSType = detectVLSCCEligibleStruct(Ty, ABIVLen))
804 return ABIArgInfo::getTargetSpecific(VLSType);
805 }
806
807 uint64_t NeededAlign = getContext().getTypeAlign(Ty);
808 // Determine the number of GPRs needed to pass the current argument
809 // according to the ABI. 2*XLen-aligned varargs are passed in "aligned"
810 // register pairs, so may consume 3 registers.
811 // TODO: To be compatible with GCC's behaviors, we don't align registers
812 // currently if we are using ILP32E calling convention. This behavior may be
813 // changed when RV32E/ILP32E is ratified.
814 int NeededArgGPRs = 1;
815 if (!IsFixed && NeededAlign == 2 * XLen)
816 NeededArgGPRs = 2 + (EABI ? 0 : (ArgGPRsLeft % 2));
817 else if (Size > XLen && Size <= 2 * XLen)
818 NeededArgGPRs = 2;
819
820 if (NeededArgGPRs > ArgGPRsLeft) {
821 NeededArgGPRs = ArgGPRsLeft;
822 }
823
824 ArgGPRsLeft -= NeededArgGPRs;
825
826 if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) {
827 // Treat an enum type as its underlying type.
828 if (const auto *ED = Ty->getAsEnumDecl())
829 Ty = ED->getIntegerType();
830
831 if (const auto *EIT = Ty->getAs<BitIntType>()) {
832
833 if (XLen == 64 && EIT->getNumBits() == 32)
834 return extendType(Ty, CGT.ConvertType(Ty));
835
836 if (EIT->getNumBits() <= 2 * XLen)
837 return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty));
838 return getNaturalAlignIndirect(
839 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
840 /*ByVal=*/false);
841 }
842
843 // All integral types are promoted to XLen width
844 if (Size < XLen && Ty->isIntegralOrEnumerationType())
845 return extendType(Ty, CGT.ConvertType(Ty));
846
847 return ABIArgInfo::getDirect();
848 }
849
850 // TODO: _BitInt is not handled yet in VLS calling convention since _BitInt
851 // ABI is also not merged yet in RISC-V:
852 // https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/419
853 if (const VectorType *VT = Ty->getAs<VectorType>();
854 VT && !VT->getElementType()->isBitIntType()) {
856 return coerceVLSVector(Ty);
857 if (VT->getVectorKind() == VectorKind::Generic && ABIVLen != 0)
858 // Generic vector without riscv_vls_cc should fall through and pass by
859 // reference.
860 return coerceVLSVector(Ty, ABIVLen);
861 }
862
863 // Aggregates which are <= 2*XLen will be passed in registers if possible,
864 // so coerce to integers.
865 if (Size <= 2 * XLen) {
866 unsigned Alignment = getContext().getTypeAlign(Ty);
867
868 if (Size <= XLen) {
869 // Use the smallest integer type we can.
871 llvm::IntegerType::get(getVMContext(), Size));
872 }
873 // Use 2*XLen if 2*XLen alignment is required.
874 if (Alignment == 2 * XLen)
876 llvm::IntegerType::get(getVMContext(), 2 * XLen));
877 // Use 2-element XLen array if only XLen alignment is required.
879 llvm::ArrayType::get(llvm::IntegerType::get(getVMContext(), XLen), 2));
880 }
881 return getNaturalAlignIndirect(
882 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
883 /*ByVal=*/false);
884}
885
886ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy,
887 unsigned ABIVLen) const {
888 if (RetTy->isVoidType())
889 return ABIArgInfo::getIgnore();
890
891 int ArgGPRsLeft = 2;
892 int ArgFPRsLeft = FLen ? 2 : 0;
893
894 // The rules for return and argument types are the same, so defer to
895 // classifyArgumentType.
896 return classifyArgumentType(RetTy, /*IsFixed=*/true, ArgGPRsLeft, ArgFPRsLeft,
897 ABIVLen);
898}
899
900RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
901 QualType Ty, AggValueSlot Slot) const {
902 CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
903
904 // Empty records are ignored for parameter passing purposes.
905 if (isEmptyRecord(getContext(), Ty, true))
906 return Slot.asRValue();
907
908 auto TInfo = getContext().getTypeInfoInChars(Ty);
909
910 // TODO: To be compatible with GCC's behaviors, we force arguments with
911 // 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`,
912 // `unsigned long long`, `double` and `__int128` to have XLEN-byte alignment
913 // for ILP32E and LP64E. This behavior may be changed when RV32E/ILP32E is
914 // ratified.
915 if (EABI)
916 TInfo.Align = std::min(TInfo.Align, SlotSize);
917
918 // Arguments bigger than 2*Xlen bytes are passed indirectly.
919 bool IsIndirect = TInfo.Width > 2 * SlotSize;
920
921 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo, SlotSize,
922 /*AllowHigherAlign=*/true, Slot);
923}
924
925ABIArgInfo RISCVABIInfo::extendType(QualType Ty, llvm::Type *CoerceTy) const {
926 int TySize = getContext().getTypeSize(Ty);
927 // RV64 ABI requires unsigned 32 bit integers to be sign extended.
928 if (XLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
929 return ABIArgInfo::getSignExtend(Ty, CoerceTy);
930 return ABIArgInfo::getExtend(Ty, CoerceTy);
931}
932
933llvm::Value *RISCVABIInfo::createCoercedLoad(Address Src, const ABIArgInfo &AI,
934 CodeGenFunction &CGF) const {
935 llvm::Type *Ty = AI.getCoerceToType();
936 llvm::Type *SrcTy = Src.getElementType();
937 llvm::StructType *SrcSTy = cast<llvm::StructType>(SrcTy);
938 assert((Ty->isScalableTy() || Ty->isTargetExtTy()) &&
939 "Only scalable vector type and vector tuple type are allowed for load "
940 "type.");
941 if (llvm::TargetExtType *TupTy = dyn_cast<llvm::TargetExtType>(Ty)) {
942 // In RISC-V VLS calling convention, struct of fixed vectors or struct of
943 // array of fixed vector of length >1 might be lowered using vector tuple
944 // type, we consider it as a valid load, e.g.
945 // struct i32x4x2 {
946 // __attribute__((vector_size(16))) int i;
947 // __attribute__((vector_size(16))) int i;
948 // };
949 // or
950 // struct i32x4 {
951 // __attribute__((vector_size(16))) int i[2];
952 // };
953 // is lowered to target("riscv.vector.tuple", <vscale x 8 x i8>, 2)
954 // when ABI_VLEN = 128 bits, please checkout
955 // clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c
956 // for more information.
957 assert(TupTy->getName() == "riscv.vector.tuple");
958 llvm::Type *EltTy = TupTy->getTypeParameter(0);
959 unsigned NumElts = TupTy->getIntParameter(0);
960
961 if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(SrcSTy->getElementType(0)))
962 Src = Src.withElementType(ArrayTy);
963
964 // Perform extract element and load
965 llvm::Value *TupleVal = llvm::PoisonValue::get(Ty);
966 auto *Load = CGF.Builder.CreateLoad(Src);
967 for (unsigned i = 0; i < NumElts; ++i) {
968 // Extract from struct
969 llvm::Value *ExtractFromLoad = CGF.Builder.CreateExtractValue(Load, i);
970 auto *FixedVecTy =
971 cast<llvm::FixedVectorType>(ExtractFromLoad->getType());
972 llvm::FixedVectorType *VLSTy = getVLSCCCompatibleType(FixedVecTy);
973 if (VLSTy != FixedVecTy)
974 ExtractFromLoad = CGF.Builder.CreateBitCast(ExtractFromLoad, VLSTy);
975 // Element in vector tuple type is always i8, so we need to cast back to
976 // it's original element type.
977 EltTy =
978 cast<llvm::ScalableVectorType>(llvm::VectorType::getWithSizeAndScalar(
979 cast<llvm::VectorType>(EltTy), VLSTy));
980 llvm::Value *VectorVal = llvm::PoisonValue::get(EltTy);
981 // Insert to scalable vector
982 VectorVal = CGF.Builder.CreateInsertVector(
983 EltTy, VectorVal, ExtractFromLoad, uint64_t(0), "cast.scalable");
984 // Insert scalable vector to vector tuple
985 llvm::Value *Idx = CGF.Builder.getInt32(i);
986 TupleVal =
987 CGF.Builder.CreateIntrinsic(llvm::Intrinsic::riscv_tuple_insert,
988 {Ty, EltTy}, {TupleVal, VectorVal, Idx});
989 }
990 return TupleVal;
991 }
992
993 // In RISC-V VLS calling convention, struct of fixed vector or struct of
994 // fixed vector array of length 1 might be lowered using scalable vector,
995 // we consider it as a valid load, e.g.
996 // struct i32x4 {
997 // __attribute__((vector_size(16))) int i;
998 // };
999 // or
1000 // struct i32x4 {
1001 // __attribute__((vector_size(16))) int i[1];
1002 // };
1003 // is lowered to <vscale x 2 x i32>
1004 // when ABI_VLEN = 128 bits, please checkout
1005 // clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c
1006 // for more information.
1007 auto *ScalableDstTy = cast<llvm::ScalableVectorType>(Ty);
1008 SrcTy = SrcSTy->getElementType(0);
1009 if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(SrcTy))
1010 SrcTy = ArrayTy->getElementType();
1011 Src = Src.withElementType(SrcTy);
1012 auto *FixedSrcTy = cast<llvm::FixedVectorType>(SrcTy);
1013 llvm::Value *Load = CGF.Builder.CreateLoad(Src);
1014 llvm::FixedVectorType *VLSTy = getVLSCCCompatibleType(FixedSrcTy);
1015 if (VLSTy != FixedSrcTy)
1016 Load = CGF.Builder.CreateBitCast(Load, VLSTy);
1017 auto *VectorVal = llvm::PoisonValue::get(ScalableDstTy);
1018 llvm::Value *Result = CGF.Builder.CreateInsertVector(
1019 ScalableDstTy, VectorVal, Load, uint64_t(0), "cast.scalable");
1020 return Result;
1021}
1022
1023void RISCVABIInfo::createCoercedStore(llvm::Value *Val, Address Dst,
1024 const ABIArgInfo &AI, bool DestIsVolatile,
1025 CodeGenFunction &CGF) const {
1026 llvm::Type *SrcTy = Val->getType();
1027 llvm::StructType *DstSTy = cast<llvm::StructType>(Dst.getElementType());
1028 assert((SrcTy->isScalableTy() || SrcTy->isTargetExtTy()) &&
1029 "Only scalable vector type and vector tuple type are allowed for "
1030 "store value.");
1031 if (llvm::TargetExtType *TupTy = dyn_cast<llvm::TargetExtType>(SrcTy)) {
1032 // In RISC-V VLS calling convention, struct of fixed vectors or struct
1033 // of array of fixed vector of length >1 might be lowered using vector
1034 // tuple type, we consider it as a valid load, e.g.
1035 // struct i32x4x2 {
1036 // __attribute__((vector_size(16))) int i;
1037 // __attribute__((vector_size(16))) int i;
1038 // };
1039 // or
1040 // struct i32x4 {
1041 // __attribute__((vector_size(16))) int i[2];
1042 // };
1043 // is lowered to target("riscv.vector.tuple", <vscale x 8 x i8>, 2)
1044 // when ABI_VLEN = 128 bits, please checkout
1045 // clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c
1046 // for more information.
1047 assert(TupTy->getName() == "riscv.vector.tuple");
1048 llvm::Type *EltTy = TupTy->getTypeParameter(0);
1049 unsigned NumElts = TupTy->getIntParameter(0);
1050
1051 llvm::Type *FixedVecTy = DstSTy->getElementType(0);
1052 if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(DstSTy->getElementType(0))) {
1053 Dst = Dst.withElementType(ArrayTy);
1054 FixedVecTy = ArrayTy->getArrayElementType();
1055 }
1056
1057 llvm::FixedVectorType *VLSTy =
1058 getVLSCCCompatibleType(cast<llvm::FixedVectorType>(FixedVecTy));
1059
1060 // Perform extract element and store
1061 for (unsigned i = 0; i < NumElts; ++i) {
1062 // Element in vector tuple type is always i8, so we need to cast back
1063 // to it's original element type.
1064 EltTy =
1065 cast<llvm::ScalableVectorType>(llvm::VectorType::getWithSizeAndScalar(
1066 cast<llvm::VectorType>(EltTy), VLSTy));
1067 // Extract scalable vector from tuple
1068 llvm::Value *Idx = CGF.Builder.getInt32(i);
1069 auto *TupleElement = CGF.Builder.CreateIntrinsic(
1070 llvm::Intrinsic::riscv_tuple_extract, {EltTy, TupTy}, {Val, Idx});
1071
1072 // Extract fixed vector from scalable vector
1073 llvm::Value *ExtractVec =
1074 CGF.Builder.CreateExtractVector(VLSTy, TupleElement, uint64_t(0));
1075 if (VLSTy != FixedVecTy)
1076 ExtractVec = CGF.Builder.CreateBitCast(ExtractVec, FixedVecTy);
1077 // Store fixed vector to corresponding address
1078 Address EltPtr = Address::invalid();
1079 if (Dst.getElementType()->isStructTy())
1080 EltPtr = CGF.Builder.CreateStructGEP(Dst, i);
1081 else
1082 EltPtr = CGF.Builder.CreateConstArrayGEP(Dst, i);
1083 auto *I = CGF.Builder.CreateStore(ExtractVec, EltPtr, DestIsVolatile);
1084 CGF.addInstToCurrentSourceAtom(I, ExtractVec);
1085 }
1086 return;
1087 }
1088
1089 // In RISC-V VLS calling convention, struct of fixed vector or struct of
1090 // fixed vector array of length 1 might be lowered using scalable
1091 // vector, we consider it as a valid load, e.g.
1092 // struct i32x4 {
1093 // __attribute__((vector_size(16))) int i;
1094 // };
1095 // or
1096 // struct i32x4 {
1097 // __attribute__((vector_size(16))) int i[1];
1098 // };
1099 // is lowered to <vscale x 2 x i32>
1100 // when ABI_VLEN = 128 bits, please checkout
1101 // clang/test/CodeGen/RISCV/riscv-vector-callingconv-llvm-ir.c
1102 // for more information.
1103 llvm::Type *EltTy = DstSTy->getElementType(0);
1104 if (auto *ArrayTy = dyn_cast<llvm::ArrayType>(EltTy)) {
1105 assert(ArrayTy->getNumElements() == 1);
1106 EltTy = ArrayTy->getElementType();
1107 }
1108 auto *FixedVecTy = cast<llvm::FixedVectorType>(EltTy);
1109 llvm::FixedVectorType *VLSTy = getVLSCCCompatibleType(FixedVecTy);
1110 llvm::Value *Coerced =
1111 CGF.Builder.CreateExtractVector(VLSTy, Val, uint64_t(0));
1112 if (VLSTy != FixedVecTy)
1113 Coerced = CGF.Builder.CreateBitCast(Coerced, FixedVecTy);
1114 auto *I = CGF.Builder.CreateStore(Coerced, Dst, DestIsVolatile);
1115 CGF.addInstToCurrentSourceAtom(I, Val);
1116}
1117
1118namespace {
1119class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
1120public:
1121 RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned XLen,
1122 unsigned FLen, bool EABI)
1123 : TargetCodeGenInfo(
1124 std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) {
1125 SwiftInfo =
1126 std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
1127 }
1128
1129 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
1130 CodeGen::CodeGenModule &CGM) const override {
1131 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
1132 if (!FD) return;
1133
1134 auto *Fn = cast<llvm::Function>(GV);
1135
1136 if (CGM.getCodeGenOpts().CFProtectionReturn)
1137 Fn->addFnAttr("hw-shadow-stack");
1138
1139 const auto *Attr = FD->getAttr<RISCVInterruptAttr>();
1140 if (!Attr)
1141 return;
1142
1143 StringRef Kind = "machine";
1144 bool HasSiFiveCLICPreemptible = false;
1145 bool HasSiFiveCLICStackSwap = false;
1146 for (RISCVInterruptAttr::InterruptType type : Attr->interrupt()) {
1147 switch (type) {
1148 case RISCVInterruptAttr::machine:
1149 // Do not update `Kind` because `Kind` is already "machine", or the
1150 // kinds also contains SiFive types which need to be applied.
1151 break;
1152 case RISCVInterruptAttr::supervisor:
1153 Kind = "supervisor";
1154 break;
1155 case RISCVInterruptAttr::rnmi:
1156 Kind = "rnmi";
1157 break;
1158 case RISCVInterruptAttr::qcinest:
1159 Kind = "qci-nest";
1160 break;
1161 case RISCVInterruptAttr::qcinonest:
1162 Kind = "qci-nonest";
1163 break;
1164 // There are three different LLVM IR attribute values for SiFive CLIC
1165 // interrupt kinds, one for each kind and one extra for their combination.
1166 case RISCVInterruptAttr::SiFiveCLICPreemptible: {
1167 HasSiFiveCLICPreemptible = true;
1168 Kind = HasSiFiveCLICStackSwap ? "SiFive-CLIC-preemptible-stack-swap"
1169 : "SiFive-CLIC-preemptible";
1170 break;
1171 }
1172 case RISCVInterruptAttr::SiFiveCLICStackSwap: {
1173 HasSiFiveCLICStackSwap = true;
1174 Kind = HasSiFiveCLICPreemptible ? "SiFive-CLIC-preemptible-stack-swap"
1175 : "SiFive-CLIC-stack-swap";
1176 break;
1177 }
1178 }
1179 }
1180
1181 Fn->addFnAttr("interrupt", Kind);
1182 }
1183};
1184} // namespace
1185
1186std::unique_ptr<TargetCodeGenInfo>
1188 unsigned FLen, bool EABI) {
1189 return std::make_unique<RISCVTargetCodeGenInfo>(CGM.getTypes(), XLen, FLen,
1190 EABI);
1191}
static unsigned getRVVFixedLengthMaskMinElts(VectorKind VK)
Minimum element count of the scalable vector a vbool<R>_t mask is coerced to, i.e.
Definition RISCV.cpp:433
static unsigned getRVVFixedLengthDataMinElts(VectorKind VK, unsigned EltSizeInBits)
Minimum element count of the scalable vector an RVV fixed-length data vector is coerced to,...
Definition RISCV.cpp:419
Result
Implement __builtin_bit_cast and related operations.
#define CC_VLS_CASE(ABI_VLEN)
static CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type)
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Attr - This represents one attribute.
Definition Attr.h:47
bool isZero() const
Test whether the quantity equals zero.
Definition CharUnits.h:101
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
Definition CharUnits.h:171
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
Definition CharUnits.h:155
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Definition CharUnits.h:122
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:58
static CharUnits Zero()
Construct a CharUnits quantity of zero.
Definition CharUnits.h:52
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
static ABIArgInfo getIgnore()
static ABIArgInfo getTargetSpecific(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
llvm::Type * getCoerceToType() const
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
Definition ABIInfo.cpp:201
static Address invalid()
Definition Address.h:176
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Definition Address.h:209
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Definition Address.h:276
RValue asRValue() const
Definition CGValue.h:711
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition CGBuilder.h:148
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
Definition CGBuilder.h:253
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Definition CGBuilder.h:231
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition CGBuilder.h:120
RecordArgABI
Specify how one should pass an argument of a record type.
Definition CGCXXABI.h:150
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition CGCXXABI.h:158
FunctionType::ExtInfo getExtInfo() const
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
This class organizes the cross-function state that is used while generating LLVM code.
const CodeGenOptions & getCodeGenOpts() const
DefaultABIInfo - The default implementation for ABI specific details.
Definition ABIInfoImpl.h:21
CallingConv getCC() const
Definition TypeBase.h:4914
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
field_range fields() const
Definition Decl.h:4709
RecordDecl * getDefinitionOrSelf() const
Definition Decl.h:4694
bool isUnion() const
Definition Decl.h:4109
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
bool isVoidType() const
Definition TypeBase.h:9200
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
Definition Type.cpp:857
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
Definition Type.cpp:2483
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9498
bool isScalarType() const
Definition TypeBase.h:9310
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition TypeBase.h:9326
bool isBitIntType() const
Definition TypeBase.h:9090
bool isBuiltinType() const
Helper methods to distinguish type categories.
Definition TypeBase.h:8938
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
bool isStructureOrClassType() const
Definition Type.cpp:839
bool isVectorType() const
Definition TypeBase.h:8954
bool isRealFloatingType() const
Floating point categories.
Definition Type.cpp:2533
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:3002
bool isFloatingType() const
Definition Type.cpp:2517
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9431
unsigned getNumElements() const
Definition TypeBase.h:4413
unsigned getRVVFixedLengthMaskLanes() const
Return the number of lanes of an RVV fixed-length mask vector.
Definition TypeBase.h:4424
VectorKind getVectorKind() const
Definition TypeBase.h:4418
QualType getElementType() const
Definition TypeBase.h:4412
Definition SPIR.cpp:47
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:146
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, unsigned FLen, bool EABI)
Definition RISCV.cpp:1187
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
PRESERVE_NONE bool Ret(InterpState &S)
Definition Interp.h:276
@ Address
A pointer to a ValueDecl.
Definition Primitives.h:28
bool Load(InterpState &S, CodePtr OpPC)
Definition Interp.h:2189
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
bool isRVVFixedLengthDataVectorKind(VectorKind VK)
True if VK is one of the RVV fixed-length data vector kinds, i.e.
Definition TypeBase.h:4316
unsigned getRVVFixedLengthMaskRatioLog2(VectorKind VK)
Return log2 of the R of the vbool<R>_t type recorded in an RVV fixed-length mask vector kind: Ratio1 ...
Definition TypeBase.h:4345
bool isRVVFixedLengthVectorKind(VectorKind VK)
True if VK is one of the RVV fixed-length data or mask vector kinds.
Definition TypeBase.h:4352
int getRVVFixedLengthDataLMulLog2(VectorKind VK)
Return log2 of the LMUL recorded in an RVV fixed-length data vector kind: MF8 -> -3,...
Definition TypeBase.h:4323
U cast(CodeGen::Address addr)
Definition Address.h:327
bool isRVVFixedLengthMaskVectorKind(VectorKind VK)
True if VK is one of the RVV fixed-length mask vector kinds, i.e.
Definition TypeBase.h:4338
unsigned long uint64_t