1 //===- AArch64.cpp --------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABIInfoImpl.h"
10 #include "TargetInfo.h"
11 #include "clang/AST/Decl.h"
12 #include "clang/Basic/DiagnosticFrontend.h"
13 #include "llvm/TargetParser/AArch64TargetParser.h"
15 using namespace clang
;
16 using namespace clang::CodeGen
;
18 //===----------------------------------------------------------------------===//
19 // AArch64 ABI Implementation
20 //===----------------------------------------------------------------------===//
24 class AArch64ABIInfo
: public ABIInfo
{
28 AArch64ABIInfo(CodeGenTypes
&CGT
, AArch64ABIKind Kind
)
29 : ABIInfo(CGT
), Kind(Kind
) {}
31 bool isSoftFloat() const { return Kind
== AArch64ABIKind::AAPCSSoft
; }
34 AArch64ABIKind
getABIKind() const { return Kind
; }
35 bool isDarwinPCS() const { return Kind
== AArch64ABIKind::DarwinPCS
; }
37 ABIArgInfo
classifyReturnType(QualType RetTy
, bool IsVariadicFn
) const;
38 ABIArgInfo
classifyArgumentType(QualType RetTy
, bool IsVariadicFn
,
39 bool IsNamedArg
, unsigned CallingConvention
,
40 unsigned &NSRN
, unsigned &NPRN
) const;
41 llvm::Type
*convertFixedToScalableVectorType(const VectorType
*VT
) const;
42 ABIArgInfo
coerceIllegalVector(QualType Ty
, unsigned &NSRN
,
43 unsigned &NPRN
) const;
44 ABIArgInfo
coerceAndExpandPureScalableAggregate(
45 QualType Ty
, bool IsNamedArg
, unsigned NVec
, unsigned NPred
,
46 const SmallVectorImpl
<llvm::Type
*> &UnpaddedCoerceToSeq
, unsigned &NSRN
,
47 unsigned &NPRN
) const;
48 bool isHomogeneousAggregateBaseType(QualType Ty
) const override
;
49 bool isHomogeneousAggregateSmallEnough(const Type
*Ty
,
50 uint64_t Members
) const override
;
51 bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const override
;
53 bool isIllegalVectorType(QualType Ty
) const;
55 bool passAsAggregateType(QualType Ty
) const;
56 bool passAsPureScalableType(QualType Ty
, unsigned &NV
, unsigned &NP
,
57 SmallVectorImpl
<llvm::Type
*> &CoerceToSeq
) const;
59 void flattenType(llvm::Type
*Ty
,
60 SmallVectorImpl
<llvm::Type
*> &Flattened
) const;
62 void computeInfo(CGFunctionInfo
&FI
) const override
{
63 if (!::classifyReturnType(getCXXABI(), FI
, *this))
65 classifyReturnType(FI
.getReturnType(), FI
.isVariadic());
68 unsigned NSRN
= 0, NPRN
= 0;
69 for (auto &it
: FI
.arguments()) {
70 const bool IsNamedArg
=
71 !FI
.isVariadic() || ArgNo
< FI
.getRequiredArgs().getNumRequiredArgs();
73 it
.info
= classifyArgumentType(it
.type
, FI
.isVariadic(), IsNamedArg
,
74 FI
.getCallingConvention(), NSRN
, NPRN
);
78 RValue
EmitDarwinVAArg(Address VAListAddr
, QualType Ty
, CodeGenFunction
&CGF
,
79 AggValueSlot Slot
) const;
81 RValue
EmitAAPCSVAArg(Address VAListAddr
, QualType Ty
, CodeGenFunction
&CGF
,
82 AArch64ABIKind Kind
, AggValueSlot Slot
) const;
84 RValue
EmitVAArg(CodeGenFunction
&CGF
, Address VAListAddr
, QualType Ty
,
85 AggValueSlot Slot
) const override
{
86 llvm::Type
*BaseTy
= CGF
.ConvertType(Ty
);
87 if (isa
<llvm::ScalableVectorType
>(BaseTy
))
88 llvm::report_fatal_error("Passing SVE types to variadic functions is "
89 "currently not supported");
91 return Kind
== AArch64ABIKind::Win64
92 ? EmitMSVAArg(CGF
, VAListAddr
, Ty
, Slot
)
93 : isDarwinPCS() ? EmitDarwinVAArg(VAListAddr
, Ty
, CGF
, Slot
)
94 : EmitAAPCSVAArg(VAListAddr
, Ty
, CGF
, Kind
, Slot
);
97 RValue
EmitMSVAArg(CodeGenFunction
&CGF
, Address VAListAddr
, QualType Ty
,
98 AggValueSlot Slot
) const override
;
100 bool allowBFloatArgsAndRet() const override
{
101 return getTarget().hasBFloat16Type();
104 using ABIInfo::appendAttributeMangling
;
105 void appendAttributeMangling(TargetClonesAttr
*Attr
, unsigned Index
,
106 raw_ostream
&Out
) const override
;
107 void appendAttributeMangling(StringRef AttrStr
,
108 raw_ostream
&Out
) const override
;
111 class AArch64SwiftABIInfo
: public SwiftABIInfo
{
113 explicit AArch64SwiftABIInfo(CodeGenTypes
&CGT
)
114 : SwiftABIInfo(CGT
, /*SwiftErrorInRegister=*/true) {}
116 bool isLegalVectorType(CharUnits VectorSize
, llvm::Type
*EltTy
,
117 unsigned NumElts
) const override
;
120 class AArch64TargetCodeGenInfo
: public TargetCodeGenInfo
{
122 AArch64TargetCodeGenInfo(CodeGenTypes
&CGT
, AArch64ABIKind Kind
)
123 : TargetCodeGenInfo(std::make_unique
<AArch64ABIInfo
>(CGT
, Kind
)) {
124 SwiftInfo
= std::make_unique
<AArch64SwiftABIInfo
>(CGT
);
127 StringRef
getARCRetainAutoreleasedReturnValueMarker() const override
{
128 return "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";
131 int getDwarfEHStackPointer(CodeGen::CodeGenModule
&M
) const override
{
135 bool doesReturnSlotInterfereWithArgs() const override
{ return false; }
137 void setTargetAttributes(const Decl
*D
, llvm::GlobalValue
*GV
,
138 CodeGen::CodeGenModule
&CGM
) const override
{
139 const FunctionDecl
*FD
= dyn_cast_or_null
<FunctionDecl
>(D
);
143 TargetInfo::BranchProtectionInfo
BPI(CGM
.getLangOpts());
145 if (const auto *TA
= FD
->getAttr
<TargetAttr
>()) {
146 ParsedTargetAttr Attr
=
147 CGM
.getTarget().parseTargetAttr(TA
->getFeaturesStr());
148 if (!Attr
.BranchProtection
.empty()) {
150 (void)CGM
.getTarget().validateBranchProtection(Attr
.BranchProtection
,
151 Attr
.CPU
, BPI
, Error
);
152 assert(Error
.empty());
155 auto *Fn
= cast
<llvm::Function
>(GV
);
156 setBranchProtectionFnAttributes(BPI
, *Fn
);
159 bool isScalarizableAsmOperand(CodeGen::CodeGenFunction
&CGF
,
160 llvm::Type
*Ty
) const override
{
161 if (CGF
.getTarget().hasFeature("ls64")) {
162 auto *ST
= dyn_cast
<llvm::StructType
>(Ty
);
163 if (ST
&& ST
->getNumElements() == 1) {
164 auto *AT
= dyn_cast
<llvm::ArrayType
>(ST
->getElementType(0));
165 if (AT
&& AT
->getNumElements() == 8 &&
166 AT
->getElementType()->isIntegerTy(64))
170 return TargetCodeGenInfo::isScalarizableAsmOperand(CGF
, Ty
);
173 void checkFunctionABI(CodeGenModule
&CGM
,
174 const FunctionDecl
*Decl
) const override
;
176 void checkFunctionCallABI(CodeGenModule
&CGM
, SourceLocation CallLoc
,
177 const FunctionDecl
*Caller
,
178 const FunctionDecl
*Callee
, const CallArgList
&Args
,
179 QualType ReturnType
) const override
;
181 bool wouldInliningViolateFunctionCallABI(
182 const FunctionDecl
*Caller
, const FunctionDecl
*Callee
) const override
;
185 // Diagnose calls between functions with incompatible Streaming SVE
187 void checkFunctionCallABIStreaming(CodeGenModule
&CGM
, SourceLocation CallLoc
,
188 const FunctionDecl
*Caller
,
189 const FunctionDecl
*Callee
) const;
190 // Diagnose calls which must pass arguments in floating-point registers when
191 // the selected target does not have floating-point registers.
192 void checkFunctionCallABISoftFloat(CodeGenModule
&CGM
, SourceLocation CallLoc
,
193 const FunctionDecl
*Caller
,
194 const FunctionDecl
*Callee
,
195 const CallArgList
&Args
,
196 QualType ReturnType
) const;
199 class WindowsAArch64TargetCodeGenInfo
: public AArch64TargetCodeGenInfo
{
201 WindowsAArch64TargetCodeGenInfo(CodeGenTypes
&CGT
, AArch64ABIKind K
)
202 : AArch64TargetCodeGenInfo(CGT
, K
) {}
204 void setTargetAttributes(const Decl
*D
, llvm::GlobalValue
*GV
,
205 CodeGen::CodeGenModule
&CGM
) const override
;
207 void getDependentLibraryOption(llvm::StringRef Lib
,
208 llvm::SmallString
<24> &Opt
) const override
{
209 Opt
= "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib
);
212 void getDetectMismatchOption(llvm::StringRef Name
, llvm::StringRef Value
,
213 llvm::SmallString
<32> &Opt
) const override
{
214 Opt
= "/FAILIFMISMATCH:\"" + Name
.str() + "=" + Value
.str() + "\"";
218 void WindowsAArch64TargetCodeGenInfo::setTargetAttributes(
219 const Decl
*D
, llvm::GlobalValue
*GV
, CodeGen::CodeGenModule
&CGM
) const {
220 AArch64TargetCodeGenInfo::setTargetAttributes(D
, GV
, CGM
);
221 if (GV
->isDeclaration())
223 addStackProbeTargetAttributes(D
, GV
, CGM
);
228 AArch64ABIInfo::convertFixedToScalableVectorType(const VectorType
*VT
) const {
229 assert(VT
->getElementType()->isBuiltinType() && "expected builtin type!");
231 if (VT
->getVectorKind() == VectorKind::SveFixedLengthPredicate
) {
232 assert(VT
->getElementType()->castAs
<BuiltinType
>()->getKind() ==
233 BuiltinType::UChar
&&
234 "unexpected builtin type for SVE predicate!");
235 return llvm::ScalableVectorType::get(llvm::Type::getInt1Ty(getVMContext()),
239 if (VT
->getVectorKind() == VectorKind::SveFixedLengthData
) {
240 const auto *BT
= VT
->getElementType()->castAs
<BuiltinType
>();
241 switch (BT
->getKind()) {
243 llvm_unreachable("unexpected builtin type for SVE vector!");
245 case BuiltinType::SChar
:
246 case BuiltinType::UChar
:
247 case BuiltinType::MFloat8
:
248 return llvm::ScalableVectorType::get(
249 llvm::Type::getInt8Ty(getVMContext()), 16);
251 case BuiltinType::Short
:
252 case BuiltinType::UShort
:
253 return llvm::ScalableVectorType::get(
254 llvm::Type::getInt16Ty(getVMContext()), 8);
256 case BuiltinType::Int
:
257 case BuiltinType::UInt
:
258 return llvm::ScalableVectorType::get(
259 llvm::Type::getInt32Ty(getVMContext()), 4);
261 case BuiltinType::Long
:
262 case BuiltinType::ULong
:
263 return llvm::ScalableVectorType::get(
264 llvm::Type::getInt64Ty(getVMContext()), 2);
266 case BuiltinType::Half
:
267 return llvm::ScalableVectorType::get(
268 llvm::Type::getHalfTy(getVMContext()), 8);
270 case BuiltinType::Float
:
271 return llvm::ScalableVectorType::get(
272 llvm::Type::getFloatTy(getVMContext()), 4);
274 case BuiltinType::Double
:
275 return llvm::ScalableVectorType::get(
276 llvm::Type::getDoubleTy(getVMContext()), 2);
278 case BuiltinType::BFloat16
:
279 return llvm::ScalableVectorType::get(
280 llvm::Type::getBFloatTy(getVMContext()), 8);
284 llvm_unreachable("expected fixed-length SVE vector");
287 ABIArgInfo
AArch64ABIInfo::coerceIllegalVector(QualType Ty
, unsigned &NSRN
,
288 unsigned &NPRN
) const {
289 assert(Ty
->isVectorType() && "expected vector type!");
291 const auto *VT
= Ty
->castAs
<VectorType
>();
292 if (VT
->getVectorKind() == VectorKind::SveFixedLengthPredicate
) {
293 assert(VT
->getElementType()->isBuiltinType() && "expected builtin type!");
294 assert(VT
->getElementType()->castAs
<BuiltinType
>()->getKind() ==
295 BuiltinType::UChar
&&
296 "unexpected builtin type for SVE predicate!");
297 NPRN
= std::min(NPRN
+ 1, 4u);
298 return ABIArgInfo::getDirect(llvm::ScalableVectorType::get(
299 llvm::Type::getInt1Ty(getVMContext()), 16));
302 if (VT
->getVectorKind() == VectorKind::SveFixedLengthData
) {
303 NSRN
= std::min(NSRN
+ 1, 8u);
304 return ABIArgInfo::getDirect(convertFixedToScalableVectorType(VT
));
307 uint64_t Size
= getContext().getTypeSize(Ty
);
308 // Android promotes <2 x i8> to i16, not i32
309 if ((isAndroid() || isOHOSFamily()) && (Size
<= 16)) {
310 llvm::Type
*ResType
= llvm::Type::getInt16Ty(getVMContext());
311 return ABIArgInfo::getDirect(ResType
);
314 llvm::Type
*ResType
= llvm::Type::getInt32Ty(getVMContext());
315 return ABIArgInfo::getDirect(ResType
);
318 NSRN
= std::min(NSRN
+ 1, 8u);
320 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2);
321 return ABIArgInfo::getDirect(ResType
);
324 NSRN
= std::min(NSRN
+ 1, 8u);
326 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4);
327 return ABIArgInfo::getDirect(ResType
);
330 return getNaturalAlignIndirect(Ty
, /*ByVal=*/false);
333 ABIArgInfo
AArch64ABIInfo::coerceAndExpandPureScalableAggregate(
334 QualType Ty
, bool IsNamedArg
, unsigned NVec
, unsigned NPred
,
335 const SmallVectorImpl
<llvm::Type
*> &UnpaddedCoerceToSeq
, unsigned &NSRN
,
336 unsigned &NPRN
) const {
337 if (!IsNamedArg
|| NSRN
+ NVec
> 8 || NPRN
+ NPred
> 4)
338 return getNaturalAlignIndirect(Ty
, /*ByVal=*/false);
342 // Handle SVE vector tuples.
343 if (Ty
->isSVESizelessBuiltinType())
344 return ABIArgInfo::getDirect();
346 llvm::Type
*UnpaddedCoerceToType
=
347 UnpaddedCoerceToSeq
.size() == 1
348 ? UnpaddedCoerceToSeq
[0]
349 : llvm::StructType::get(CGT
.getLLVMContext(), UnpaddedCoerceToSeq
,
352 SmallVector
<llvm::Type
*> CoerceToSeq
;
353 flattenType(CGT
.ConvertType(Ty
), CoerceToSeq
);
355 llvm::StructType::get(CGT
.getLLVMContext(), CoerceToSeq
, false);
357 return ABIArgInfo::getCoerceAndExpand(CoerceToType
, UnpaddedCoerceToType
);
360 ABIArgInfo
AArch64ABIInfo::classifyArgumentType(QualType Ty
, bool IsVariadicFn
,
362 unsigned CallingConvention
,
364 unsigned &NPRN
) const {
365 Ty
= useFirstFieldIfTransparentUnion(Ty
);
367 // Handle illegal vector types here.
368 if (isIllegalVectorType(Ty
))
369 return coerceIllegalVector(Ty
, NSRN
, NPRN
);
371 if (!passAsAggregateType(Ty
)) {
372 // Treat an enum type as its underlying type.
373 if (const EnumType
*EnumTy
= Ty
->getAs
<EnumType
>())
374 Ty
= EnumTy
->getDecl()->getIntegerType();
376 if (const auto *EIT
= Ty
->getAs
<BitIntType
>())
377 if (EIT
->getNumBits() > 128)
378 return getNaturalAlignIndirect(Ty
, false);
380 if (Ty
->isVectorType())
381 NSRN
= std::min(NSRN
+ 1, 8u);
382 else if (const auto *BT
= Ty
->getAs
<BuiltinType
>()) {
383 if (BT
->isFloatingPoint())
384 NSRN
= std::min(NSRN
+ 1, 8u);
386 switch (BT
->getKind()) {
387 case BuiltinType::SveBool
:
388 case BuiltinType::SveCount
:
389 NPRN
= std::min(NPRN
+ 1, 4u);
391 case BuiltinType::SveBoolx2
:
392 NPRN
= std::min(NPRN
+ 2, 4u);
394 case BuiltinType::SveBoolx4
:
395 NPRN
= std::min(NPRN
+ 4, 4u);
398 if (BT
->isSVESizelessBuiltinType())
400 NSRN
+ getContext().getBuiltinVectorTypeInfo(BT
).NumVectors
,
406 return (isPromotableIntegerTypeForABI(Ty
) && isDarwinPCS()
407 ? ABIArgInfo::getExtend(Ty
, CGT
.ConvertType(Ty
))
408 : ABIArgInfo::getDirect());
411 // Structures with either a non-trivial destructor or a non-trivial
412 // copy constructor are always indirect.
413 if (CGCXXABI::RecordArgABI RAA
= getRecordArgABI(Ty
, getCXXABI())) {
414 return getNaturalAlignIndirect(Ty
, /*ByVal=*/RAA
==
415 CGCXXABI::RAA_DirectInMemory
);
419 uint64_t Size
= getContext().getTypeSize(Ty
);
420 bool IsEmpty
= isEmptyRecord(getContext(), Ty
, true);
421 if (!Ty
->isSVESizelessBuiltinType() && (IsEmpty
|| Size
== 0)) {
422 // Empty records are ignored in C mode, and in C++ on Darwin.
423 if (!getContext().getLangOpts().CPlusPlus
|| isDarwinPCS())
424 return ABIArgInfo::getIgnore();
426 // In C++ mode, arguments which have sizeof() == 0 (which are non-standard
427 // C++) are ignored. This isn't defined by any standard, so we copy GCC's
430 return ABIArgInfo::getIgnore();
432 // Otherwise, they are passed as if they have a size of 1 byte.
433 return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
436 // Homogeneous Floating-point Aggregates (HFAs) need to be expanded.
437 const Type
*Base
= nullptr;
438 uint64_t Members
= 0;
439 bool IsWin64
= Kind
== AArch64ABIKind::Win64
||
440 CallingConvention
== llvm::CallingConv::Win64
;
441 bool IsWinVariadic
= IsWin64
&& IsVariadicFn
;
442 // In variadic functions on Windows, all composite types are treated alike,
443 // no special handling of HFAs/HVAs.
444 if (!IsWinVariadic
&& isHomogeneousAggregate(Ty
, Base
, Members
)) {
445 NSRN
= std::min(NSRN
+ Members
, uint64_t(8));
446 if (Kind
!= AArch64ABIKind::AAPCS
)
447 return ABIArgInfo::getDirect(
448 llvm::ArrayType::get(CGT
.ConvertType(QualType(Base
, 0)), Members
));
450 // For HFAs/HVAs, cap the argument alignment to 16, otherwise
451 // set it to 8 according to the AAPCS64 document.
453 getContext().getTypeUnadjustedAlignInChars(Ty
).getQuantity();
454 Align
= (Align
>= 16) ? 16 : 8;
455 return ABIArgInfo::getDirect(
456 llvm::ArrayType::get(CGT
.ConvertType(QualType(Base
, 0)), Members
), 0,
457 nullptr, true, Align
);
460 // In AAPCS named arguments of a Pure Scalable Type are passed expanded in
461 // registers, or indirectly if there are not enough registers.
462 if (Kind
== AArch64ABIKind::AAPCS
) {
463 unsigned NVec
= 0, NPred
= 0;
464 SmallVector
<llvm::Type
*> UnpaddedCoerceToSeq
;
465 if (passAsPureScalableType(Ty
, NVec
, NPred
, UnpaddedCoerceToSeq
) &&
467 return coerceAndExpandPureScalableAggregate(
468 Ty
, IsNamedArg
, NVec
, NPred
, UnpaddedCoerceToSeq
, NSRN
, NPRN
);
471 // Aggregates <= 16 bytes are passed directly in registers or on the stack.
474 if (Kind
== AArch64ABIKind::AAPCS
) {
475 Alignment
= getContext().getTypeUnadjustedAlign(Ty
);
476 Alignment
= Alignment
< 128 ? 64 : 128;
479 std::max(getContext().getTypeAlign(Ty
),
480 (unsigned)getTarget().getPointerWidth(LangAS::Default
));
482 Size
= llvm::alignTo(Size
, Alignment
);
484 // We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
485 // For aggregates with 16-byte alignment, we use i128.
486 llvm::Type
*BaseTy
= llvm::Type::getIntNTy(getVMContext(), Alignment
);
487 return ABIArgInfo::getDirect(
488 Size
== Alignment
? BaseTy
489 : llvm::ArrayType::get(BaseTy
, Size
/ Alignment
));
492 return getNaturalAlignIndirect(Ty
, /*ByVal=*/false);
495 ABIArgInfo
AArch64ABIInfo::classifyReturnType(QualType RetTy
,
496 bool IsVariadicFn
) const {
497 if (RetTy
->isVoidType())
498 return ABIArgInfo::getIgnore();
500 if (const auto *VT
= RetTy
->getAs
<VectorType
>()) {
501 if (VT
->getVectorKind() == VectorKind::SveFixedLengthData
||
502 VT
->getVectorKind() == VectorKind::SveFixedLengthPredicate
) {
503 unsigned NSRN
= 0, NPRN
= 0;
504 return coerceIllegalVector(RetTy
, NSRN
, NPRN
);
508 // Large vector types should be returned via memory.
509 if (RetTy
->isVectorType() && getContext().getTypeSize(RetTy
) > 128)
510 return getNaturalAlignIndirect(RetTy
);
512 if (!passAsAggregateType(RetTy
)) {
513 // Treat an enum type as its underlying type.
514 if (const EnumType
*EnumTy
= RetTy
->getAs
<EnumType
>())
515 RetTy
= EnumTy
->getDecl()->getIntegerType();
517 if (const auto *EIT
= RetTy
->getAs
<BitIntType
>())
518 if (EIT
->getNumBits() > 128)
519 return getNaturalAlignIndirect(RetTy
);
521 return (isPromotableIntegerTypeForABI(RetTy
) && isDarwinPCS()
522 ? ABIArgInfo::getExtend(RetTy
)
523 : ABIArgInfo::getDirect());
526 uint64_t Size
= getContext().getTypeSize(RetTy
);
527 if (!RetTy
->isSVESizelessBuiltinType() &&
528 (isEmptyRecord(getContext(), RetTy
, true) || Size
== 0))
529 return ABIArgInfo::getIgnore();
531 const Type
*Base
= nullptr;
532 uint64_t Members
= 0;
533 if (isHomogeneousAggregate(RetTy
, Base
, Members
) &&
534 !(getTarget().getTriple().getArch() == llvm::Triple::aarch64_32
&&
536 // Homogeneous Floating-point Aggregates (HFAs) are returned directly.
537 return ABIArgInfo::getDirect();
539 // In AAPCS return values of a Pure Scalable type are treated as a single
540 // named argument and passed expanded in registers, or indirectly if there are
541 // not enough registers.
542 if (Kind
== AArch64ABIKind::AAPCS
) {
543 unsigned NSRN
= 0, NPRN
= 0;
544 unsigned NVec
= 0, NPred
= 0;
545 SmallVector
<llvm::Type
*> UnpaddedCoerceToSeq
;
546 if (passAsPureScalableType(RetTy
, NVec
, NPred
, UnpaddedCoerceToSeq
) &&
548 return coerceAndExpandPureScalableAggregate(
549 RetTy
, /* IsNamedArg */ true, NVec
, NPred
, UnpaddedCoerceToSeq
, NSRN
,
553 // Aggregates <= 16 bytes are returned directly in registers or on the stack.
555 if (Size
<= 64 && getDataLayout().isLittleEndian()) {
556 // Composite types are returned in lower bits of a 64-bit register for LE,
557 // and in higher bits for BE. However, integer types are always returned
558 // in lower bits for both LE and BE, and they are not rounded up to
559 // 64-bits. We can skip rounding up of composite types for LE, but not for
560 // BE, otherwise composite types will be indistinguishable from integer
562 return ABIArgInfo::getDirect(
563 llvm::IntegerType::get(getVMContext(), Size
));
566 unsigned Alignment
= getContext().getTypeAlign(RetTy
);
567 Size
= llvm::alignTo(Size
, 64); // round up to multiple of 8 bytes
569 // We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
570 // For aggregates with 16-byte alignment, we use i128.
571 if (Alignment
< 128 && Size
== 128) {
572 llvm::Type
*BaseTy
= llvm::Type::getInt64Ty(getVMContext());
573 return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy
, Size
/ 64));
575 return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size
));
578 return getNaturalAlignIndirect(RetTy
);
581 /// isIllegalVectorType - check whether the vector type is legal for AArch64.
582 bool AArch64ABIInfo::isIllegalVectorType(QualType Ty
) const {
583 if (const VectorType
*VT
= Ty
->getAs
<VectorType
>()) {
584 // Check whether VT is a fixed-length SVE vector. These types are
585 // represented as scalable vectors in function args/return and must be
586 // coerced from fixed vectors.
587 if (VT
->getVectorKind() == VectorKind::SveFixedLengthData
||
588 VT
->getVectorKind() == VectorKind::SveFixedLengthPredicate
)
591 // Check whether VT is legal.
592 unsigned NumElements
= VT
->getNumElements();
593 uint64_t Size
= getContext().getTypeSize(VT
);
594 // NumElements should be power of 2.
595 if (!llvm::isPowerOf2_32(NumElements
))
598 // arm64_32 has to be compatible with the ARM logic here, which allows huge
599 // vectors for some reason.
600 llvm::Triple Triple
= getTarget().getTriple();
601 if (Triple
.getArch() == llvm::Triple::aarch64_32
&&
602 Triple
.isOSBinFormatMachO())
605 return Size
!= 64 && (Size
!= 128 || NumElements
== 1);
610 bool AArch64SwiftABIInfo::isLegalVectorType(CharUnits VectorSize
,
612 unsigned NumElts
) const {
613 if (!llvm::isPowerOf2_32(NumElts
))
615 if (VectorSize
.getQuantity() != 8 &&
616 (VectorSize
.getQuantity() != 16 || NumElts
== 1))
621 bool AArch64ABIInfo::isHomogeneousAggregateBaseType(QualType Ty
) const {
622 // For the soft-float ABI variant, no types are considered to be homogeneous
627 // Homogeneous aggregates for AAPCS64 must have base types of a floating
628 // point type or a short-vector type. This is the same as the 32-bit ABI,
629 // but with the difference that any floating-point type is allowed,
631 if (const BuiltinType
*BT
= Ty
->getAs
<BuiltinType
>()) {
632 if (BT
->isFloatingPoint())
634 } else if (const VectorType
*VT
= Ty
->getAs
<VectorType
>()) {
635 if (auto Kind
= VT
->getVectorKind();
636 Kind
== VectorKind::SveFixedLengthData
||
637 Kind
== VectorKind::SveFixedLengthPredicate
)
640 unsigned VecSize
= getContext().getTypeSize(VT
);
641 if (VecSize
== 64 || VecSize
== 128)
647 bool AArch64ABIInfo::isHomogeneousAggregateSmallEnough(const Type
*Base
,
648 uint64_t Members
) const {
652 bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
654 // AAPCS64 says that the rule for whether something is a homogeneous
655 // aggregate is applied to the output of the data layout decision. So
656 // anything that doesn't affect the data layout also does not affect
657 // homogeneity. In particular, zero-length bitfields don't stop a struct
658 // being homogeneous.
662 bool AArch64ABIInfo::passAsAggregateType(QualType Ty
) const {
663 if (Kind
== AArch64ABIKind::AAPCS
&& Ty
->isSVESizelessBuiltinType()) {
664 const auto *BT
= Ty
->castAs
<BuiltinType
>();
665 return !BT
->isSVECount() &&
666 getContext().getBuiltinVectorTypeInfo(BT
).NumVectors
> 1;
668 return isAggregateTypeForABI(Ty
);
671 // Check if a type needs to be passed in registers as a Pure Scalable Type (as
672 // defined by AAPCS64). Return the number of data vectors and the number of
673 // predicate vectors in the type, into `NVec` and `NPred`, respectively. Upon
674 // return `CoerceToSeq` contains an expanded sequence of LLVM IR types, one
675 // element for each non-composite member. For practical purposes, limit the
676 // length of `CoerceToSeq` to about 12 (the maximum that could possibly fit
677 // in registers) and return false, the effect of which will be to pass the
678 // argument under the rules for a large (> 128 bytes) composite.
679 bool AArch64ABIInfo::passAsPureScalableType(
680 QualType Ty
, unsigned &NVec
, unsigned &NPred
,
681 SmallVectorImpl
<llvm::Type
*> &CoerceToSeq
) const {
682 if (const ConstantArrayType
*AT
= getContext().getAsConstantArrayType(Ty
)) {
683 uint64_t NElt
= AT
->getZExtSize();
687 unsigned NV
= 0, NP
= 0;
688 SmallVector
<llvm::Type
*> EltCoerceToSeq
;
689 if (!passAsPureScalableType(AT
->getElementType(), NV
, NP
, EltCoerceToSeq
))
692 if (CoerceToSeq
.size() + NElt
* EltCoerceToSeq
.size() > 12)
695 for (uint64_t I
= 0; I
< NElt
; ++I
)
696 llvm::copy(EltCoerceToSeq
, std::back_inserter(CoerceToSeq
));
703 if (const RecordType
*RT
= Ty
->getAs
<RecordType
>()) {
704 // If the record cannot be passed in registers, then it's not a PST.
705 if (CGCXXABI::RecordArgABI RAA
= getRecordArgABI(RT
, getCXXABI());
706 RAA
!= CGCXXABI::RAA_Default
)
709 // Pure scalable types are never unions and never contain unions.
710 const RecordDecl
*RD
= RT
->getDecl();
714 // If this is a C++ record, check the bases.
715 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(RD
)) {
716 for (const auto &I
: CXXRD
->bases()) {
717 if (isEmptyRecord(getContext(), I
.getType(), true))
719 if (!passAsPureScalableType(I
.getType(), NVec
, NPred
, CoerceToSeq
))
725 for (const auto *FD
: RD
->fields()) {
726 QualType FT
= FD
->getType();
727 if (isEmptyField(getContext(), FD
, /* AllowArrays */ true))
729 if (!passAsPureScalableType(FT
, NVec
, NPred
, CoerceToSeq
))
736 if (const auto *VT
= Ty
->getAs
<VectorType
>()) {
737 if (VT
->getVectorKind() == VectorKind::SveFixedLengthPredicate
) {
739 if (CoerceToSeq
.size() + 1 > 12)
741 CoerceToSeq
.push_back(convertFixedToScalableVectorType(VT
));
745 if (VT
->getVectorKind() == VectorKind::SveFixedLengthData
) {
747 if (CoerceToSeq
.size() + 1 > 12)
749 CoerceToSeq
.push_back(convertFixedToScalableVectorType(VT
));
756 if (!Ty
->isBuiltinType())
760 switch (Ty
->getAs
<BuiltinType
>()->getKind()) {
761 #define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
762 case BuiltinType::Id: \
763 isPredicate = false; \
765 #define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
766 case BuiltinType::Id: \
767 isPredicate = true; \
769 #define SVE_TYPE(Name, Id, SingletonId)
770 #include "clang/Basic/AArch64SVEACLETypes.def"
775 ASTContext::BuiltinVectorTypeInfo Info
=
776 getContext().getBuiltinVectorTypeInfo(cast
<BuiltinType
>(Ty
));
777 assert(Info
.NumVectors
> 0 && Info
.NumVectors
<= 4 &&
778 "Expected 1, 2, 3 or 4 vectors!");
780 NPred
+= Info
.NumVectors
;
782 NVec
+= Info
.NumVectors
;
783 llvm::Type
*EltTy
= Info
.ElementType
->isMFloat8Type()
784 ? llvm::Type::getInt8Ty(getVMContext())
785 : CGT
.ConvertType(Info
.ElementType
);
786 auto *VTy
= llvm::ScalableVectorType::get(EltTy
, Info
.EC
.getKnownMinValue());
788 if (CoerceToSeq
.size() + Info
.NumVectors
> 12)
790 std::fill_n(std::back_inserter(CoerceToSeq
), Info
.NumVectors
, VTy
);
795 // Expand an LLVM IR type into a sequence with a element for each non-struct,
796 // non-array member of the type, with the exception of the padding types, which
798 void AArch64ABIInfo::flattenType(
799 llvm::Type
*Ty
, SmallVectorImpl
<llvm::Type
*> &Flattened
) const {
801 if (ABIArgInfo::isPaddingForCoerceAndExpand(Ty
)) {
802 Flattened
.push_back(Ty
);
806 if (const auto *AT
= dyn_cast
<llvm::ArrayType
>(Ty
)) {
807 uint64_t NElt
= AT
->getNumElements();
811 SmallVector
<llvm::Type
*> EltFlattened
;
812 flattenType(AT
->getElementType(), EltFlattened
);
814 for (uint64_t I
= 0; I
< NElt
; ++I
)
815 llvm::copy(EltFlattened
, std::back_inserter(Flattened
));
819 if (const auto *ST
= dyn_cast
<llvm::StructType
>(Ty
)) {
820 for (auto *ET
: ST
->elements())
821 flattenType(ET
, Flattened
);
825 Flattened
.push_back(Ty
);
828 RValue
AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr
, QualType Ty
,
829 CodeGenFunction
&CGF
, AArch64ABIKind Kind
,
830 AggValueSlot Slot
) const {
831 // These numbers are not used for variadic arguments, hence it doesn't matter
832 // they don't retain their values across multiple calls to
833 // `classifyArgumentType` here.
834 unsigned NSRN
= 0, NPRN
= 0;
836 classifyArgumentType(Ty
, /*IsVariadicFn=*/true, /* IsNamedArg */ false,
837 CGF
.CurFnInfo
->getCallingConvention(), NSRN
, NPRN
);
838 // Empty records are ignored for parameter passing purposes.
840 return Slot
.asRValue();
842 bool IsIndirect
= AI
.isIndirect();
844 llvm::Type
*BaseTy
= CGF
.ConvertType(Ty
);
846 BaseTy
= llvm::PointerType::getUnqual(BaseTy
);
847 else if (AI
.getCoerceToType())
848 BaseTy
= AI
.getCoerceToType();
850 unsigned NumRegs
= 1;
851 if (llvm::ArrayType
*ArrTy
= dyn_cast
<llvm::ArrayType
>(BaseTy
)) {
852 BaseTy
= ArrTy
->getElementType();
853 NumRegs
= ArrTy
->getNumElements();
856 !isSoftFloat() && (BaseTy
->isFloatingPointTy() || BaseTy
->isVectorTy());
858 // The AArch64 va_list type and handling is specified in the Procedure Call
859 // Standard, section B.4:
869 llvm::BasicBlock
*MaybeRegBlock
= CGF
.createBasicBlock("vaarg.maybe_reg");
870 llvm::BasicBlock
*InRegBlock
= CGF
.createBasicBlock("vaarg.in_reg");
871 llvm::BasicBlock
*OnStackBlock
= CGF
.createBasicBlock("vaarg.on_stack");
872 llvm::BasicBlock
*ContBlock
= CGF
.createBasicBlock("vaarg.end");
874 CharUnits TySize
= getContext().getTypeSizeInChars(Ty
);
875 CharUnits TyAlign
= getContext().getTypeUnadjustedAlignInChars(Ty
);
877 Address reg_offs_p
= Address::invalid();
878 llvm::Value
*reg_offs
= nullptr;
880 int RegSize
= IsIndirect
? 8 : TySize
.getQuantity();
882 // 3 is the field number of __gr_offs
883 reg_offs_p
= CGF
.Builder
.CreateStructGEP(VAListAddr
, 3, "gr_offs_p");
884 reg_offs
= CGF
.Builder
.CreateLoad(reg_offs_p
, "gr_offs");
885 reg_top_index
= 1; // field number for __gr_top
886 RegSize
= llvm::alignTo(RegSize
, 8);
888 // 4 is the field number of __vr_offs.
889 reg_offs_p
= CGF
.Builder
.CreateStructGEP(VAListAddr
, 4, "vr_offs_p");
890 reg_offs
= CGF
.Builder
.CreateLoad(reg_offs_p
, "vr_offs");
891 reg_top_index
= 2; // field number for __vr_top
892 RegSize
= 16 * NumRegs
;
895 //=======================================
896 // Find out where argument was passed
897 //=======================================
899 // If reg_offs >= 0 we're already using the stack for this type of
900 // argument. We don't want to keep updating reg_offs (in case it overflows,
901 // though anyone passing 2GB of arguments, each at most 16 bytes, deserves
902 // whatever they get).
903 llvm::Value
*UsingStack
= nullptr;
904 UsingStack
= CGF
.Builder
.CreateICmpSGE(
905 reg_offs
, llvm::ConstantInt::get(CGF
.Int32Ty
, 0));
907 CGF
.Builder
.CreateCondBr(UsingStack
, OnStackBlock
, MaybeRegBlock
);
909 // Otherwise, at least some kind of argument could go in these registers, the
910 // question is whether this particular type is too big.
911 CGF
.EmitBlock(MaybeRegBlock
);
913 // Integer arguments may need to correct register alignment (for example a
914 // "struct { __int128 a; };" gets passed in x_2N, x_{2N+1}). In this case we
915 // align __gr_offs to calculate the potential address.
916 if (!IsFPR
&& !IsIndirect
&& TyAlign
.getQuantity() > 8) {
917 int Align
= TyAlign
.getQuantity();
919 reg_offs
= CGF
.Builder
.CreateAdd(
920 reg_offs
, llvm::ConstantInt::get(CGF
.Int32Ty
, Align
- 1),
922 reg_offs
= CGF
.Builder
.CreateAnd(
923 reg_offs
, llvm::ConstantInt::get(CGF
.Int32Ty
, -Align
),
927 // Update the gr_offs/vr_offs pointer for next call to va_arg on this va_list.
928 // The fact that this is done unconditionally reflects the fact that
929 // allocating an argument to the stack also uses up all the remaining
930 // registers of the appropriate kind.
931 llvm::Value
*NewOffset
= nullptr;
932 NewOffset
= CGF
.Builder
.CreateAdd(
933 reg_offs
, llvm::ConstantInt::get(CGF
.Int32Ty
, RegSize
), "new_reg_offs");
934 CGF
.Builder
.CreateStore(NewOffset
, reg_offs_p
);
936 // Now we're in a position to decide whether this argument really was in
938 llvm::Value
*InRegs
= nullptr;
939 InRegs
= CGF
.Builder
.CreateICmpSLE(
940 NewOffset
, llvm::ConstantInt::get(CGF
.Int32Ty
, 0), "inreg");
942 CGF
.Builder
.CreateCondBr(InRegs
, InRegBlock
, OnStackBlock
);
944 //=======================================
945 // Argument was in registers
946 //=======================================
948 // Now we emit the code for if the argument was originally passed in
949 // registers. First start the appropriate block:
950 CGF
.EmitBlock(InRegBlock
);
952 llvm::Value
*reg_top
= nullptr;
954 CGF
.Builder
.CreateStructGEP(VAListAddr
, reg_top_index
, "reg_top_p");
955 reg_top
= CGF
.Builder
.CreateLoad(reg_top_p
, "reg_top");
956 Address
BaseAddr(CGF
.Builder
.CreateInBoundsGEP(CGF
.Int8Ty
, reg_top
, reg_offs
),
957 CGF
.Int8Ty
, CharUnits::fromQuantity(IsFPR
? 16 : 8));
958 Address RegAddr
= Address::invalid();
959 llvm::Type
*MemTy
= CGF
.ConvertTypeForMem(Ty
), *ElementTy
= MemTy
;
962 // If it's been passed indirectly (actually a struct), whatever we find from
963 // stored registers or on the stack will actually be a struct **.
964 MemTy
= llvm::PointerType::getUnqual(MemTy
);
967 const Type
*Base
= nullptr;
968 uint64_t NumMembers
= 0;
969 bool IsHFA
= isHomogeneousAggregate(Ty
, Base
, NumMembers
);
970 if (IsHFA
&& NumMembers
> 1) {
971 // Homogeneous aggregates passed in registers will have their elements split
972 // and stored 16-bytes apart regardless of size (they're notionally in qN,
973 // qN+1, ...). We reload and store into a temporary local variable
975 assert(!IsIndirect
&& "Homogeneous aggregates should be passed directly");
976 auto BaseTyInfo
= getContext().getTypeInfoInChars(QualType(Base
, 0));
977 llvm::Type
*BaseTy
= CGF
.ConvertType(QualType(Base
, 0));
978 llvm::Type
*HFATy
= llvm::ArrayType::get(BaseTy
, NumMembers
);
979 Address Tmp
= CGF
.CreateTempAlloca(HFATy
,
980 std::max(TyAlign
, BaseTyInfo
.Align
));
982 // On big-endian platforms, the value will be right-aligned in its slot.
984 if (CGF
.CGM
.getDataLayout().isBigEndian() &&
985 BaseTyInfo
.Width
.getQuantity() < 16)
986 Offset
= 16 - BaseTyInfo
.Width
.getQuantity();
988 for (unsigned i
= 0; i
< NumMembers
; ++i
) {
989 CharUnits BaseOffset
= CharUnits::fromQuantity(16 * i
+ Offset
);
991 CGF
.Builder
.CreateConstInBoundsByteGEP(BaseAddr
, BaseOffset
);
992 LoadAddr
= LoadAddr
.withElementType(BaseTy
);
994 Address StoreAddr
= CGF
.Builder
.CreateConstArrayGEP(Tmp
, i
);
996 llvm::Value
*Elem
= CGF
.Builder
.CreateLoad(LoadAddr
);
997 CGF
.Builder
.CreateStore(Elem
, StoreAddr
);
1000 RegAddr
= Tmp
.withElementType(MemTy
);
1002 // Otherwise the object is contiguous in memory.
1004 // It might be right-aligned in its slot.
1005 CharUnits SlotSize
= BaseAddr
.getAlignment();
1006 if (CGF
.CGM
.getDataLayout().isBigEndian() && !IsIndirect
&&
1007 (IsHFA
|| !isAggregateTypeForABI(Ty
)) &&
1008 TySize
< SlotSize
) {
1009 CharUnits Offset
= SlotSize
- TySize
;
1010 BaseAddr
= CGF
.Builder
.CreateConstInBoundsByteGEP(BaseAddr
, Offset
);
1013 RegAddr
= BaseAddr
.withElementType(MemTy
);
1016 CGF
.EmitBranch(ContBlock
);
1018 //=======================================
1019 // Argument was on the stack
1020 //=======================================
1021 CGF
.EmitBlock(OnStackBlock
);
1023 Address stack_p
= CGF
.Builder
.CreateStructGEP(VAListAddr
, 0, "stack_p");
1024 llvm::Value
*OnStackPtr
= CGF
.Builder
.CreateLoad(stack_p
, "stack");
1026 // Again, stack arguments may need realignment. In this case both integer and
1027 // floating-point ones might be affected.
1028 if (!IsIndirect
&& TyAlign
.getQuantity() > 8) {
1029 OnStackPtr
= emitRoundPointerUpToAlignment(CGF
, OnStackPtr
, TyAlign
);
1031 Address OnStackAddr
= Address(OnStackPtr
, CGF
.Int8Ty
,
1032 std::max(CharUnits::fromQuantity(8), TyAlign
));
1034 // All stack slots are multiples of 8 bytes.
1035 CharUnits StackSlotSize
= CharUnits::fromQuantity(8);
1036 CharUnits StackSize
;
1038 StackSize
= StackSlotSize
;
1040 StackSize
= TySize
.alignTo(StackSlotSize
);
1042 llvm::Value
*StackSizeC
= CGF
.Builder
.getSize(StackSize
);
1043 llvm::Value
*NewStack
= CGF
.Builder
.CreateInBoundsGEP(
1044 CGF
.Int8Ty
, OnStackPtr
, StackSizeC
, "new_stack");
1046 // Write the new value of __stack for the next call to va_arg
1047 CGF
.Builder
.CreateStore(NewStack
, stack_p
);
1049 if (CGF
.CGM
.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty
) &&
1050 TySize
< StackSlotSize
) {
1051 CharUnits Offset
= StackSlotSize
- TySize
;
1052 OnStackAddr
= CGF
.Builder
.CreateConstInBoundsByteGEP(OnStackAddr
, Offset
);
1055 OnStackAddr
= OnStackAddr
.withElementType(MemTy
);
1057 CGF
.EmitBranch(ContBlock
);
1059 //=======================================
1061 //=======================================
1062 CGF
.EmitBlock(ContBlock
);
1064 Address ResAddr
= emitMergePHI(CGF
, RegAddr
, InRegBlock
, OnStackAddr
,
1065 OnStackBlock
, "vaargs.addr");
1068 return CGF
.EmitLoadOfAnyValue(
1070 Address(CGF
.Builder
.CreateLoad(ResAddr
, "vaarg.addr"), ElementTy
,
1075 return CGF
.EmitLoadOfAnyValue(CGF
.MakeAddrLValue(ResAddr
, Ty
), Slot
);
1078 RValue
AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr
, QualType Ty
,
1079 CodeGenFunction
&CGF
,
1080 AggValueSlot Slot
) const {
1081 // The backend's lowering doesn't support va_arg for aggregates or
1082 // illegal vector types. Lower VAArg here for these cases and use
1083 // the LLVM va_arg instruction for everything else.
1084 if (!isAggregateTypeForABI(Ty
) && !isIllegalVectorType(Ty
))
1085 return CGF
.EmitLoadOfAnyValue(
1087 EmitVAArgInstr(CGF
, VAListAddr
, Ty
, ABIArgInfo::getDirect()), Ty
),
1090 uint64_t PointerSize
= getTarget().getPointerWidth(LangAS::Default
) / 8;
1091 CharUnits SlotSize
= CharUnits::fromQuantity(PointerSize
);
1093 // Empty records are ignored for parameter passing purposes.
1094 if (isEmptyRecord(getContext(), Ty
, true))
1095 return Slot
.asRValue();
1097 // The size of the actual thing passed, which might end up just
1098 // being a pointer for indirect types.
1099 auto TyInfo
= getContext().getTypeInfoInChars(Ty
);
1101 // Arguments bigger than 16 bytes which aren't homogeneous
1102 // aggregates should be passed indirectly.
1103 bool IsIndirect
= false;
1104 if (TyInfo
.Width
.getQuantity() > 16) {
1105 const Type
*Base
= nullptr;
1106 uint64_t Members
= 0;
1107 IsIndirect
= !isHomogeneousAggregate(Ty
, Base
, Members
);
1110 return emitVoidPtrVAArg(CGF
, VAListAddr
, Ty
, IsIndirect
, TyInfo
, SlotSize
,
1111 /*AllowHigherAlign*/ true, Slot
);
1114 RValue
AArch64ABIInfo::EmitMSVAArg(CodeGenFunction
&CGF
, Address VAListAddr
,
1115 QualType Ty
, AggValueSlot Slot
) const {
1116 bool IsIndirect
= false;
1118 // Composites larger than 16 bytes are passed by reference.
1119 if (isAggregateTypeForABI(Ty
) && getContext().getTypeSize(Ty
) > 128)
1122 return emitVoidPtrVAArg(CGF
, VAListAddr
, Ty
, IsIndirect
,
1123 CGF
.getContext().getTypeInfoInChars(Ty
),
1124 CharUnits::fromQuantity(8),
1125 /*allowHigherAlign*/ false, Slot
);
1128 static bool isStreamingCompatible(const FunctionDecl
*F
) {
1129 if (const auto *T
= F
->getType()->getAs
<FunctionProtoType
>())
1130 return T
->getAArch64SMEAttributes() &
1131 FunctionType::SME_PStateSMCompatibleMask
;
1135 // Report an error if an argument or return value of type Ty would need to be
1136 // passed in a floating-point register.
1137 static void diagnoseIfNeedsFPReg(DiagnosticsEngine
&Diags
,
1138 const StringRef ABIName
,
1139 const AArch64ABIInfo
&ABIInfo
,
1140 const QualType
&Ty
, const NamedDecl
*D
,
1141 SourceLocation loc
) {
1142 const Type
*HABase
= nullptr;
1143 uint64_t HAMembers
= 0;
1144 if (Ty
->isFloatingType() || Ty
->isVectorType() ||
1145 ABIInfo
.isHomogeneousAggregate(Ty
, HABase
, HAMembers
)) {
1146 Diags
.Report(loc
, diag::err_target_unsupported_type_for_abi
)
1147 << D
->getDeclName() << Ty
<< ABIName
;
1151 // If we are using a hard-float ABI, but do not have floating point registers,
1152 // then report an error for any function arguments or returns which would be
1153 // passed in floating-pint registers.
1154 void AArch64TargetCodeGenInfo::checkFunctionABI(
1155 CodeGenModule
&CGM
, const FunctionDecl
*FuncDecl
) const {
1156 const AArch64ABIInfo
&ABIInfo
= getABIInfo
<AArch64ABIInfo
>();
1157 const TargetInfo
&TI
= ABIInfo
.getContext().getTargetInfo();
1159 if (!TI
.hasFeature("fp") && !ABIInfo
.isSoftFloat()) {
1160 diagnoseIfNeedsFPReg(CGM
.getDiags(), TI
.getABI(), ABIInfo
,
1161 FuncDecl
->getReturnType(), FuncDecl
,
1162 FuncDecl
->getLocation());
1163 for (ParmVarDecl
*PVD
: FuncDecl
->parameters()) {
1164 diagnoseIfNeedsFPReg(CGM
.getDiags(), TI
.getABI(), ABIInfo
, PVD
->getType(),
1165 PVD
, FuncDecl
->getLocation());
1170 enum class ArmSMEInlinability
: uint8_t {
1172 ErrorCalleeRequiresNewZA
= 1 << 0,
1173 ErrorCalleeRequiresNewZT0
= 1 << 1,
1174 WarnIncompatibleStreamingModes
= 1 << 2,
1175 ErrorIncompatibleStreamingModes
= 1 << 3,
1177 IncompatibleStreamingModes
=
1178 WarnIncompatibleStreamingModes
| ErrorIncompatibleStreamingModes
,
1180 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/ErrorIncompatibleStreamingModes
),
1183 /// Determines if there are any Arm SME ABI issues with inlining \p Callee into
1184 /// \p Caller. Returns the issue (if any) in the ArmSMEInlinability bit enum.
1185 static ArmSMEInlinability
GetArmSMEInlinability(const FunctionDecl
*Caller
,
1186 const FunctionDecl
*Callee
) {
1187 bool CallerIsStreaming
=
1188 IsArmStreamingFunction(Caller
, /*IncludeLocallyStreaming=*/true);
1189 bool CalleeIsStreaming
=
1190 IsArmStreamingFunction(Callee
, /*IncludeLocallyStreaming=*/true);
1191 bool CallerIsStreamingCompatible
= isStreamingCompatible(Caller
);
1192 bool CalleeIsStreamingCompatible
= isStreamingCompatible(Callee
);
1194 ArmSMEInlinability Inlinability
= ArmSMEInlinability::Ok
;
1196 if (!CalleeIsStreamingCompatible
&&
1197 (CallerIsStreaming
!= CalleeIsStreaming
|| CallerIsStreamingCompatible
)) {
1198 if (CalleeIsStreaming
)
1199 Inlinability
|= ArmSMEInlinability::ErrorIncompatibleStreamingModes
;
1201 Inlinability
|= ArmSMEInlinability::WarnIncompatibleStreamingModes
;
1203 if (auto *NewAttr
= Callee
->getAttr
<ArmNewAttr
>()) {
1204 if (NewAttr
->isNewZA())
1205 Inlinability
|= ArmSMEInlinability::ErrorCalleeRequiresNewZA
;
1206 if (NewAttr
->isNewZT0())
1207 Inlinability
|= ArmSMEInlinability::ErrorCalleeRequiresNewZT0
;
1210 return Inlinability
;
1213 void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
1214 CodeGenModule
&CGM
, SourceLocation CallLoc
, const FunctionDecl
*Caller
,
1215 const FunctionDecl
*Callee
) const {
1216 if (!Caller
|| !Callee
|| !Callee
->hasAttr
<AlwaysInlineAttr
>())
1219 ArmSMEInlinability Inlinability
= GetArmSMEInlinability(Caller
, Callee
);
1221 if ((Inlinability
& ArmSMEInlinability::IncompatibleStreamingModes
) !=
1222 ArmSMEInlinability::Ok
)
1223 CGM
.getDiags().Report(
1225 (Inlinability
& ArmSMEInlinability::ErrorIncompatibleStreamingModes
) ==
1226 ArmSMEInlinability::ErrorIncompatibleStreamingModes
1227 ? diag::err_function_always_inline_attribute_mismatch
1228 : diag::warn_function_always_inline_attribute_mismatch
)
1229 << Caller
->getDeclName() << Callee
->getDeclName() << "streaming";
1231 if ((Inlinability
& ArmSMEInlinability::ErrorCalleeRequiresNewZA
) ==
1232 ArmSMEInlinability::ErrorCalleeRequiresNewZA
)
1233 CGM
.getDiags().Report(CallLoc
, diag::err_function_always_inline_new_za
)
1234 << Callee
->getDeclName();
1236 if ((Inlinability
& ArmSMEInlinability::ErrorCalleeRequiresNewZT0
) ==
1237 ArmSMEInlinability::ErrorCalleeRequiresNewZT0
)
1238 CGM
.getDiags().Report(CallLoc
, diag::err_function_always_inline_new_zt0
)
1239 << Callee
->getDeclName();
1242 // If the target does not have floating-point registers, but we are using a
1243 // hard-float ABI, there is no way to pass floating-point, vector or HFA values
1244 // to functions, so we report an error.
1245 void AArch64TargetCodeGenInfo::checkFunctionCallABISoftFloat(
1246 CodeGenModule
&CGM
, SourceLocation CallLoc
, const FunctionDecl
*Caller
,
1247 const FunctionDecl
*Callee
, const CallArgList
&Args
,
1248 QualType ReturnType
) const {
1249 const AArch64ABIInfo
&ABIInfo
= getABIInfo
<AArch64ABIInfo
>();
1250 const TargetInfo
&TI
= ABIInfo
.getContext().getTargetInfo();
1252 if (!Caller
|| TI
.hasFeature("fp") || ABIInfo
.isSoftFloat())
1255 diagnoseIfNeedsFPReg(CGM
.getDiags(), TI
.getABI(), ABIInfo
, ReturnType
,
1256 Callee
? Callee
: Caller
, CallLoc
);
1258 for (const CallArg
&Arg
: Args
)
1259 diagnoseIfNeedsFPReg(CGM
.getDiags(), TI
.getABI(), ABIInfo
, Arg
.getType(),
1260 Callee
? Callee
: Caller
, CallLoc
);
1263 void AArch64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule
&CGM
,
1264 SourceLocation CallLoc
,
1265 const FunctionDecl
*Caller
,
1266 const FunctionDecl
*Callee
,
1267 const CallArgList
&Args
,
1268 QualType ReturnType
) const {
1269 checkFunctionCallABIStreaming(CGM
, CallLoc
, Caller
, Callee
);
1270 checkFunctionCallABISoftFloat(CGM
, CallLoc
, Caller
, Callee
, Args
, ReturnType
);
1273 bool AArch64TargetCodeGenInfo::wouldInliningViolateFunctionCallABI(
1274 const FunctionDecl
*Caller
, const FunctionDecl
*Callee
) const {
1275 return Caller
&& Callee
&&
1276 GetArmSMEInlinability(Caller
, Callee
) != ArmSMEInlinability::Ok
;
1279 void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr
*Attr
,
1281 raw_ostream
&Out
) const {
1282 appendAttributeMangling(Attr
->getFeatureStr(Index
), Out
);
1285 void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr
,
1286 raw_ostream
&Out
) const {
1287 if (AttrStr
== "default") {
1293 SmallVector
<StringRef
, 8> Features
;
1294 AttrStr
.split(Features
, "+");
1295 for (auto &Feat
: Features
)
1298 llvm::sort(Features
, [](const StringRef LHS
, const StringRef RHS
) {
1299 return LHS
.compare(RHS
) < 0;
1302 llvm::SmallDenseSet
<StringRef
, 8> UniqueFeats
;
1303 for (auto &Feat
: Features
)
1304 if (auto Ext
= llvm::AArch64::parseFMVExtension(Feat
))
1305 if (UniqueFeats
.insert(Ext
->Name
).second
)
1306 Out
<< 'M' << Ext
->Name
;
1309 std::unique_ptr
<TargetCodeGenInfo
>
1310 CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule
&CGM
,
1311 AArch64ABIKind Kind
) {
1312 return std::make_unique
<AArch64TargetCodeGenInfo
>(CGM
.getTypes(), Kind
);
1315 std::unique_ptr
<TargetCodeGenInfo
>
1316 CodeGen::createWindowsAArch64TargetCodeGenInfo(CodeGenModule
&CGM
,
1318 return std::make_unique
<WindowsAArch64TargetCodeGenInfo
>(CGM
.getTypes(), K
);