clang 22.0.0git
AArch64.cpp
Go to the documentation of this file.
1//===- AArch64.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 "clang/AST/Decl.h"
13#include "llvm/TargetParser/AArch64TargetParser.h"
14
15using namespace clang;
16using namespace clang::CodeGen;
17
18//===----------------------------------------------------------------------===//
19// AArch64 ABI Implementation
20//===----------------------------------------------------------------------===//
21
22namespace {
23
24class AArch64ABIInfo : public ABIInfo {
25 AArch64ABIKind Kind;
26
27public:
28 AArch64ABIInfo(CodeGenTypes &CGT, AArch64ABIKind Kind)
29 : ABIInfo(CGT), Kind(Kind) {}
30
31 bool isSoftFloat() const { return Kind == AArch64ABIKind::AAPCSSoft; }
32
33private:
34 AArch64ABIKind getABIKind() const { return Kind; }
35 bool isDarwinPCS() const { return Kind == AArch64ABIKind::DarwinPCS; }
36
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;
52
53 bool isIllegalVectorType(QualType Ty) const;
54
55 bool passAsAggregateType(QualType Ty) const;
56 bool passAsPureScalableType(QualType Ty, unsigned &NV, unsigned &NP,
57 SmallVectorImpl<llvm::Type *> &CoerceToSeq) const;
58
59 void flattenType(llvm::Type *Ty,
60 SmallVectorImpl<llvm::Type *> &Flattened) const;
61
62 void computeInfo(CGFunctionInfo &FI) const override {
63 if (!::classifyReturnType(getCXXABI(), FI, *this))
64 FI.getReturnInfo() =
66
67 unsigned ArgNo = 0;
68 unsigned NSRN = 0, NPRN = 0;
69 for (auto &it : FI.arguments()) {
70 const bool IsNamedArg =
71 !FI.isVariadic() || ArgNo < FI.getRequiredArgs().getNumRequiredArgs();
72 ++ArgNo;
73 it.info = classifyArgumentType(it.type, FI.isVariadic(), IsNamedArg,
74 FI.getCallingConvention(), NSRN, NPRN);
75 }
76 }
77
78 RValue EmitDarwinVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
79 AggValueSlot Slot) const;
80
81 RValue EmitAAPCSVAArg(Address VAListAddr, QualType Ty, CodeGenFunction &CGF,
82 AArch64ABIKind Kind, AggValueSlot Slot) const;
83
84 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
85 AggValueSlot Slot) const override {
86 llvm::Type *BaseTy = CGF.ConvertType(Ty);
88 llvm::report_fatal_error("Passing SVE types to variadic functions is "
89 "currently not supported");
90
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);
95 }
96
97 RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
98 AggValueSlot Slot) const override;
99
100 bool allowBFloatArgsAndRet() const override {
101 return getTarget().hasBFloat16Type();
102 }
103
105 void appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
106 raw_ostream &Out) const override;
107 void appendAttributeMangling(StringRef AttrStr,
108 raw_ostream &Out) const override;
109};
110
111class AArch64SwiftABIInfo : public SwiftABIInfo {
112public:
113 explicit AArch64SwiftABIInfo(CodeGenTypes &CGT)
114 : SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/true) {}
115
116 bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
117 unsigned NumElts) const override;
118};
119
120class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
121public:
122 AArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIKind Kind)
123 : TargetCodeGenInfo(std::make_unique<AArch64ABIInfo>(CGT, Kind)) {
124 SwiftInfo = std::make_unique<AArch64SwiftABIInfo>(CGT);
125 }
126
127 StringRef getARCRetainAutoreleasedReturnValueMarker() const override {
128 return "mov\tfp, fp\t\t// marker for objc_retainAutoreleaseReturnValue";
129 }
130
131 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
132 return 31;
133 }
134
135 bool doesReturnSlotInterfereWithArgs() const override { return false; }
136
137 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
138 CodeGen::CodeGenModule &CGM) const override {
139 auto *Fn = dyn_cast<llvm::Function>(GV);
140 if (!Fn)
141 return;
142
143 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
144 TargetInfo::BranchProtectionInfo BPI(CGM.getLangOpts());
145
146 if (FD && FD->hasAttr<TargetAttr>()) {
147 const auto *TA = FD->getAttr<TargetAttr>();
148 ParsedTargetAttr Attr =
149 CGM.getTarget().parseTargetAttr(TA->getFeaturesStr());
150 if (!Attr.BranchProtection.empty()) {
151 StringRef Error;
153 Attr.BranchProtection, Attr.CPU, BPI, CGM.getLangOpts(), Error);
154 assert(Error.empty());
155 }
156 }
157 setBranchProtectionFnAttributes(BPI, *Fn);
158 setPointerAuthFnAttributes(CGM.getCodeGenOpts().PointerAuth, *Fn);
159 }
160
161 bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF,
162 llvm::Type *Ty) const override {
163 if (CGF.getTarget().hasFeature("ls64")) {
164 auto *ST = dyn_cast<llvm::StructType>(Ty);
165 if (ST && ST->getNumElements() == 1) {
166 auto *AT = dyn_cast<llvm::ArrayType>(ST->getElementType(0));
167 if (AT && AT->getNumElements() == 8 &&
168 AT->getElementType()->isIntegerTy(64))
169 return true;
170 }
171 }
173 }
174
175 void checkFunctionABI(CodeGenModule &CGM,
176 const FunctionDecl *Decl) const override;
177
178 void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc,
179 const FunctionDecl *Caller,
180 const FunctionDecl *Callee, const CallArgList &Args,
181 QualType ReturnType) const override;
182
183 bool wouldInliningViolateFunctionCallABI(
184 const FunctionDecl *Caller, const FunctionDecl *Callee) const override;
185
186private:
187 // Diagnose calls between functions with incompatible Streaming SVE
188 // attributes.
189 void checkFunctionCallABIStreaming(CodeGenModule &CGM, SourceLocation CallLoc,
190 const FunctionDecl *Caller,
191 const FunctionDecl *Callee) const;
192 // Diagnose calls which must pass arguments in floating-point registers when
193 // the selected target does not have floating-point registers.
194 void checkFunctionCallABISoftFloat(CodeGenModule &CGM, SourceLocation CallLoc,
195 const FunctionDecl *Caller,
196 const FunctionDecl *Callee,
197 const CallArgList &Args,
198 QualType ReturnType) const;
199};
200
201class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo {
202public:
203 WindowsAArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIKind K)
204 : AArch64TargetCodeGenInfo(CGT, K) {}
205
206 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
207 CodeGen::CodeGenModule &CGM) const override;
208
209 void getDependentLibraryOption(llvm::StringRef Lib,
210 llvm::SmallString<24> &Opt) const override {
211 Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib);
212 }
213
214 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value,
215 llvm::SmallString<32> &Opt) const override {
216 Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
217 }
218};
219
220void WindowsAArch64TargetCodeGenInfo::setTargetAttributes(
221 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
222 AArch64TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
223 if (GV->isDeclaration())
224 return;
225 addStackProbeTargetAttributes(D, GV, CGM);
226}
227}
228
229llvm::Type *
230AArch64ABIInfo::convertFixedToScalableVectorType(const VectorType *VT) const {
231 assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
232
233 if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
234 assert(VT->getElementType()->castAs<BuiltinType>()->getKind() ==
235 BuiltinType::UChar &&
236 "unexpected builtin type for SVE predicate!");
237 return llvm::ScalableVectorType::get(llvm::Type::getInt1Ty(getVMContext()),
238 16);
239 }
240
241 if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
242 const auto *BT = VT->getElementType()->castAs<BuiltinType>();
243 switch (BT->getKind()) {
244 default:
245 llvm_unreachable("unexpected builtin type for SVE vector!");
246
247 case BuiltinType::SChar:
248 case BuiltinType::UChar:
249 case BuiltinType::MFloat8:
250 return llvm::ScalableVectorType::get(
251 llvm::Type::getInt8Ty(getVMContext()), 16);
252
253 case BuiltinType::Short:
254 case BuiltinType::UShort:
255 return llvm::ScalableVectorType::get(
256 llvm::Type::getInt16Ty(getVMContext()), 8);
257
258 case BuiltinType::Int:
259 case BuiltinType::UInt:
260 return llvm::ScalableVectorType::get(
261 llvm::Type::getInt32Ty(getVMContext()), 4);
262
263 case BuiltinType::Long:
264 case BuiltinType::ULong:
265 return llvm::ScalableVectorType::get(
266 llvm::Type::getInt64Ty(getVMContext()), 2);
267
268 case BuiltinType::Half:
269 return llvm::ScalableVectorType::get(
270 llvm::Type::getHalfTy(getVMContext()), 8);
271
272 case BuiltinType::Float:
273 return llvm::ScalableVectorType::get(
274 llvm::Type::getFloatTy(getVMContext()), 4);
275
276 case BuiltinType::Double:
277 return llvm::ScalableVectorType::get(
278 llvm::Type::getDoubleTy(getVMContext()), 2);
279
280 case BuiltinType::BFloat16:
281 return llvm::ScalableVectorType::get(
282 llvm::Type::getBFloatTy(getVMContext()), 8);
283 }
284 }
285
286 llvm_unreachable("expected fixed-length SVE vector");
287}
288
289ABIArgInfo AArch64ABIInfo::coerceIllegalVector(QualType Ty, unsigned &NSRN,
290 unsigned &NPRN) const {
291 assert(Ty->isVectorType() && "expected vector type!");
292
293 const auto *VT = Ty->castAs<VectorType>();
294 if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
295 assert(VT->getElementType()->isBuiltinType() && "expected builtin type!");
296 assert(VT->getElementType()->castAs<BuiltinType>()->getKind() ==
297 BuiltinType::UChar &&
298 "unexpected builtin type for SVE predicate!");
299 NPRN = std::min(NPRN + 1, 4u);
300 return ABIArgInfo::getDirect(llvm::ScalableVectorType::get(
301 llvm::Type::getInt1Ty(getVMContext()), 16));
302 }
303
304 if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
305 NSRN = std::min(NSRN + 1, 8u);
306 return ABIArgInfo::getDirect(convertFixedToScalableVectorType(VT));
307 }
308
309 uint64_t Size = getContext().getTypeSize(Ty);
310 // Android promotes <2 x i8> to i16, not i32
311 if ((isAndroid() || isOHOSFamily()) && (Size <= 16)) {
312 llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext());
313 return ABIArgInfo::getDirect(ResType);
314 }
315 if (Size <= 32) {
316 llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext());
317 return ABIArgInfo::getDirect(ResType);
318 }
319 if (Size == 64) {
320 NSRN = std::min(NSRN + 1, 8u);
321 auto *ResType =
322 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2);
323 return ABIArgInfo::getDirect(ResType);
324 }
325 if (Size == 128) {
326 NSRN = std::min(NSRN + 1, 8u);
327 auto *ResType =
328 llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4);
329 return ABIArgInfo::getDirect(ResType);
330 }
331
332 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
333 /*ByVal=*/false);
334}
335
336ABIArgInfo AArch64ABIInfo::coerceAndExpandPureScalableAggregate(
337 QualType Ty, bool IsNamedArg, unsigned NVec, unsigned NPred,
338 const SmallVectorImpl<llvm::Type *> &UnpaddedCoerceToSeq, unsigned &NSRN,
339 unsigned &NPRN) const {
340 if (!IsNamedArg || NSRN + NVec > 8 || NPRN + NPred > 4)
341 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
342 /*ByVal=*/false);
343 NSRN += NVec;
344 NPRN += NPred;
345
346 // Handle SVE vector tuples.
347 if (Ty->isSVESizelessBuiltinType())
348 return ABIArgInfo::getDirect();
349
350 llvm::Type *UnpaddedCoerceToType =
351 UnpaddedCoerceToSeq.size() == 1
352 ? UnpaddedCoerceToSeq[0]
353 : llvm::StructType::get(CGT.getLLVMContext(), UnpaddedCoerceToSeq,
354 true);
355
356 SmallVector<llvm::Type *> CoerceToSeq;
357 flattenType(CGT.ConvertType(Ty), CoerceToSeq);
358 auto *CoerceToType =
359 llvm::StructType::get(CGT.getLLVMContext(), CoerceToSeq, false);
360
361 return ABIArgInfo::getCoerceAndExpand(CoerceToType, UnpaddedCoerceToType);
362}
363
364ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
365 bool IsNamedArg,
366 unsigned CallingConvention,
367 unsigned &NSRN,
368 unsigned &NPRN) const {
370
371 // Handle illegal vector types here.
372 if (isIllegalVectorType(Ty))
373 return coerceIllegalVector(Ty, NSRN, NPRN);
374
375 if (!passAsAggregateType(Ty)) {
376 // Treat an enum type as its underlying type.
377 if (const auto *ED = Ty->getAsEnumDecl())
378 Ty = ED->getIntegerType();
379
380 if (const auto *EIT = Ty->getAs<BitIntType>())
381 if (EIT->getNumBits() > 128)
382 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
383 false);
384
385 if (Ty->isVectorType())
386 NSRN = std::min(NSRN + 1, 8u);
387 else if (const auto *BT = Ty->getAs<BuiltinType>()) {
388 if (BT->isFloatingPoint())
389 NSRN = std::min(NSRN + 1, 8u);
390 else {
391 switch (BT->getKind()) {
392 case BuiltinType::SveBool:
393 case BuiltinType::SveCount:
394 NPRN = std::min(NPRN + 1, 4u);
395 break;
396 case BuiltinType::SveBoolx2:
397 NPRN = std::min(NPRN + 2, 4u);
398 break;
399 case BuiltinType::SveBoolx4:
400 NPRN = std::min(NPRN + 4, 4u);
401 break;
402 default:
403 if (BT->isSVESizelessBuiltinType())
404 NSRN = std::min(
405 NSRN + getContext().getBuiltinVectorTypeInfo(BT).NumVectors,
406 8u);
407 }
408 }
409 }
410
411 return (isPromotableIntegerTypeForABI(Ty) && isDarwinPCS()
412 ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
414 }
415
416 // Structures with either a non-trivial destructor or a non-trivial
417 // copy constructor are always indirect.
418 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
419 return getNaturalAlignIndirect(
420 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
421 /*ByVal=*/RAA == CGCXXABI::RAA_DirectInMemory);
422 }
423
424 // Empty records:
425 // AAPCS64 does not say that empty records are ignored as arguments,
426 // but other compilers do so in certain situations, and we copy that behavior.
427 // Those situations are in fact language-mode-specific, which seems really
428 // unfortunate, but it's something we just have to accept. If this doesn't
429 // apply, just fall through to the standard argument-handling path.
430 // Darwin overrides the psABI here to ignore all empty records in all modes.
431 uint64_t Size = getContext().getTypeSize(Ty);
432 bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
433 if (!Ty->isSVESizelessBuiltinType() && (IsEmpty || Size == 0)) {
434 // Empty records are ignored in C mode, and in C++ on Darwin.
435 if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
436 return ABIArgInfo::getIgnore();
437
438 // In C++ mode, arguments which have sizeof() == 0 (which are non-standard
439 // C++) are ignored. This isn't defined by any standard, so we copy GCC's
440 // behaviour here.
441 if (Size == 0)
442 return ABIArgInfo::getIgnore();
443 }
444
445 // Homogeneous Floating-point Aggregates (HFAs) need to be expanded.
446 const Type *Base = nullptr;
447 uint64_t Members = 0;
448 bool IsWin64 = Kind == AArch64ABIKind::Win64 ||
449 CallingConvention == llvm::CallingConv::Win64;
450 bool IsWinVariadic = IsWin64 && IsVariadicFn;
451 // In variadic functions on Windows, all composite types are treated alike,
452 // no special handling of HFAs/HVAs.
453 if (!IsWinVariadic && isHomogeneousAggregate(Ty, Base, Members)) {
454 NSRN = std::min(NSRN + Members, uint64_t(8));
455 if (Kind != AArch64ABIKind::AAPCS)
457 llvm::ArrayType::get(CGT.ConvertType(QualType(Base, 0)), Members));
458
459 // For HFAs/HVAs, cap the argument alignment to 16, otherwise
460 // set it to 8 according to the AAPCS64 document.
461 unsigned Align =
462 getContext().getTypeUnadjustedAlignInChars(Ty).getQuantity();
463 Align = (Align >= 16) ? 16 : 8;
465 llvm::ArrayType::get(CGT.ConvertType(QualType(Base, 0)), Members), 0,
466 nullptr, true, Align);
467 }
468
469 // In AAPCS named arguments of a Pure Scalable Type are passed expanded in
470 // registers, or indirectly if there are not enough registers.
471 if (Kind == AArch64ABIKind::AAPCS) {
472 unsigned NVec = 0, NPred = 0;
473 SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
474 if (passAsPureScalableType(Ty, NVec, NPred, UnpaddedCoerceToSeq) &&
475 (NVec + NPred) > 0)
476 return coerceAndExpandPureScalableAggregate(
477 Ty, IsNamedArg, NVec, NPred, UnpaddedCoerceToSeq, NSRN, NPRN);
478 }
479
480 // Aggregates <= 16 bytes are passed directly in registers or on the stack.
481 if (Size <= 128) {
482 unsigned Alignment;
483 if (Kind == AArch64ABIKind::AAPCS) {
484 Alignment = getContext().getTypeUnadjustedAlign(Ty);
485 Alignment = Alignment < 128 ? 64 : 128;
486 } else {
487 Alignment =
488 std::max(getContext().getTypeAlign(Ty),
489 (unsigned)getTarget().getPointerWidth(LangAS::Default));
490 }
491 Size = llvm::alignTo(Size, Alignment);
492
493 // If the Aggregate is made up of pointers, use an array of pointers for the
494 // coerced type. This prevents having to convert ptr2int->int2ptr through
495 // the call, allowing alias analysis to produce better code.
496 auto ContainsOnlyPointers = [&](const auto &Self, QualType Ty) {
497 if (isEmptyRecord(getContext(), Ty, true))
498 return false;
499 const auto *RD = Ty->getAsRecordDecl();
500 if (!RD)
501 return false;
502 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
503 for (const auto &I : CXXRD->bases())
504 if (!Self(Self, I.getType()))
505 return false;
506 }
507 return all_of(RD->fields(), [&](FieldDecl *FD) {
508 QualType FDTy = FD->getType();
509 if (FDTy->isArrayType())
510 FDTy = getContext().getBaseElementType(FDTy);
511 return (FDTy->isPointerOrReferenceType() &&
512 getContext().getTypeSize(FDTy) == 64 &&
513 !FDTy->getPointeeType().hasAddressSpace()) ||
514 Self(Self, FDTy);
515 });
516 };
517
518 // We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
519 // For aggregates with 16-byte alignment, we use i128.
520 llvm::Type *BaseTy = llvm::Type::getIntNTy(getVMContext(), Alignment);
521 if ((Size == 64 || Size == 128) && Alignment == 64 &&
522 ContainsOnlyPointers(ContainsOnlyPointers, Ty))
523 BaseTy = llvm::PointerType::getUnqual(getVMContext());
525 Size == Alignment ? BaseTy
526 : llvm::ArrayType::get(BaseTy, Size / Alignment));
527 }
528
529 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
530 /*ByVal=*/false);
531}
532
533ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
534 bool IsVariadicFn) const {
535 if (RetTy->isVoidType())
536 return ABIArgInfo::getIgnore();
537
538 if (const auto *VT = RetTy->getAs<VectorType>()) {
539 if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
540 VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
541 unsigned NSRN = 0, NPRN = 0;
542 return coerceIllegalVector(RetTy, NSRN, NPRN);
543 }
544 }
545
546 // Large vector types should be returned via memory.
547 if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128)
548 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
549
550 if (!passAsAggregateType(RetTy)) {
551 // Treat an enum type as its underlying type.
552 if (const auto *ED = RetTy->getAsEnumDecl())
553 RetTy = ED->getIntegerType();
554
555 if (const auto *EIT = RetTy->getAs<BitIntType>())
556 if (EIT->getNumBits() > 128)
557 return getNaturalAlignIndirect(RetTy,
558 getDataLayout().getAllocaAddrSpace());
559
560 return (isPromotableIntegerTypeForABI(RetTy) && isDarwinPCS()
561 ? ABIArgInfo::getExtend(RetTy)
563 }
564
565 uint64_t Size = getContext().getTypeSize(RetTy);
566 if (!RetTy->isSVESizelessBuiltinType() &&
567 (isEmptyRecord(getContext(), RetTy, true) || Size == 0))
568 return ABIArgInfo::getIgnore();
569
570 const Type *Base = nullptr;
571 uint64_t Members = 0;
572 if (isHomogeneousAggregate(RetTy, Base, Members) &&
573 !(getTarget().getTriple().getArch() == llvm::Triple::aarch64_32 &&
574 IsVariadicFn))
575 // Homogeneous Floating-point Aggregates (HFAs) are returned directly.
576 return ABIArgInfo::getDirect();
577
578 // In AAPCS return values of a Pure Scalable type are treated as a single
579 // named argument and passed expanded in registers, or indirectly if there are
580 // not enough registers.
581 if (Kind == AArch64ABIKind::AAPCS) {
582 unsigned NSRN = 0, NPRN = 0;
583 unsigned NVec = 0, NPred = 0;
584 SmallVector<llvm::Type *> UnpaddedCoerceToSeq;
585 if (passAsPureScalableType(RetTy, NVec, NPred, UnpaddedCoerceToSeq) &&
586 (NVec + NPred) > 0)
587 return coerceAndExpandPureScalableAggregate(
588 RetTy, /* IsNamedArg */ true, NVec, NPred, UnpaddedCoerceToSeq, NSRN,
589 NPRN);
590 }
591
592 // Aggregates <= 16 bytes are returned directly in registers or on the stack.
593 if (Size <= 128) {
594 if (Size <= 64 && getDataLayout().isLittleEndian()) {
595 // Composite types are returned in lower bits of a 64-bit register for LE,
596 // and in higher bits for BE. However, integer types are always returned
597 // in lower bits for both LE and BE, and they are not rounded up to
598 // 64-bits. We can skip rounding up of composite types for LE, but not for
599 // BE, otherwise composite types will be indistinguishable from integer
600 // types.
602 llvm::IntegerType::get(getVMContext(), Size));
603 }
604
605 unsigned Alignment = getContext().getTypeAlign(RetTy);
606 Size = llvm::alignTo(Size, 64); // round up to multiple of 8 bytes
607
608 // We use a pair of i64 for 16-byte aggregate with 8-byte alignment.
609 // For aggregates with 16-byte alignment, we use i128.
610 if (Alignment < 128 && Size == 128) {
611 llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext());
612 return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64));
613 }
614 return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size));
615 }
616
617 return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
618}
619
620/// isIllegalVectorType - check whether the vector type is legal for AArch64.
621bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const {
622 if (const VectorType *VT = Ty->getAs<VectorType>()) {
623 // Check whether VT is a fixed-length SVE vector. These types are
624 // represented as scalable vectors in function args/return and must be
625 // coerced from fixed vectors.
626 if (VT->getVectorKind() == VectorKind::SveFixedLengthData ||
627 VT->getVectorKind() == VectorKind::SveFixedLengthPredicate)
628 return true;
629
630 // Check whether VT is legal.
631 unsigned NumElements = VT->getNumElements();
632 uint64_t Size = getContext().getTypeSize(VT);
633 // NumElements should be power of 2.
634 if (!llvm::isPowerOf2_32(NumElements))
635 return true;
636
637 // arm64_32 has to be compatible with the ARM logic here, which allows huge
638 // vectors for some reason.
639 llvm::Triple Triple = getTarget().getTriple();
640 if (Triple.getArch() == llvm::Triple::aarch64_32 &&
641 Triple.isOSBinFormatMachO())
642 return Size <= 32;
643
644 return Size != 64 && (Size != 128 || NumElements == 1);
645 }
646 return false;
647}
648
649bool AArch64SwiftABIInfo::isLegalVectorType(CharUnits VectorSize,
650 llvm::Type *EltTy,
651 unsigned NumElts) const {
652 if (!llvm::isPowerOf2_32(NumElts))
653 return false;
654 if (VectorSize.getQuantity() != 8 &&
655 (VectorSize.getQuantity() != 16 || NumElts == 1))
656 return false;
657 return true;
658}
659
660bool AArch64ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
661 // For the soft-float ABI variant, no types are considered to be homogeneous
662 // aggregates.
663 if (isSoftFloat())
664 return false;
665
666 // Homogeneous aggregates for AAPCS64 must have base types of a floating
667 // point type or a short-vector type. This is the same as the 32-bit ABI,
668 // but with the difference that any floating-point type is allowed,
669 // including __fp16.
670 if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {
671 if (BT->isFloatingPoint())
672 return true;
673 } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
674 if (auto Kind = VT->getVectorKind();
675 Kind == VectorKind::SveFixedLengthData ||
676 Kind == VectorKind::SveFixedLengthPredicate)
677 return false;
678
679 unsigned VecSize = getContext().getTypeSize(VT);
680 if (VecSize == 64 || VecSize == 128)
681 return true;
682 }
683 return false;
684}
685
686bool AArch64ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,
687 uint64_t Members) const {
688 return Members <= 4;
689}
690
691bool AArch64ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate()
692 const {
693 // AAPCS64 says that the rule for whether something is a homogeneous
694 // aggregate is applied to the output of the data layout decision. So
695 // anything that doesn't affect the data layout also does not affect
696 // homogeneity. In particular, zero-length bitfields don't stop a struct
697 // being homogeneous.
698 return true;
699}
700
701bool AArch64ABIInfo::passAsAggregateType(QualType Ty) const {
702 if (Kind == AArch64ABIKind::AAPCS && Ty->isSVESizelessBuiltinType()) {
703 const auto *BT = Ty->castAs<BuiltinType>();
704 return !BT->isSVECount() &&
705 getContext().getBuiltinVectorTypeInfo(BT).NumVectors > 1;
706 }
707 return isAggregateTypeForABI(Ty);
708}
709
710// Check if a type needs to be passed in registers as a Pure Scalable Type (as
711// defined by AAPCS64). Return the number of data vectors and the number of
712// predicate vectors in the type, into `NVec` and `NPred`, respectively. Upon
713// return `CoerceToSeq` contains an expanded sequence of LLVM IR types, one
714// element for each non-composite member. For practical purposes, limit the
715// length of `CoerceToSeq` to about 12 (the maximum that could possibly fit
716// in registers) and return false, the effect of which will be to pass the
717// argument under the rules for a large (> 128 bytes) composite.
718bool AArch64ABIInfo::passAsPureScalableType(
719 QualType Ty, unsigned &NVec, unsigned &NPred,
720 SmallVectorImpl<llvm::Type *> &CoerceToSeq) const {
721 if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
722 uint64_t NElt = AT->getZExtSize();
723 if (NElt == 0)
724 return false;
725
726 unsigned NV = 0, NP = 0;
727 SmallVector<llvm::Type *> EltCoerceToSeq;
728 if (!passAsPureScalableType(AT->getElementType(), NV, NP, EltCoerceToSeq))
729 return false;
730
731 if (CoerceToSeq.size() + NElt * EltCoerceToSeq.size() > 12)
732 return false;
733
734 for (uint64_t I = 0; I < NElt; ++I)
735 llvm::append_range(CoerceToSeq, EltCoerceToSeq);
736
737 NVec += NElt * NV;
738 NPred += NElt * NP;
739 return true;
740 }
741
742 if (const RecordType *RT = Ty->getAsCanonical<RecordType>()) {
743 // If the record cannot be passed in registers, then it's not a PST.
744 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
746 return false;
747
748 // Pure scalable types are never unions and never contain unions.
749 const RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();
750 if (RD->isUnion())
751 return false;
752
753 // If this is a C++ record, check the bases.
754 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
755 for (const auto &I : CXXRD->bases()) {
756 if (isEmptyRecord(getContext(), I.getType(), true))
757 continue;
758 if (!passAsPureScalableType(I.getType(), NVec, NPred, CoerceToSeq))
759 return false;
760 }
761 }
762
763 // Check members.
764 for (const auto *FD : RD->fields()) {
765 QualType FT = FD->getType();
766 if (isEmptyField(getContext(), FD, /* AllowArrays */ true))
767 continue;
768 if (!passAsPureScalableType(FT, NVec, NPred, CoerceToSeq))
769 return false;
770 }
771
772 return true;
773 }
774
775 if (const auto *VT = Ty->getAs<VectorType>()) {
776 if (VT->getVectorKind() == VectorKind::SveFixedLengthPredicate) {
777 ++NPred;
778 if (CoerceToSeq.size() + 1 > 12)
779 return false;
780 CoerceToSeq.push_back(convertFixedToScalableVectorType(VT));
781 return true;
782 }
783
784 if (VT->getVectorKind() == VectorKind::SveFixedLengthData) {
785 ++NVec;
786 if (CoerceToSeq.size() + 1 > 12)
787 return false;
788 CoerceToSeq.push_back(convertFixedToScalableVectorType(VT));
789 return true;
790 }
791
792 return false;
793 }
794
795 if (!Ty->isBuiltinType())
796 return false;
797
798 bool isPredicate;
799 switch (Ty->castAs<BuiltinType>()->getKind()) {
800#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId) \
801 case BuiltinType::Id: \
802 isPredicate = false; \
803 break;
804#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId) \
805 case BuiltinType::Id: \
806 isPredicate = true; \
807 break;
808#include "clang/Basic/AArch64ACLETypes.def"
809 default:
810 return false;
811 }
812
813 ASTContext::BuiltinVectorTypeInfo Info =
814 getContext().getBuiltinVectorTypeInfo(cast<BuiltinType>(Ty));
815 assert(Info.NumVectors > 0 && Info.NumVectors <= 4 &&
816 "Expected 1, 2, 3 or 4 vectors!");
817 if (isPredicate)
818 NPred += Info.NumVectors;
819 else
820 NVec += Info.NumVectors;
821 llvm::Type *EltTy = Info.ElementType->isMFloat8Type()
822 ? llvm::Type::getInt8Ty(getVMContext())
823 : CGT.ConvertType(Info.ElementType);
824 auto *VTy = llvm::ScalableVectorType::get(EltTy, Info.EC.getKnownMinValue());
825
826 if (CoerceToSeq.size() + Info.NumVectors > 12)
827 return false;
828 std::fill_n(std::back_inserter(CoerceToSeq), Info.NumVectors, VTy);
829
830 return true;
831}
832
833// Expand an LLVM IR type into a sequence with a element for each non-struct,
834// non-array member of the type, with the exception of the padding types, which
835// are retained.
836void AArch64ABIInfo::flattenType(
837 llvm::Type *Ty, SmallVectorImpl<llvm::Type *> &Flattened) const {
838
840 Flattened.push_back(Ty);
841 return;
842 }
843
844 if (const auto *AT = dyn_cast<llvm::ArrayType>(Ty)) {
845 uint64_t NElt = AT->getNumElements();
846 if (NElt == 0)
847 return;
848
849 SmallVector<llvm::Type *> EltFlattened;
850 flattenType(AT->getElementType(), EltFlattened);
851
852 for (uint64_t I = 0; I < NElt; ++I)
853 llvm::append_range(Flattened, EltFlattened);
854 return;
855 }
856
857 if (const auto *ST = dyn_cast<llvm::StructType>(Ty)) {
858 for (auto *ET : ST->elements())
859 flattenType(ET, Flattened);
860 return;
861 }
862
863 Flattened.push_back(Ty);
864}
865
866RValue AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, QualType Ty,
867 CodeGenFunction &CGF, AArch64ABIKind Kind,
868 AggValueSlot Slot) const {
869 // These numbers are not used for variadic arguments, hence it doesn't matter
870 // they don't retain their values across multiple calls to
871 // `classifyArgumentType` here.
872 unsigned NSRN = 0, NPRN = 0;
873 ABIArgInfo AI =
874 classifyArgumentType(Ty, /*IsVariadicFn=*/true, /* IsNamedArg */ false,
875 CGF.CurFnInfo->getCallingConvention(), NSRN, NPRN);
876 // Empty records are ignored for parameter passing purposes.
877 if (AI.isIgnore())
878 return Slot.asRValue();
879
880 bool IsIndirect = AI.isIndirect();
881
882 llvm::Type *BaseTy = CGF.ConvertType(Ty);
883 if (IsIndirect)
884 BaseTy = llvm::PointerType::getUnqual(BaseTy->getContext());
885 else if (AI.getCoerceToType())
886 BaseTy = AI.getCoerceToType();
887
888 unsigned NumRegs = 1;
889 if (llvm::ArrayType *ArrTy = dyn_cast<llvm::ArrayType>(BaseTy)) {
890 BaseTy = ArrTy->getElementType();
891 NumRegs = ArrTy->getNumElements();
892 }
893 bool IsFPR =
894 !isSoftFloat() && (BaseTy->isFloatingPointTy() || BaseTy->isVectorTy());
895
896 // The AArch64 va_list type and handling is specified in the Procedure Call
897 // Standard, section B.4:
898 //
899 // struct {
900 // void *__stack;
901 // void *__gr_top;
902 // void *__vr_top;
903 // int __gr_offs;
904 // int __vr_offs;
905 // };
906
907 llvm::BasicBlock *MaybeRegBlock = CGF.createBasicBlock("vaarg.maybe_reg");
908 llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
909 llvm::BasicBlock *OnStackBlock = CGF.createBasicBlock("vaarg.on_stack");
910 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
911
912 CharUnits TySize = getContext().getTypeSizeInChars(Ty);
913 CharUnits TyAlign = getContext().getTypeUnadjustedAlignInChars(Ty);
914
915 Address reg_offs_p = Address::invalid();
916 llvm::Value *reg_offs = nullptr;
917 int reg_top_index;
918 int RegSize = IsIndirect ? 8 : TySize.getQuantity();
919 if (!IsFPR) {
920 // 3 is the field number of __gr_offs
921 reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 3, "gr_offs_p");
922 reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "gr_offs");
923 reg_top_index = 1; // field number for __gr_top
924 RegSize = llvm::alignTo(RegSize, 8);
925 } else {
926 // 4 is the field number of __vr_offs.
927 reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 4, "vr_offs_p");
928 reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "vr_offs");
929 reg_top_index = 2; // field number for __vr_top
930 RegSize = 16 * NumRegs;
931 }
932
933 //=======================================
934 // Find out where argument was passed
935 //=======================================
936
937 // If reg_offs >= 0 we're already using the stack for this type of
938 // argument. We don't want to keep updating reg_offs (in case it overflows,
939 // though anyone passing 2GB of arguments, each at most 16 bytes, deserves
940 // whatever they get).
941 llvm::Value *UsingStack = nullptr;
942 UsingStack = CGF.Builder.CreateICmpSGE(
943 reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, 0));
944
945 CGF.Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock);
946
947 // Otherwise, at least some kind of argument could go in these registers, the
948 // question is whether this particular type is too big.
949 CGF.EmitBlock(MaybeRegBlock);
950
951 // Integer arguments may need to correct register alignment (for example a
952 // "struct { __int128 a; };" gets passed in x_2N, x_{2N+1}). In this case we
953 // align __gr_offs to calculate the potential address.
954 if (!IsFPR && !IsIndirect && TyAlign.getQuantity() > 8) {
955 int Align = TyAlign.getQuantity();
956
957 reg_offs = CGF.Builder.CreateAdd(
958 reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, Align - 1),
959 "align_regoffs");
960 reg_offs = CGF.Builder.CreateAnd(
961 reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, -Align),
962 "aligned_regoffs");
963 }
964
965 // Update the gr_offs/vr_offs pointer for next call to va_arg on this va_list.
966 // The fact that this is done unconditionally reflects the fact that
967 // allocating an argument to the stack also uses up all the remaining
968 // registers of the appropriate kind.
969 llvm::Value *NewOffset = nullptr;
970 NewOffset = CGF.Builder.CreateAdd(
971 reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, RegSize), "new_reg_offs");
972 CGF.Builder.CreateStore(NewOffset, reg_offs_p);
973
974 // Now we're in a position to decide whether this argument really was in
975 // registers or not.
976 llvm::Value *InRegs = nullptr;
977 InRegs = CGF.Builder.CreateICmpSLE(
978 NewOffset, llvm::ConstantInt::get(CGF.Int32Ty, 0), "inreg");
979
980 CGF.Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock);
981
982 //=======================================
983 // Argument was in registers
984 //=======================================
985
986 // Now we emit the code for if the argument was originally passed in
987 // registers. First start the appropriate block:
988 CGF.EmitBlock(InRegBlock);
989
990 llvm::Value *reg_top = nullptr;
991 Address reg_top_p =
992 CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p");
993 reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top");
994 Address BaseAddr(CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, reg_top, reg_offs),
995 CGF.Int8Ty, CharUnits::fromQuantity(IsFPR ? 16 : 8));
996 Address RegAddr = Address::invalid();
997 llvm::Type *MemTy = CGF.ConvertTypeForMem(Ty), *ElementTy = MemTy;
998
999 if (IsIndirect) {
1000 // If it's been passed indirectly (actually a struct), whatever we find from
1001 // stored registers or on the stack will actually be a struct **.
1002 MemTy = llvm::PointerType::getUnqual(MemTy->getContext());
1003 }
1004
1005 const Type *Base = nullptr;
1006 uint64_t NumMembers = 0;
1007 bool IsHFA = isHomogeneousAggregate(Ty, Base, NumMembers);
1008 if (IsHFA && NumMembers > 1) {
1009 // Homogeneous aggregates passed in registers will have their elements split
1010 // and stored 16-bytes apart regardless of size (they're notionally in qN,
1011 // qN+1, ...). We reload and store into a temporary local variable
1012 // contiguously.
1013 assert(!IsIndirect && "Homogeneous aggregates should be passed directly");
1014 auto BaseTyInfo = getContext().getTypeInfoInChars(QualType(Base, 0));
1015 llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0));
1016 llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers);
1017 Address Tmp = CGF.CreateTempAlloca(HFATy,
1018 std::max(TyAlign, BaseTyInfo.Align));
1019
1020 // On big-endian platforms, the value will be right-aligned in its slot.
1021 int Offset = 0;
1022 if (CGF.CGM.getDataLayout().isBigEndian() &&
1023 BaseTyInfo.Width.getQuantity() < 16)
1024 Offset = 16 - BaseTyInfo.Width.getQuantity();
1025
1026 for (unsigned i = 0; i < NumMembers; ++i) {
1027 CharUnits BaseOffset = CharUnits::fromQuantity(16 * i + Offset);
1028 Address LoadAddr =
1029 CGF.Builder.CreateConstInBoundsByteGEP(BaseAddr, BaseOffset);
1030 LoadAddr = LoadAddr.withElementType(BaseTy);
1031
1032 Address StoreAddr = CGF.Builder.CreateConstArrayGEP(Tmp, i);
1033
1034 llvm::Value *Elem = CGF.Builder.CreateLoad(LoadAddr);
1035 CGF.Builder.CreateStore(Elem, StoreAddr);
1036 }
1037
1038 RegAddr = Tmp.withElementType(MemTy);
1039 } else {
1040 // Otherwise the object is contiguous in memory.
1041
1042 // It might be right-aligned in its slot.
1043 CharUnits SlotSize = BaseAddr.getAlignment();
1044 if (CGF.CGM.getDataLayout().isBigEndian() && !IsIndirect &&
1045 (IsHFA || !isAggregateTypeForABI(Ty)) &&
1046 TySize < SlotSize) {
1047 CharUnits Offset = SlotSize - TySize;
1048 BaseAddr = CGF.Builder.CreateConstInBoundsByteGEP(BaseAddr, Offset);
1049 }
1050
1051 RegAddr = BaseAddr.withElementType(MemTy);
1052 }
1053
1054 CGF.EmitBranch(ContBlock);
1055
1056 //=======================================
1057 // Argument was on the stack
1058 //=======================================
1059 CGF.EmitBlock(OnStackBlock);
1060
1061 Address stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "stack_p");
1062 llvm::Value *OnStackPtr = CGF.Builder.CreateLoad(stack_p, "stack");
1063
1064 // Again, stack arguments may need realignment. In this case both integer and
1065 // floating-point ones might be affected.
1066 if (!IsIndirect && TyAlign.getQuantity() > 8) {
1067 OnStackPtr = emitRoundPointerUpToAlignment(CGF, OnStackPtr, TyAlign);
1068 }
1069 Address OnStackAddr = Address(OnStackPtr, CGF.Int8Ty,
1070 std::max(CharUnits::fromQuantity(8), TyAlign));
1071
1072 // All stack slots are multiples of 8 bytes.
1073 CharUnits StackSlotSize = CharUnits::fromQuantity(8);
1074 CharUnits StackSize;
1075 if (IsIndirect)
1076 StackSize = StackSlotSize;
1077 else
1078 StackSize = TySize.alignTo(StackSlotSize);
1079
1080 llvm::Value *StackSizeC = CGF.Builder.getSize(StackSize);
1081 llvm::Value *NewStack = CGF.Builder.CreateInBoundsGEP(
1082 CGF.Int8Ty, OnStackPtr, StackSizeC, "new_stack");
1083
1084 // Write the new value of __stack for the next call to va_arg
1085 CGF.Builder.CreateStore(NewStack, stack_p);
1086
1087 if (CGF.CGM.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty) &&
1088 TySize < StackSlotSize) {
1089 CharUnits Offset = StackSlotSize - TySize;
1090 OnStackAddr = CGF.Builder.CreateConstInBoundsByteGEP(OnStackAddr, Offset);
1091 }
1092
1093 OnStackAddr = OnStackAddr.withElementType(MemTy);
1094
1095 CGF.EmitBranch(ContBlock);
1096
1097 //=======================================
1098 // Tidy up
1099 //=======================================
1100 CGF.EmitBlock(ContBlock);
1101
1102 Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, OnStackAddr,
1103 OnStackBlock, "vaargs.addr");
1104
1105 if (IsIndirect)
1106 return CGF.EmitLoadOfAnyValue(
1107 CGF.MakeAddrLValue(
1108 Address(CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"), ElementTy,
1109 TyAlign),
1110 Ty),
1111 Slot);
1112
1113 return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot);
1114}
1115
1116RValue AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
1117 CodeGenFunction &CGF,
1118 AggValueSlot Slot) const {
1119 // The backend's lowering doesn't support va_arg for aggregates or
1120 // illegal vector types. Lower VAArg here for these cases and use
1121 // the LLVM va_arg instruction for everything else.
1122 if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty))
1123 return CGF.EmitLoadOfAnyValue(
1124 CGF.MakeAddrLValue(
1125 EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty),
1126 Slot);
1127
1128 uint64_t PointerSize = getTarget().getPointerWidth(LangAS::Default) / 8;
1129 CharUnits SlotSize = CharUnits::fromQuantity(PointerSize);
1130
1131 // Empty records are ignored for parameter passing purposes.
1132 if (isEmptyRecord(getContext(), Ty, true))
1133 return Slot.asRValue();
1134
1135 // The size of the actual thing passed, which might end up just
1136 // being a pointer for indirect types.
1137 auto TyInfo = getContext().getTypeInfoInChars(Ty);
1138
1139 // Arguments bigger than 16 bytes which aren't homogeneous
1140 // aggregates should be passed indirectly.
1141 bool IsIndirect = false;
1142 if (TyInfo.Width.getQuantity() > 16) {
1143 const Type *Base = nullptr;
1144 uint64_t Members = 0;
1145 IsIndirect = !isHomogeneousAggregate(Ty, Base, Members);
1146 }
1147
1148 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize,
1149 /*AllowHigherAlign*/ true, Slot);
1150}
1151
1152RValue AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
1153 QualType Ty, AggValueSlot Slot) const {
1154 bool IsIndirect = false;
1155
1156 // Composites larger than 16 bytes are passed by reference.
1157 if (isAggregateTypeForABI(Ty) && getContext().getTypeSize(Ty) > 128)
1158 IsIndirect = true;
1159
1160 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect,
1163 /*allowHigherAlign*/ false, Slot);
1164}
1165
1167 if (const auto *T = F->getType()->getAs<FunctionProtoType>())
1168 return T->getAArch64SMEAttributes() &
1170 return false;
1171}
1172
1173// Report an error if an argument or return value of type Ty would need to be
1174// passed in a floating-point register.
1176 const StringRef ABIName,
1177 const AArch64ABIInfo &ABIInfo,
1178 const QualType &Ty, const NamedDecl *D,
1179 SourceLocation loc) {
1180 const Type *HABase = nullptr;
1181 uint64_t HAMembers = 0;
1182 if (Ty->isFloatingType() || Ty->isVectorType() ||
1183 ABIInfo.isHomogeneousAggregate(Ty, HABase, HAMembers)) {
1184 Diags.Report(loc, diag::err_target_unsupported_type_for_abi)
1185 << D->getDeclName() << Ty << ABIName;
1186 }
1187}
1188
1189// If we are using a hard-float ABI, but do not have floating point registers,
1190// then report an error for any function arguments or returns which would be
1191// passed in floating-pint registers.
1192void AArch64TargetCodeGenInfo::checkFunctionABI(
1193 CodeGenModule &CGM, const FunctionDecl *FuncDecl) const {
1194 const AArch64ABIInfo &ABIInfo = getABIInfo<AArch64ABIInfo>();
1195 const TargetInfo &TI = ABIInfo.getContext().getTargetInfo();
1196
1197 if (!TI.hasFeature("fp") && !ABIInfo.isSoftFloat()) {
1198 diagnoseIfNeedsFPReg(CGM.getDiags(), TI.getABI(), ABIInfo,
1199 FuncDecl->getReturnType(), FuncDecl,
1200 FuncDecl->getLocation());
1201 for (ParmVarDecl *PVD : FuncDecl->parameters()) {
1202 diagnoseIfNeedsFPReg(CGM.getDiags(), TI.getABI(), ABIInfo, PVD->getType(),
1203 PVD, FuncDecl->getLocation());
1204 }
1205 }
1206}
1207
1220
1221/// Determines if there are any Arm SME ABI issues with inlining \p Callee into
1222/// \p Caller. Returns the issue (if any) in the ArmSMEInlinability bit enum.
1224 const FunctionDecl *Callee) {
1225 bool CallerIsStreaming =
1226 IsArmStreamingFunction(Caller, /*IncludeLocallyStreaming=*/true);
1227 bool CalleeIsStreaming =
1228 IsArmStreamingFunction(Callee, /*IncludeLocallyStreaming=*/true);
1229 bool CallerIsStreamingCompatible = isStreamingCompatible(Caller);
1230 bool CalleeIsStreamingCompatible = isStreamingCompatible(Callee);
1231
1233
1234 if (!CalleeIsStreamingCompatible &&
1235 (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) {
1236 if (CalleeIsStreaming)
1238 else
1240 }
1241 if (auto *NewAttr = Callee->getAttr<ArmNewAttr>()) {
1242 if (NewAttr->isNewZA())
1244 if (NewAttr->isNewZT0())
1246 }
1247
1248 return Inlinability;
1249}
1250
1251void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
1252 CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller,
1253 const FunctionDecl *Callee) const {
1254 if (!Caller || !Callee || !Callee->hasAttr<AlwaysInlineAttr>())
1255 return;
1256
1257 ArmSMEInlinability Inlinability = GetArmSMEInlinability(Caller, Callee);
1258
1261 CGM.getDiags().Report(
1262 CallLoc,
1265 ? diag::err_function_always_inline_attribute_mismatch
1266 : diag::warn_function_always_inline_attribute_mismatch)
1267 << Caller->getDeclName() << Callee->getDeclName() << "streaming";
1268
1269 if ((Inlinability & ArmSMEInlinability::ErrorCalleeRequiresNewZA) ==
1271 CGM.getDiags().Report(CallLoc, diag::err_function_always_inline_new_za)
1272 << Callee->getDeclName();
1273
1274 if ((Inlinability & ArmSMEInlinability::ErrorCalleeRequiresNewZT0) ==
1276 CGM.getDiags().Report(CallLoc, diag::err_function_always_inline_new_zt0)
1277 << Callee->getDeclName();
1278}
1279
1280// If the target does not have floating-point registers, but we are using a
1281// hard-float ABI, there is no way to pass floating-point, vector or HFA values
1282// to functions, so we report an error.
1283void AArch64TargetCodeGenInfo::checkFunctionCallABISoftFloat(
1284 CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller,
1285 const FunctionDecl *Callee, const CallArgList &Args,
1286 QualType ReturnType) const {
1287 const AArch64ABIInfo &ABIInfo = getABIInfo<AArch64ABIInfo>();
1288 const TargetInfo &TI = ABIInfo.getContext().getTargetInfo();
1289
1290 if (!Caller || TI.hasFeature("fp") || ABIInfo.isSoftFloat())
1291 return;
1292
1293 diagnoseIfNeedsFPReg(CGM.getDiags(), TI.getABI(), ABIInfo, ReturnType,
1294 Callee ? Callee : Caller, CallLoc);
1295
1296 for (const CallArg &Arg : Args)
1297 diagnoseIfNeedsFPReg(CGM.getDiags(), TI.getABI(), ABIInfo, Arg.getType(),
1298 Callee ? Callee : Caller, CallLoc);
1299}
1300
1301void AArch64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule &CGM,
1302 SourceLocation CallLoc,
1303 const FunctionDecl *Caller,
1304 const FunctionDecl *Callee,
1305 const CallArgList &Args,
1306 QualType ReturnType) const {
1307 checkFunctionCallABIStreaming(CGM, CallLoc, Caller, Callee);
1308 checkFunctionCallABISoftFloat(CGM, CallLoc, Caller, Callee, Args, ReturnType);
1309}
1310
1311bool AArch64TargetCodeGenInfo::wouldInliningViolateFunctionCallABI(
1312 const FunctionDecl *Caller, const FunctionDecl *Callee) const {
1313 return Caller && Callee &&
1315}
1316
1317void AArch64ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr,
1318 unsigned Index,
1319 raw_ostream &Out) const {
1320 appendAttributeMangling(Attr->getFeatureStr(Index), Out);
1321}
1322
1323void AArch64ABIInfo::appendAttributeMangling(StringRef AttrStr,
1324 raw_ostream &Out) const {
1325 if (AttrStr == "default") {
1326 Out << ".default";
1327 return;
1328 }
1329
1330 Out << "._";
1331 SmallVector<StringRef, 8> Features;
1332 AttrStr.split(Features, "+");
1333 for (auto &Feat : Features)
1334 Feat = Feat.trim();
1335
1336 llvm::sort(Features, [](const StringRef LHS, const StringRef RHS) {
1337 return LHS.compare(RHS) < 0;
1338 });
1339
1340 llvm::SmallDenseSet<StringRef, 8> UniqueFeats;
1341 for (auto &Feat : Features)
1342 if (auto Ext = llvm::AArch64::parseFMVExtension(Feat))
1343 if (UniqueFeats.insert(Ext->Name).second)
1344 Out << 'M' << Ext->Name;
1345}
1346
1347std::unique_ptr<TargetCodeGenInfo>
1349 AArch64ABIKind Kind) {
1350 return std::make_unique<AArch64TargetCodeGenInfo>(CGM.getTypes(), Kind);
1351}
1352
1353std::unique_ptr<TargetCodeGenInfo>
1355 AArch64ABIKind K) {
1356 return std::make_unique<WindowsAArch64TargetCodeGenInfo>(CGM.getTypes(), K);
1357}
static bool isStreamingCompatible(const FunctionDecl *F)
Definition AArch64.cpp:1166
ArmSMEInlinability
Definition AArch64.cpp:1208
static ArmSMEInlinability GetArmSMEInlinability(const FunctionDecl *Caller, const FunctionDecl *Callee)
Determines if there are any Arm SME ABI issues with inlining Callee into Caller.
Definition AArch64.cpp:1223
static void diagnoseIfNeedsFPReg(DiagnosticsEngine &Diags, const StringRef ABIName, const AArch64ABIInfo &ABIInfo, const QualType &Ty, const NamedDecl *D, SourceLocation loc)
Definition AArch64.cpp:1175
TypeInfoChars getTypeInfoInChars(const Type *T) const
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
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
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
static ABIArgInfo getIgnore()
static bool isPaddingForCoerceAndExpand(llvm::Type *eltType)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
llvm::Type * getCoerceToType() const
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
Definition ABIInfo.h:48
bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const
isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.
Definition ABIInfo.cpp:61
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
Definition ABIInfo.cpp:186
static Address invalid()
Definition Address.h:176
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:666
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition CGBuilder.h:140
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
Definition CGBuilder.h:309
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:245
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Definition CGBuilder.h:223
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition CGBuilder.h:112
llvm::ConstantInt * getSize(CharUnits N)
Definition CGBuilder.h:103
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
Definition CGBuilder.h:350
RecordArgABI
Specify how one should pass an argument of a record type.
Definition CGCXXABI.h:150
@ RAA_Default
Pass it using the normal C aggregate rules for the ABI, potentially introducing extra copies and pass...
Definition CGCXXABI.h:153
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition CGCXXABI.h:158
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
RequiredArgs getRequiredArgs() const
llvm::Type * ConvertType(QualType T)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
Definition CGExpr.cpp:2359
const TargetInfo & getTarget() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
Definition CGExpr.cpp:153
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
Definition CGStmt.cpp:672
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CGFunctionInfo * CurFnInfo
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
Definition CGStmt.cpp:652
This class organizes the cross-function state that is used while generating LLVM code.
DiagnosticsEngine & getDiags() const
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
const CodeGenOptions & getCodeGenOpts() const
unsigned getNumRequiredArgs() const
Target specific hooks for defining how a type should be passed or returned from functions with one of...
Definition ABIInfo.h:145
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition TargetInfo.h:47
virtual bool isScalarizableAsmOperand(CodeGen::CodeGenFunction &CGF, llvm::Type *Ty) const
Target hook to decide whether an inline asm operand can be passed by value.
Definition TargetInfo.h:202
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getLocation() const
Definition DeclBase.h:439
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents a function declaration or definition.
Definition Decl.h:2000
QualType getReturnType() const
Definition Decl.h:2845
ArrayRef< ParmVarDecl * > parameters() const
Definition Decl.h:2774
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5254
This represents a decl that may have a name.
Definition Decl.h:274
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
A (possibly-)qualified type.
Definition TypeBase.h:937
field_range fields() const
Definition Decl.h:4515
Encodes a location in the source.
bool isUnion() const
Definition Decl.h:3922
virtual bool validateBranchProtection(StringRef Spec, StringRef Arch, BranchProtectionInfo &BPI, const LangOptions &LO, StringRef &Err) const
Determine if this TargetInfo supports the given branch protection specification.
virtual StringRef getABI() const
Get the ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isVoidType() const
Definition TypeBase.h:8871
bool isMFloat8Type() const
Definition TypeBase.h:8896
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isSVESizelessBuiltinType() const
Returns true for SVE scalable vector types.
Definition Type.cpp:2573
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9158
bool isBuiltinType() const
Helper methods to distinguish type categories.
Definition TypeBase.h:8638
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
bool isVectorType() const
Definition TypeBase.h:8654
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2921
bool isFloatingType() const
Definition Type.cpp:2304
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9091
QualType getType() const
Definition Decl.h:723
unsigned getNumElements() const
Definition TypeBase.h:4190
VectorKind getVectorKind() const
Definition TypeBase.h:4195
QualType getElementType() const
Definition TypeBase.h:4189
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, llvm::VectorType *vectorTy)
Is the given vector type "legal" for Swift's perspective on the current platform?
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:145
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, const ABIArgInfo &AI)
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 ...
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyField - Return true iff a the field is "empty", that is it is an unnamed bit-field or an (arra...
llvm::Value * emitRoundPointerUpToAlignment(CodeGenFunction &CGF, llvm::Value *Ptr, CharUnits Align)
bool isAggregateTypeForABI(QualType T)
std::unique_ptr< TargetCodeGenInfo > createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind)
Definition AArch64.cpp:1348
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createWindowsAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind K)
Definition AArch64.cpp:1354
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
const FunctionProtoType * T
@ Type
The name was classified as a type.
Definition Sema.h:562
U cast(CodeGen::Address addr)
Definition Address.h:327
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
Definition Decl.cpp:6019
unsigned long uint64_t
#define true
Definition stdbool.h:25
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64