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