xref: /src/contrib/llvm-project/clang/lib/CodeGen/CGCall.cpp (revision 5deeebd8c6ca991269e72902a7a62cada57947f6)
1bfef3995SDimitry Andric //===--- CGCall.cpp - Encapsulate calling convention details --------------===//
2ec2b103cSEd Schouten //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ec2b103cSEd Schouten //
7ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
8ec2b103cSEd Schouten //
9ec2b103cSEd Schouten // These classes wrap the information about a call or function
10ec2b103cSEd Schouten // definition used to handle ABI compliancy.
11ec2b103cSEd Schouten //
12ec2b103cSEd Schouten //===----------------------------------------------------------------------===//
13ec2b103cSEd Schouten 
14ec2b103cSEd Schouten #include "CGCall.h"
154ba67500SRoman Divacky #include "ABIInfo.h"
16b1c73532SDimitry Andric #include "ABIInfoImpl.h"
172b6b257fSDimitry Andric #include "CGBlocks.h"
18809500fcSDimitry Andric #include "CGCXXABI.h"
1945b53394SDimitry Andric #include "CGCleanup.h"
20cfca06d7SDimitry Andric #include "CGRecordLayout.h"
21ec2b103cSEd Schouten #include "CodeGenFunction.h"
22ec2b103cSEd Schouten #include "CodeGenModule.h"
23dbe13110SDimitry Andric #include "TargetInfo.h"
24706b4fc4SDimitry Andric #include "clang/AST/Attr.h"
25ec2b103cSEd Schouten #include "clang/AST/Decl.h"
26ec2b103cSEd Schouten #include "clang/AST/DeclCXX.h"
27ec2b103cSEd Schouten #include "clang/AST/DeclObjC.h"
28676fbe81SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
29809500fcSDimitry Andric #include "clang/Basic/TargetInfo.h"
30bfef3995SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h"
312b6b257fSDimitry Andric #include "clang/CodeGen/SwiftCallingConv.h"
32809500fcSDimitry Andric #include "llvm/ADT/StringExtras.h"
33bab175ecSDimitry Andric #include "llvm/Analysis/ValueTracking.h"
34b60736ecSDimitry Andric #include "llvm/IR/Assumptions.h"
357fa27ce4SDimitry Andric #include "llvm/IR/AttributeMask.h"
36809500fcSDimitry Andric #include "llvm/IR/Attributes.h"
3748675466SDimitry Andric #include "llvm/IR/CallingConv.h"
38809500fcSDimitry Andric #include "llvm/IR/DataLayout.h"
39809500fcSDimitry Andric #include "llvm/IR/InlineAsm.h"
405e20cdd8SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
4148675466SDimitry Andric #include "llvm/IR/Intrinsics.h"
42145449b1SDimitry Andric #include "llvm/IR/Type.h"
43706b4fc4SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
44e3b55780SDimitry Andric #include <optional>
45ec2b103cSEd Schouten using namespace clang;
46ec2b103cSEd Schouten using namespace CodeGen;
47ec2b103cSEd Schouten 
48ec2b103cSEd Schouten /***/
49ec2b103cSEd Schouten 
ClangCallConvToLLVMCallConv(CallingConv CC)502b6b257fSDimitry Andric unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
51ecb7e5c8SRoman Divacky   switch (CC) {
52ecb7e5c8SRoman Divacky   default: return llvm::CallingConv::C;
53ecb7e5c8SRoman Divacky   case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
54ecb7e5c8SRoman Divacky   case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
55bab175ecSDimitry Andric   case CC_X86RegCall: return llvm::CallingConv::X86_RegCall;
56d7279c4cSRoman Divacky   case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
57de51d671SDimitry Andric   case CC_Win64: return llvm::CallingConv::Win64;
58bfef3995SDimitry Andric   case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV;
5901af97d3SDimitry Andric   case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS;
6001af97d3SDimitry Andric   case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP;
61809500fcSDimitry Andric   case CC_IntelOclBicc: return llvm::CallingConv::Intel_OCL_BI;
6206d4ba38SDimitry Andric   // TODO: Add support for __pascal to LLVM.
6306d4ba38SDimitry Andric   case CC_X86Pascal: return llvm::CallingConv::C;
6406d4ba38SDimitry Andric   // TODO: Add support for __vectorcall to LLVM.
6506d4ba38SDimitry Andric   case CC_X86VectorCall: return llvm::CallingConv::X86_VectorCall;
66676fbe81SDimitry Andric   case CC_AArch64VectorCall: return llvm::CallingConv::AArch64_VectorCall;
67145449b1SDimitry Andric   case CC_AArch64SVEPCS: return llvm::CallingConv::AArch64_SVE_VectorCall;
68145449b1SDimitry Andric   case CC_AMDGPUKernelCall: return llvm::CallingConv::AMDGPU_KERNEL;
695e20cdd8SDimitry Andric   case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC;
702b6b257fSDimitry Andric   case CC_OpenCLKernel: return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv();
712b6b257fSDimitry Andric   case CC_PreserveMost: return llvm::CallingConv::PreserveMost;
722b6b257fSDimitry Andric   case CC_PreserveAll: return llvm::CallingConv::PreserveAll;
732b6b257fSDimitry Andric   case CC_Swift: return llvm::CallingConv::Swift;
74344a3780SDimitry Andric   case CC_SwiftAsync: return llvm::CallingConv::SwiftTail;
75b1c73532SDimitry Andric   case CC_M68kRTD: return llvm::CallingConv::M68k_RTD;
76ac9a064cSDimitry Andric   case CC_PreserveNone: return llvm::CallingConv::PreserveNone;
77ac9a064cSDimitry Andric     // clang-format off
78ac9a064cSDimitry Andric   case CC_RISCVVectorCall: return llvm::CallingConv::RISCV_VectorCall;
79ac9a064cSDimitry Andric     // clang-format on
80ecb7e5c8SRoman Divacky   }
81ecb7e5c8SRoman Divacky }
82ecb7e5c8SRoman Divacky 
83676fbe81SDimitry Andric /// Derives the 'this' type for codegen purposes, i.e. ignoring method CVR
8422989816SDimitry Andric /// qualification. Either or both of RD and MD may be null. A null RD indicates
8522989816SDimitry Andric /// that there is no meaningful 'this' type, and a null MD can occur when
8622989816SDimitry Andric /// calling a method pointer.
DeriveThisType(const CXXRecordDecl * RD,const CXXMethodDecl * MD)8722989816SDimitry Andric CanQualType CodeGenTypes::DeriveThisType(const CXXRecordDecl *RD,
88676fbe81SDimitry Andric                                          const CXXMethodDecl *MD) {
8922989816SDimitry Andric   QualType RecTy;
9022989816SDimitry Andric   if (RD)
9122989816SDimitry Andric     RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal();
9222989816SDimitry Andric   else
9322989816SDimitry Andric     RecTy = Context.VoidTy;
9422989816SDimitry Andric 
95676fbe81SDimitry Andric   if (MD)
9622989816SDimitry Andric     RecTy = Context.getAddrSpaceQualType(RecTy, MD->getMethodQualifiers().getAddressSpace());
9779ade4e0SRoman Divacky   return Context.getPointerType(CanQualType::CreateUnsafe(RecTy));
98ec2b103cSEd Schouten }
99ec2b103cSEd Schouten 
10079ade4e0SRoman Divacky /// Returns the canonical formal type of the given C++ method.
GetFormalType(const CXXMethodDecl * MD)10179ade4e0SRoman Divacky static CanQual<FunctionProtoType> GetFormalType(const CXXMethodDecl *MD) {
10279ade4e0SRoman Divacky   return MD->getType()->getCanonicalTypeUnqualified()
10379ade4e0SRoman Divacky            .getAs<FunctionProtoType>();
10479ade4e0SRoman Divacky }
10579ade4e0SRoman Divacky 
10679ade4e0SRoman Divacky /// Returns the "extra-canonicalized" return type, which discards
10779ade4e0SRoman Divacky /// qualifiers on the return type.  Codegen doesn't care about them,
10879ade4e0SRoman Divacky /// and it makes ABI code a little easier to be able to assume that
10979ade4e0SRoman Divacky /// all parameter and return types are top-level unqualified.
GetReturnType(QualType RetTy)11079ade4e0SRoman Divacky static CanQualType GetReturnType(QualType RetTy) {
11179ade4e0SRoman Divacky   return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType();
11279ade4e0SRoman Divacky }
11379ade4e0SRoman Divacky 
11456d91b49SDimitry Andric /// Arrange the argument and result information for a value of the given
11556d91b49SDimitry Andric /// unprototyped freestanding function type.
11679ade4e0SRoman Divacky const CGFunctionInfo &
arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP)11756d91b49SDimitry Andric CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
118dbe13110SDimitry Andric   // When translating an unprototyped function type, always use a
119dbe13110SDimitry Andric   // variadic type.
1209f4dbff6SDimitry Andric   return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
121b1c73532SDimitry Andric                                  FnInfoOpts::None, std::nullopt,
1222b6b257fSDimitry Andric                                  FTNP->getExtInfo(), {}, RequiredArgs(0));
12379ade4e0SRoman Divacky }
12479ade4e0SRoman Divacky 
addExtParameterInfosForCall(llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> & paramInfos,const FunctionProtoType * proto,unsigned prefixArgs,unsigned totalArgs)1257442d6faSDimitry Andric static void addExtParameterInfosForCall(
1267442d6faSDimitry Andric          llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &paramInfos,
1277442d6faSDimitry Andric                                         const FunctionProtoType *proto,
1287442d6faSDimitry Andric                                         unsigned prefixArgs,
1297442d6faSDimitry Andric                                         unsigned totalArgs) {
1307442d6faSDimitry Andric   assert(proto->hasExtParameterInfos());
1317442d6faSDimitry Andric   assert(paramInfos.size() <= prefixArgs);
1327442d6faSDimitry Andric   assert(proto->getNumParams() + prefixArgs <= totalArgs);
1337442d6faSDimitry Andric 
1347442d6faSDimitry Andric   paramInfos.reserve(totalArgs);
1357442d6faSDimitry Andric 
1367442d6faSDimitry Andric   // Add default infos for any prefix args that don't already have infos.
1377442d6faSDimitry Andric   paramInfos.resize(prefixArgs);
1387442d6faSDimitry Andric 
1397442d6faSDimitry Andric   // Add infos for the prototype.
1407442d6faSDimitry Andric   for (const auto &ParamInfo : proto->getExtParameterInfos()) {
1417442d6faSDimitry Andric     paramInfos.push_back(ParamInfo);
1427442d6faSDimitry Andric     // pass_object_size params have no parameter info.
1437442d6faSDimitry Andric     if (ParamInfo.hasPassObjectSize())
1447442d6faSDimitry Andric       paramInfos.emplace_back();
1457442d6faSDimitry Andric   }
1467442d6faSDimitry Andric 
1477442d6faSDimitry Andric   assert(paramInfos.size() <= totalArgs &&
1487442d6faSDimitry Andric          "Did we forget to insert pass_object_size args?");
1497442d6faSDimitry Andric   // Add default infos for the variadic and/or suffix arguments.
1507442d6faSDimitry Andric   paramInfos.resize(totalArgs);
1517442d6faSDimitry Andric }
1527442d6faSDimitry Andric 
1538746d127SDimitry Andric /// Adds the formal parameters in FPT to the given prefix. If any parameter in
15445b53394SDimitry Andric /// FPT has pass_object_size attrs, then we'll add parameters for those, too.
appendParameterTypes(const CodeGenTypes & CGT,SmallVectorImpl<CanQualType> & prefix,SmallVectorImpl<FunctionProtoType::ExtParameterInfo> & paramInfos,CanQual<FunctionProtoType> FPT)15545b53394SDimitry Andric static void appendParameterTypes(const CodeGenTypes &CGT,
15645b53394SDimitry Andric                                  SmallVectorImpl<CanQualType> &prefix,
1572b6b257fSDimitry Andric               SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &paramInfos,
1587442d6faSDimitry Andric                                  CanQual<FunctionProtoType> FPT) {
1597442d6faSDimitry Andric   // Fast path: don't touch param info if we don't need to.
1607442d6faSDimitry Andric   if (!FPT->hasExtParameterInfos()) {
1617442d6faSDimitry Andric     assert(paramInfos.empty() &&
1627442d6faSDimitry Andric            "We have paramInfos, but the prototype doesn't?");
16345b53394SDimitry Andric     prefix.append(FPT->param_type_begin(), FPT->param_type_end());
16445b53394SDimitry Andric     return;
16545b53394SDimitry Andric   }
16645b53394SDimitry Andric 
1677442d6faSDimitry Andric   unsigned PrefixSize = prefix.size();
1687442d6faSDimitry Andric   // In the vast majority of cases, we'll have precisely FPT->getNumParams()
16945b53394SDimitry Andric   // parameters; the only thing that can change this is the presence of
17045b53394SDimitry Andric   // pass_object_size. So, we preallocate for the common case.
17145b53394SDimitry Andric   prefix.reserve(prefix.size() + FPT->getNumParams());
17245b53394SDimitry Andric 
1737442d6faSDimitry Andric   auto ExtInfos = FPT->getExtParameterInfos();
1747442d6faSDimitry Andric   assert(ExtInfos.size() == FPT->getNumParams());
17545b53394SDimitry Andric   for (unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
17645b53394SDimitry Andric     prefix.push_back(FPT->getParamType(I));
1777442d6faSDimitry Andric     if (ExtInfos[I].hasPassObjectSize())
17845b53394SDimitry Andric       prefix.push_back(CGT.getContext().getSizeType());
17945b53394SDimitry Andric   }
1807442d6faSDimitry Andric 
1817442d6faSDimitry Andric   addExtParameterInfosForCall(paramInfos, FPT.getTypePtr(), PrefixSize,
1827442d6faSDimitry Andric                               prefix.size());
18345b53394SDimitry Andric }
18445b53394SDimitry Andric 
18556d91b49SDimitry Andric /// Arrange the LLVM function layout for a value of the given function
18606d4ba38SDimitry Andric /// type, on top of any implicit parameters already stored.
18706d4ba38SDimitry Andric static const CGFunctionInfo &
arrangeLLVMFunctionInfo(CodeGenTypes & CGT,bool instanceMethod,SmallVectorImpl<CanQualType> & prefix,CanQual<FunctionProtoType> FTP)18806d4ba38SDimitry Andric arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
18956d91b49SDimitry Andric                         SmallVectorImpl<CanQualType> &prefix,
19022989816SDimitry Andric                         CanQual<FunctionProtoType> FTP) {
1912b6b257fSDimitry Andric   SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
19222989816SDimitry Andric   RequiredArgs Required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
193ec2b103cSEd Schouten   // FIXME: Kill copy.
1947442d6faSDimitry Andric   appendParameterTypes(CGT, prefix, paramInfos, FTP);
1959f4dbff6SDimitry Andric   CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
1962b6b257fSDimitry Andric 
197b1c73532SDimitry Andric   FnInfoOpts opts =
198b1c73532SDimitry Andric       instanceMethod ? FnInfoOpts::IsInstanceMethod : FnInfoOpts::None;
199b1c73532SDimitry Andric   return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix,
200b1c73532SDimitry Andric                                      FTP->getExtInfo(), paramInfos, Required);
20179ade4e0SRoman Divacky }
20279ade4e0SRoman Divacky 
203dbe13110SDimitry Andric /// Arrange the argument and result information for a value of the
20456d91b49SDimitry Andric /// given freestanding function type.
20579ade4e0SRoman Divacky const CGFunctionInfo &
arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP)20622989816SDimitry Andric CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) {
207dbe13110SDimitry Andric   SmallVector<CanQualType, 16> argTypes;
20806d4ba38SDimitry Andric   return ::arrangeLLVMFunctionInfo(*this, /*instanceMethod=*/false, argTypes,
20922989816SDimitry Andric                                    FTP);
2104c8b2481SRoman Divacky }
2114c8b2481SRoman Divacky 
getCallingConventionForDecl(const ObjCMethodDecl * D,bool IsWindows)212b60736ecSDimitry Andric static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
213b60736ecSDimitry Andric                                                bool IsWindows) {
2144c8b2481SRoman Divacky   // Set the appropriate calling convention for the Function.
2154c8b2481SRoman Divacky   if (D->hasAttr<StdCallAttr>())
216ecb7e5c8SRoman Divacky     return CC_X86StdCall;
2174c8b2481SRoman Divacky 
2184c8b2481SRoman Divacky   if (D->hasAttr<FastCallAttr>())
219ecb7e5c8SRoman Divacky     return CC_X86FastCall;
2204c8b2481SRoman Divacky 
221bab175ecSDimitry Andric   if (D->hasAttr<RegCallAttr>())
222bab175ecSDimitry Andric     return CC_X86RegCall;
223bab175ecSDimitry Andric 
224d7279c4cSRoman Divacky   if (D->hasAttr<ThisCallAttr>())
225d7279c4cSRoman Divacky     return CC_X86ThisCall;
226d7279c4cSRoman Divacky 
22706d4ba38SDimitry Andric   if (D->hasAttr<VectorCallAttr>())
22806d4ba38SDimitry Andric     return CC_X86VectorCall;
22906d4ba38SDimitry Andric 
2303d1dcd9bSDimitry Andric   if (D->hasAttr<PascalAttr>())
2313d1dcd9bSDimitry Andric     return CC_X86Pascal;
2323d1dcd9bSDimitry Andric 
23301af97d3SDimitry Andric   if (PcsAttr *PCS = D->getAttr<PcsAttr>())
23401af97d3SDimitry Andric     return (PCS->getPCS() == PcsAttr::AAPCS ? CC_AAPCS : CC_AAPCS_VFP);
23501af97d3SDimitry Andric 
236676fbe81SDimitry Andric   if (D->hasAttr<AArch64VectorPcsAttr>())
237676fbe81SDimitry Andric     return CC_AArch64VectorCall;
238676fbe81SDimitry Andric 
239145449b1SDimitry Andric   if (D->hasAttr<AArch64SVEPcsAttr>())
240145449b1SDimitry Andric     return CC_AArch64SVEPCS;
241145449b1SDimitry Andric 
242145449b1SDimitry Andric   if (D->hasAttr<AMDGPUKernelCallAttr>())
243145449b1SDimitry Andric     return CC_AMDGPUKernelCall;
244145449b1SDimitry Andric 
245809500fcSDimitry Andric   if (D->hasAttr<IntelOclBiccAttr>())
246809500fcSDimitry Andric     return CC_IntelOclBicc;
247809500fcSDimitry Andric 
2489f4dbff6SDimitry Andric   if (D->hasAttr<MSABIAttr>())
249de51d671SDimitry Andric     return IsWindows ? CC_C : CC_Win64;
2509f4dbff6SDimitry Andric 
2519f4dbff6SDimitry Andric   if (D->hasAttr<SysVABIAttr>())
2529f4dbff6SDimitry Andric     return IsWindows ? CC_X86_64SysV : CC_C;
2539f4dbff6SDimitry Andric 
2542b6b257fSDimitry Andric   if (D->hasAttr<PreserveMostAttr>())
2552b6b257fSDimitry Andric     return CC_PreserveMost;
2562b6b257fSDimitry Andric 
2572b6b257fSDimitry Andric   if (D->hasAttr<PreserveAllAttr>())
2582b6b257fSDimitry Andric     return CC_PreserveAll;
2592b6b257fSDimitry Andric 
260b1c73532SDimitry Andric   if (D->hasAttr<M68kRTDAttr>())
261b1c73532SDimitry Andric     return CC_M68kRTD;
262b1c73532SDimitry Andric 
263ac9a064cSDimitry Andric   if (D->hasAttr<PreserveNoneAttr>())
264ac9a064cSDimitry Andric     return CC_PreserveNone;
265ac9a064cSDimitry Andric 
266ac9a064cSDimitry Andric   if (D->hasAttr<RISCVVectorCCAttr>())
267ac9a064cSDimitry Andric     return CC_RISCVVectorCall;
268ac9a064cSDimitry Andric 
269ecb7e5c8SRoman Divacky   return CC_C;
2704c8b2481SRoman Divacky }
2714c8b2481SRoman Divacky 
272dbe13110SDimitry Andric /// Arrange the argument and result information for a call to an
273dbe13110SDimitry Andric /// unknown C++ non-static member function of the given abstract type.
27422989816SDimitry Andric /// (A null RD means we don't have any meaningful "this" argument type,
275bfef3995SDimitry Andric ///  so fall back to a generic pointer type).
276dbe13110SDimitry Andric /// The member function must be an ordinary function, i.e. not a
277dbe13110SDimitry Andric /// constructor or destructor.
278dbe13110SDimitry Andric const CGFunctionInfo &
arrangeCXXMethodType(const CXXRecordDecl * RD,const FunctionProtoType * FTP,const CXXMethodDecl * MD)279dbe13110SDimitry Andric CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
28045b53394SDimitry Andric                                    const FunctionProtoType *FTP,
28145b53394SDimitry Andric                                    const CXXMethodDecl *MD) {
282dbe13110SDimitry Andric   SmallVector<CanQualType, 16> argTypes;
2834c8b2481SRoman Divacky 
2844c8b2481SRoman Divacky   // Add the 'this' pointer.
28522989816SDimitry Andric   argTypes.push_back(DeriveThisType(RD, MD));
2864c8b2481SRoman Divacky 
28706d4ba38SDimitry Andric   return ::arrangeLLVMFunctionInfo(
288b1c73532SDimitry Andric       *this, /*instanceMethod=*/true, argTypes,
28922989816SDimitry Andric       FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
290ec2b103cSEd Schouten }
291ec2b103cSEd Schouten 
29248675466SDimitry Andric /// Set calling convention for CUDA/HIP kernel.
setCUDAKernelCallingConvention(CanQualType & FTy,CodeGenModule & CGM,const FunctionDecl * FD)29348675466SDimitry Andric static void setCUDAKernelCallingConvention(CanQualType &FTy, CodeGenModule &CGM,
29448675466SDimitry Andric                                            const FunctionDecl *FD) {
29548675466SDimitry Andric   if (FD->hasAttr<CUDAGlobalAttr>()) {
29648675466SDimitry Andric     const FunctionType *FT = FTy->getAs<FunctionType>();
29748675466SDimitry Andric     CGM.getTargetCodeGenInfo().setCUDAKernelCallingConvention(FT);
29848675466SDimitry Andric     FTy = FT->getCanonicalTypeUnqualified();
29948675466SDimitry Andric   }
30048675466SDimitry Andric }
30148675466SDimitry Andric 
302dbe13110SDimitry Andric /// Arrange the argument and result information for a declaration or
303dbe13110SDimitry Andric /// definition of the given C++ non-static member function.  The
304dbe13110SDimitry Andric /// member function must be an ordinary function, i.e. not a
305dbe13110SDimitry Andric /// constructor or destructor.
306dbe13110SDimitry Andric const CGFunctionInfo &
arrangeCXXMethodDeclaration(const CXXMethodDecl * MD)307dbe13110SDimitry Andric CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) {
308bfef3995SDimitry Andric   assert(!isa<CXXConstructorDecl>(MD) && "wrong method for constructors!");
3093d1dcd9bSDimitry Andric   assert(!isa<CXXDestructorDecl>(MD) && "wrong method for destructors!");
3103d1dcd9bSDimitry Andric 
31148675466SDimitry Andric   CanQualType FT = GetFormalType(MD).getAs<Type>();
31248675466SDimitry Andric   setCUDAKernelCallingConvention(FT, CGM, MD);
31348675466SDimitry Andric   auto prototype = FT.getAs<FunctionProtoType>();
314ec2b103cSEd Schouten 
315b1c73532SDimitry Andric   if (MD->isImplicitObjectMemberFunction()) {
316dbe13110SDimitry Andric     // The abstract case is perfectly fine.
317e6b73279SDimitry Andric     const CXXRecordDecl *ThisType =
318e6b73279SDimitry Andric         getCXXABI().getThisArgumentTypeForMethod(MD);
31945b53394SDimitry Andric     return arrangeCXXMethodType(ThisType, prototype.getTypePtr(), MD);
320ec2b103cSEd Schouten   }
321ec2b103cSEd Schouten 
32222989816SDimitry Andric   return arrangeFreeFunctionType(prototype);
323dbe13110SDimitry Andric }
3241569ce68SRoman Divacky 
inheritingCtorHasParams(const InheritedConstructor & Inherited,CXXCtorType Type)3252b6b257fSDimitry Andric bool CodeGenTypes::inheritingCtorHasParams(
3262b6b257fSDimitry Andric     const InheritedConstructor &Inherited, CXXCtorType Type) {
3272b6b257fSDimitry Andric   // Parameters are unnecessary if we're constructing a base class subobject
3282b6b257fSDimitry Andric   // and the inherited constructor lives in a virtual base.
3292b6b257fSDimitry Andric   return Type == Ctor_Complete ||
3302b6b257fSDimitry Andric          !Inherited.getShadowDecl()->constructsVirtualBase() ||
3312b6b257fSDimitry Andric          !Target.getCXXABI().hasConstructorVariants();
3322b6b257fSDimitry Andric }
3332b6b257fSDimitry Andric 
334dbe13110SDimitry Andric const CGFunctionInfo &
arrangeCXXStructorDeclaration(GlobalDecl GD)33522989816SDimitry Andric CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
33622989816SDimitry Andric   auto *MD = cast<CXXMethodDecl>(GD.getDecl());
33706d4ba38SDimitry Andric 
338dbe13110SDimitry Andric   SmallVector<CanQualType, 16> argTypes;
3392b6b257fSDimitry Andric   SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
3407fa27ce4SDimitry Andric 
341e6b73279SDimitry Andric   const CXXRecordDecl *ThisType = getCXXABI().getThisArgumentTypeForMethod(GD);
3427fa27ce4SDimitry Andric   argTypes.push_back(DeriveThisType(ThisType, MD));
343bfef3995SDimitry Andric 
3442b6b257fSDimitry Andric   bool PassParams = true;
3452b6b257fSDimitry Andric 
34606d4ba38SDimitry Andric   if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3472b6b257fSDimitry Andric     // A base class inheriting constructor doesn't get forwarded arguments
3482b6b257fSDimitry Andric     // needed to construct a virtual base (or base class thereof).
3492b6b257fSDimitry Andric     if (auto Inherited = CD->getInheritedConstructor())
35022989816SDimitry Andric       PassParams = inheritingCtorHasParams(Inherited, GD.getCtorType());
35106d4ba38SDimitry Andric   }
352dbe13110SDimitry Andric 
35306d4ba38SDimitry Andric   CanQual<FunctionProtoType> FTP = GetFormalType(MD);
3543d1dcd9bSDimitry Andric 
3553d1dcd9bSDimitry Andric   // Add the formal parameters.
3562b6b257fSDimitry Andric   if (PassParams)
3577442d6faSDimitry Andric     appendParameterTypes(*this, argTypes, paramInfos, FTP);
3589f4dbff6SDimitry Andric 
359cfca06d7SDimitry Andric   CGCXXABI::AddedStructorArgCounts AddedArgs =
360e6b73279SDimitry Andric       getCXXABI().buildStructorSignature(GD, argTypes);
3617442d6faSDimitry Andric   if (!paramInfos.empty()) {
3627442d6faSDimitry Andric     // Note: prefix implies after the first param.
3637442d6faSDimitry Andric     if (AddedArgs.Prefix)
3647442d6faSDimitry Andric       paramInfos.insert(paramInfos.begin() + 1, AddedArgs.Prefix,
3657442d6faSDimitry Andric                         FunctionProtoType::ExtParameterInfo{});
3667442d6faSDimitry Andric     if (AddedArgs.Suffix)
3677442d6faSDimitry Andric       paramInfos.append(AddedArgs.Suffix,
3687442d6faSDimitry Andric                         FunctionProtoType::ExtParameterInfo{});
3697442d6faSDimitry Andric   }
3709f4dbff6SDimitry Andric 
3719f4dbff6SDimitry Andric   RequiredArgs required =
3722b6b257fSDimitry Andric       (PassParams && MD->isVariadic() ? RequiredArgs(argTypes.size())
3732b6b257fSDimitry Andric                                       : RequiredArgs::All);
3743d1dcd9bSDimitry Andric 
37556d91b49SDimitry Andric   FunctionType::ExtInfo extInfo = FTP->getExtInfo();
376e6b73279SDimitry Andric   CanQualType resultType = getCXXABI().HasThisReturn(GD) ? argTypes.front()
377e6b73279SDimitry Andric                            : getCXXABI().hasMostDerivedReturn(GD)
37806d4ba38SDimitry Andric                                ? CGM.getContext().VoidPtrTy
37906d4ba38SDimitry Andric                                : Context.VoidTy;
380b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::IsInstanceMethod,
381b1c73532SDimitry Andric                                  argTypes, extInfo, paramInfos, required);
3822b6b257fSDimitry Andric }
3832b6b257fSDimitry Andric 
3842b6b257fSDimitry Andric static SmallVector<CanQualType, 16>
getArgTypesForCall(ASTContext & ctx,const CallArgList & args)3852b6b257fSDimitry Andric getArgTypesForCall(ASTContext &ctx, const CallArgList &args) {
3862b6b257fSDimitry Andric   SmallVector<CanQualType, 16> argTypes;
3872b6b257fSDimitry Andric   for (auto &arg : args)
3882b6b257fSDimitry Andric     argTypes.push_back(ctx.getCanonicalParamType(arg.Ty));
3892b6b257fSDimitry Andric   return argTypes;
3902b6b257fSDimitry Andric }
3912b6b257fSDimitry Andric 
3922b6b257fSDimitry Andric static SmallVector<CanQualType, 16>
getArgTypesForDeclaration(ASTContext & ctx,const FunctionArgList & args)3932b6b257fSDimitry Andric getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args) {
3942b6b257fSDimitry Andric   SmallVector<CanQualType, 16> argTypes;
3952b6b257fSDimitry Andric   for (auto &arg : args)
3962b6b257fSDimitry Andric     argTypes.push_back(ctx.getCanonicalParamType(arg->getType()));
3972b6b257fSDimitry Andric   return argTypes;
3982b6b257fSDimitry Andric }
3992b6b257fSDimitry Andric 
4002b6b257fSDimitry Andric static llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16>
getExtParameterInfosForCall(const FunctionProtoType * proto,unsigned prefixArgs,unsigned totalArgs)4012b6b257fSDimitry Andric getExtParameterInfosForCall(const FunctionProtoType *proto,
4022b6b257fSDimitry Andric                             unsigned prefixArgs, unsigned totalArgs) {
4032b6b257fSDimitry Andric   llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> result;
4042b6b257fSDimitry Andric   if (proto->hasExtParameterInfos()) {
4052b6b257fSDimitry Andric     addExtParameterInfosForCall(result, proto, prefixArgs, totalArgs);
4062b6b257fSDimitry Andric   }
4072b6b257fSDimitry Andric   return result;
4089f4dbff6SDimitry Andric }
4099f4dbff6SDimitry Andric 
4109f4dbff6SDimitry Andric /// Arrange a call to a C++ method, passing the given arguments.
4117442d6faSDimitry Andric ///
4127442d6faSDimitry Andric /// ExtraPrefixArgs is the number of ABI-specific args passed after the `this`
4137442d6faSDimitry Andric /// parameter.
4147442d6faSDimitry Andric /// ExtraSuffixArgs is the number of ABI-specific args passed at the end of
4157442d6faSDimitry Andric /// args.
4167442d6faSDimitry Andric /// PassProtoArgs indicates whether `args` has args for the parameters in the
4177442d6faSDimitry Andric /// given CXXConstructorDecl.
4189f4dbff6SDimitry Andric const CGFunctionInfo &
arrangeCXXConstructorCall(const CallArgList & args,const CXXConstructorDecl * D,CXXCtorType CtorKind,unsigned ExtraPrefixArgs,unsigned ExtraSuffixArgs,bool PassProtoArgs)4199f4dbff6SDimitry Andric CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
4209f4dbff6SDimitry Andric                                         const CXXConstructorDecl *D,
4219f4dbff6SDimitry Andric                                         CXXCtorType CtorKind,
4227442d6faSDimitry Andric                                         unsigned ExtraPrefixArgs,
4237442d6faSDimitry Andric                                         unsigned ExtraSuffixArgs,
4247442d6faSDimitry Andric                                         bool PassProtoArgs) {
4259f4dbff6SDimitry Andric   // FIXME: Kill copy.
4269f4dbff6SDimitry Andric   SmallVector<CanQualType, 16> ArgTypes;
42706d4ba38SDimitry Andric   for (const auto &Arg : args)
42806d4ba38SDimitry Andric     ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
4299f4dbff6SDimitry Andric 
4307442d6faSDimitry Andric   // +1 for implicit this, which should always be args[0].
4317442d6faSDimitry Andric   unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
4327442d6faSDimitry Andric 
4339f4dbff6SDimitry Andric   CanQual<FunctionProtoType> FPT = GetFormalType(D);
43422989816SDimitry Andric   RequiredArgs Required = PassProtoArgs
43522989816SDimitry Andric                               ? RequiredArgs::forPrototypePlus(
43622989816SDimitry Andric                                     FPT, TotalPrefixArgs + ExtraSuffixArgs)
43722989816SDimitry Andric                               : RequiredArgs::All;
43822989816SDimitry Andric 
4399f4dbff6SDimitry Andric   GlobalDecl GD(D, CtorKind);
440e6b73279SDimitry Andric   CanQualType ResultType = getCXXABI().HasThisReturn(GD) ? ArgTypes.front()
441e6b73279SDimitry Andric                            : getCXXABI().hasMostDerivedReturn(GD)
44206d4ba38SDimitry Andric                                ? CGM.getContext().VoidPtrTy
44306d4ba38SDimitry Andric                                : Context.VoidTy;
4449f4dbff6SDimitry Andric 
4459f4dbff6SDimitry Andric   FunctionType::ExtInfo Info = FPT->getExtInfo();
4467442d6faSDimitry Andric   llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> ParamInfos;
4477442d6faSDimitry Andric   // If the prototype args are elided, we should only have ABI-specific args,
4487442d6faSDimitry Andric   // which never have param info.
4497442d6faSDimitry Andric   if (PassProtoArgs && FPT->hasExtParameterInfos()) {
4507442d6faSDimitry Andric     // ABI-specific suffix arguments are treated the same as variadic arguments.
4517442d6faSDimitry Andric     addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
4522b6b257fSDimitry Andric                                 ArgTypes.size());
4537442d6faSDimitry Andric   }
454b1c73532SDimitry Andric 
455b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(ResultType, FnInfoOpts::IsInstanceMethod,
456b1c73532SDimitry Andric                                  ArgTypes, Info, ParamInfos, Required);
4571569ce68SRoman Divacky }
4581569ce68SRoman Divacky 
459dbe13110SDimitry Andric /// Arrange the argument and result information for the declaration or
460dbe13110SDimitry Andric /// definition of the given function.
461dbe13110SDimitry Andric const CGFunctionInfo &
arrangeFunctionDeclaration(const FunctionDecl * FD)462dbe13110SDimitry Andric CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
463ec2b103cSEd Schouten   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
464b1c73532SDimitry Andric     if (MD->isImplicitObjectMemberFunction())
465dbe13110SDimitry Andric       return arrangeCXXMethodDeclaration(MD);
466ec2b103cSEd Schouten 
46779ade4e0SRoman Divacky   CanQualType FTy = FD->getType()->getCanonicalTypeUnqualified();
468dbe13110SDimitry Andric 
46979ade4e0SRoman Divacky   assert(isa<FunctionType>(FTy));
47048675466SDimitry Andric   setCUDAKernelCallingConvention(FTy, CGM, FD);
471dbe13110SDimitry Andric 
472dbe13110SDimitry Andric   // When declaring a function without a prototype, always use a
473dbe13110SDimitry Andric   // non-variadic type.
4746694ed09SDimitry Andric   if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
475b1c73532SDimitry Andric     return arrangeLLVMFunctionInfo(noProto->getReturnType(), FnInfoOpts::None,
476b1c73532SDimitry Andric                                    std::nullopt, noProto->getExtInfo(), {},
477e3b55780SDimitry Andric                                    RequiredArgs::All);
478ec2b103cSEd Schouten   }
479ec2b103cSEd Schouten 
48022989816SDimitry Andric   return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
481dbe13110SDimitry Andric }
482dbe13110SDimitry Andric 
483dbe13110SDimitry Andric /// Arrange the argument and result information for the declaration or
484dbe13110SDimitry Andric /// definition of an Objective-C method.
485dbe13110SDimitry Andric const CGFunctionInfo &
arrangeObjCMethodDeclaration(const ObjCMethodDecl * MD)486dbe13110SDimitry Andric CodeGenTypes::arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD) {
487dbe13110SDimitry Andric   // It happens that this is the same as a call with no optional
488dbe13110SDimitry Andric   // arguments, except also using the formal 'self' type.
489dbe13110SDimitry Andric   return arrangeObjCMessageSendSignature(MD, MD->getSelfDecl()->getType());
490dbe13110SDimitry Andric }
491dbe13110SDimitry Andric 
492dbe13110SDimitry Andric /// Arrange the argument and result information for the function type
493dbe13110SDimitry Andric /// through which to perform a send to the given Objective-C method,
494dbe13110SDimitry Andric /// using the given receiver type.  The receiver type is not always
495dbe13110SDimitry Andric /// the 'self' type of the method or even an Objective-C pointer type.
496dbe13110SDimitry Andric /// This is *not* the right method for actually performing such a
497dbe13110SDimitry Andric /// message send, due to the possibility of optional arguments.
498dbe13110SDimitry Andric const CGFunctionInfo &
arrangeObjCMessageSendSignature(const ObjCMethodDecl * MD,QualType receiverType)499dbe13110SDimitry Andric CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
500dbe13110SDimitry Andric                                               QualType receiverType) {
501dbe13110SDimitry Andric   SmallVector<CanQualType, 16> argTys;
502e3b55780SDimitry Andric   SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(
503e3b55780SDimitry Andric       MD->isDirectMethod() ? 1 : 2);
504dbe13110SDimitry Andric   argTys.push_back(Context.getCanonicalParamType(receiverType));
505e3b55780SDimitry Andric   if (!MD->isDirectMethod())
506dbe13110SDimitry Andric     argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
507ec2b103cSEd Schouten   // FIXME: Kill copy?
5082b6b257fSDimitry Andric   for (const auto *I : MD->parameters()) {
5099f4dbff6SDimitry Andric     argTys.push_back(Context.getCanonicalParamType(I->getType()));
510461a67faSDimitry Andric     auto extParamInfo = FunctionProtoType::ExtParameterInfo().withIsNoEscape(
511461a67faSDimitry Andric         I->hasAttr<NoEscapeAttr>());
512461a67faSDimitry Andric     extParamInfos.push_back(extParamInfo);
51379ade4e0SRoman Divacky   }
514180abc3dSDimitry Andric 
515180abc3dSDimitry Andric   FunctionType::ExtInfo einfo;
5169f4dbff6SDimitry Andric   bool IsWindows = getContext().getTargetInfo().getTriple().isOSWindows();
5179f4dbff6SDimitry Andric   einfo = einfo.withCallingConv(getCallingConventionForDecl(MD, IsWindows));
518180abc3dSDimitry Andric 
519dbe13110SDimitry Andric   if (getContext().getLangOpts().ObjCAutoRefCount &&
520180abc3dSDimitry Andric       MD->hasAttr<NSReturnsRetainedAttr>())
521180abc3dSDimitry Andric     einfo = einfo.withProducesResult(true);
522180abc3dSDimitry Andric 
523dbe13110SDimitry Andric   RequiredArgs required =
524dbe13110SDimitry Andric     (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
525dbe13110SDimitry Andric 
526b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()),
527b1c73532SDimitry Andric                                  FnInfoOpts::None, argTys, einfo, extParamInfos,
528b1c73532SDimitry Andric                                  required);
5292b6b257fSDimitry Andric }
5302b6b257fSDimitry Andric 
5312b6b257fSDimitry Andric const CGFunctionInfo &
arrangeUnprototypedObjCMessageSend(QualType returnType,const CallArgList & args)5322b6b257fSDimitry Andric CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
5332b6b257fSDimitry Andric                                                  const CallArgList &args) {
5342b6b257fSDimitry Andric   auto argTypes = getArgTypesForCall(Context, args);
5352b6b257fSDimitry Andric   FunctionType::ExtInfo einfo;
5362b6b257fSDimitry Andric 
537b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(GetReturnType(returnType), FnInfoOpts::None,
538b1c73532SDimitry Andric                                  argTypes, einfo, {}, RequiredArgs::All);
539ecb7e5c8SRoman Divacky }
540ecb7e5c8SRoman Divacky 
541dbe13110SDimitry Andric const CGFunctionInfo &
arrangeGlobalDeclaration(GlobalDecl GD)542dbe13110SDimitry Andric CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) {
543ecb7e5c8SRoman Divacky   // FIXME: Do we need to handle ObjCMethodDecl?
544ecb7e5c8SRoman Divacky   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
545ecb7e5c8SRoman Divacky 
54622989816SDimitry Andric   if (isa<CXXConstructorDecl>(GD.getDecl()) ||
54722989816SDimitry Andric       isa<CXXDestructorDecl>(GD.getDecl()))
54822989816SDimitry Andric     return arrangeCXXStructorDeclaration(GD);
549ecb7e5c8SRoman Divacky 
550dbe13110SDimitry Andric   return arrangeFunctionDeclaration(FD);
551ec2b103cSEd Schouten }
552ec2b103cSEd Schouten 
55306d4ba38SDimitry Andric /// Arrange a thunk that takes 'this' as the first parameter followed by
55406d4ba38SDimitry Andric /// varargs.  Return a void pointer, regardless of the actual return type.
55506d4ba38SDimitry Andric /// The body of the thunk will end in a musttail call to a function of the
55606d4ba38SDimitry Andric /// correct type, and the caller will bitcast the function to the correct
55706d4ba38SDimitry Andric /// prototype.
55806d4ba38SDimitry Andric const CGFunctionInfo &
arrangeUnprototypedMustTailThunk(const CXXMethodDecl * MD)55948675466SDimitry Andric CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
56048675466SDimitry Andric   assert(MD->isVirtual() && "only methods have thunks");
56106d4ba38SDimitry Andric   CanQual<FunctionProtoType> FTP = GetFormalType(MD);
56222989816SDimitry Andric   CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
563b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::None, ArgTys,
5642b6b257fSDimitry Andric                                  FTP->getExtInfo(), {}, RequiredArgs(1));
56506d4ba38SDimitry Andric }
56606d4ba38SDimitry Andric 
5675e20cdd8SDimitry Andric const CGFunctionInfo &
arrangeMSCtorClosure(const CXXConstructorDecl * CD,CXXCtorType CT)5685e20cdd8SDimitry Andric CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
5695e20cdd8SDimitry Andric                                    CXXCtorType CT) {
5705e20cdd8SDimitry Andric   assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure);
5715e20cdd8SDimitry Andric 
5725e20cdd8SDimitry Andric   CanQual<FunctionProtoType> FTP = GetFormalType(CD);
5735e20cdd8SDimitry Andric   SmallVector<CanQualType, 2> ArgTys;
5745e20cdd8SDimitry Andric   const CXXRecordDecl *RD = CD->getParent();
57522989816SDimitry Andric   ArgTys.push_back(DeriveThisType(RD, CD));
5765e20cdd8SDimitry Andric   if (CT == Ctor_CopyingClosure)
5775e20cdd8SDimitry Andric     ArgTys.push_back(*FTP->param_type_begin());
5785e20cdd8SDimitry Andric   if (RD->getNumVBases() > 0)
5795e20cdd8SDimitry Andric     ArgTys.push_back(Context.IntTy);
5805e20cdd8SDimitry Andric   CallingConv CC = Context.getDefaultCallingConvention(
5815e20cdd8SDimitry Andric       /*IsVariadic=*/false, /*IsCXXMethod=*/true);
582b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::IsInstanceMethod,
583b1c73532SDimitry Andric                                  ArgTys, FunctionType::ExtInfo(CC), {},
5842b6b257fSDimitry Andric                                  RequiredArgs::All);
5855e20cdd8SDimitry Andric }
5865e20cdd8SDimitry Andric 
587809500fcSDimitry Andric /// Arrange a call as unto a free function, except possibly with an
588809500fcSDimitry Andric /// additional number of formal parameters considered required.
589809500fcSDimitry Andric static const CGFunctionInfo &
arrangeFreeFunctionLikeCall(CodeGenTypes & CGT,CodeGenModule & CGM,const CallArgList & args,const FunctionType * fnType,unsigned numExtraRequiredArgs,bool chainCall)590809500fcSDimitry Andric arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
591bfef3995SDimitry Andric                             CodeGenModule &CGM,
592809500fcSDimitry Andric                             const CallArgList &args,
593809500fcSDimitry Andric                             const FunctionType *fnType,
59406d4ba38SDimitry Andric                             unsigned numExtraRequiredArgs,
59506d4ba38SDimitry Andric                             bool chainCall) {
596809500fcSDimitry Andric   assert(args.size() >= numExtraRequiredArgs);
597809500fcSDimitry Andric 
5982b6b257fSDimitry Andric   llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
5992b6b257fSDimitry Andric 
600809500fcSDimitry Andric   // In most cases, there are no optional arguments.
601809500fcSDimitry Andric   RequiredArgs required = RequiredArgs::All;
602809500fcSDimitry Andric 
603809500fcSDimitry Andric   // If we have a variadic prototype, the required arguments are the
604809500fcSDimitry Andric   // extra prefix plus the arguments in the prototype.
605809500fcSDimitry Andric   if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
606809500fcSDimitry Andric     if (proto->isVariadic())
60722989816SDimitry Andric       required = RequiredArgs::forPrototypePlus(proto, numExtraRequiredArgs);
608809500fcSDimitry Andric 
6092b6b257fSDimitry Andric     if (proto->hasExtParameterInfos())
6102b6b257fSDimitry Andric       addExtParameterInfosForCall(paramInfos, proto, numExtraRequiredArgs,
6112b6b257fSDimitry Andric                                   args.size());
6122b6b257fSDimitry Andric 
613809500fcSDimitry Andric   // If we don't have a prototype at all, but we're supposed to
614809500fcSDimitry Andric   // explicitly use the variadic convention for unprototyped calls,
615809500fcSDimitry Andric   // treat all of the arguments as required but preserve the nominal
616809500fcSDimitry Andric   // possibility of variadics.
617bfef3995SDimitry Andric   } else if (CGM.getTargetCodeGenInfo()
618bfef3995SDimitry Andric                 .isNoProtoCallVariadic(args,
619bfef3995SDimitry Andric                                        cast<FunctionNoProtoType>(fnType))) {
620809500fcSDimitry Andric     required = RequiredArgs(args.size());
621809500fcSDimitry Andric   }
622809500fcSDimitry Andric 
62306d4ba38SDimitry Andric   // FIXME: Kill copy.
62406d4ba38SDimitry Andric   SmallVector<CanQualType, 16> argTypes;
62506d4ba38SDimitry Andric   for (const auto &arg : args)
62606d4ba38SDimitry Andric     argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
627b1c73532SDimitry Andric   FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
62806d4ba38SDimitry Andric   return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
629b1c73532SDimitry Andric                                      opts, argTypes, fnType->getExtInfo(),
630b1c73532SDimitry Andric                                      paramInfos, required);
631809500fcSDimitry Andric }
632809500fcSDimitry Andric 
633dbe13110SDimitry Andric /// Figure out the rules for calling a function with the given formal
634dbe13110SDimitry Andric /// type using the given arguments.  The arguments are necessary
635dbe13110SDimitry Andric /// because the function might be unprototyped, in which case it's
636dbe13110SDimitry Andric /// target-dependent in crazy ways.
637dbe13110SDimitry Andric const CGFunctionInfo &
arrangeFreeFunctionCall(const CallArgList & args,const FunctionType * fnType,bool chainCall)63856d91b49SDimitry Andric CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args,
63906d4ba38SDimitry Andric                                       const FunctionType *fnType,
64006d4ba38SDimitry Andric                                       bool chainCall) {
64106d4ba38SDimitry Andric   return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType,
64206d4ba38SDimitry Andric                                      chainCall ? 1 : 0, chainCall);
643dbe13110SDimitry Andric }
644dbe13110SDimitry Andric 
6452b6b257fSDimitry Andric /// A block function is essentially a free function with an
646809500fcSDimitry Andric /// extra implicit argument.
647809500fcSDimitry Andric const CGFunctionInfo &
arrangeBlockFunctionCall(const CallArgList & args,const FunctionType * fnType)648809500fcSDimitry Andric CodeGenTypes::arrangeBlockFunctionCall(const CallArgList &args,
649809500fcSDimitry Andric                                        const FunctionType *fnType) {
65006d4ba38SDimitry Andric   return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 1,
65106d4ba38SDimitry Andric                                      /*chainCall=*/false);
652dbe13110SDimitry Andric }
653dbe13110SDimitry Andric 
654dbe13110SDimitry Andric const CGFunctionInfo &
arrangeBlockFunctionDeclaration(const FunctionProtoType * proto,const FunctionArgList & params)6552b6b257fSDimitry Andric CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
6562b6b257fSDimitry Andric                                               const FunctionArgList &params) {
6572b6b257fSDimitry Andric   auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size());
6582b6b257fSDimitry Andric   auto argTypes = getArgTypesForDeclaration(Context, params);
6592b6b257fSDimitry Andric 
66022989816SDimitry Andric   return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
661b1c73532SDimitry Andric                                  FnInfoOpts::None, argTypes,
662b1c73532SDimitry Andric                                  proto->getExtInfo(), paramInfos,
66322989816SDimitry Andric                                  RequiredArgs::forPrototypePlus(proto, 1));
6642b6b257fSDimitry Andric }
6652b6b257fSDimitry Andric 
6662b6b257fSDimitry Andric const CGFunctionInfo &
arrangeBuiltinFunctionCall(QualType resultType,const CallArgList & args)6672b6b257fSDimitry Andric CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
6682b6b257fSDimitry Andric                                          const CallArgList &args) {
669ec2b103cSEd Schouten   // FIXME: Kill copy.
670dbe13110SDimitry Andric   SmallVector<CanQualType, 16> argTypes;
67106d4ba38SDimitry Andric   for (const auto &Arg : args)
67206d4ba38SDimitry Andric     argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
673b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
674b1c73532SDimitry Andric                                  argTypes, FunctionType::ExtInfo(),
6752b6b257fSDimitry Andric                                  /*paramInfos=*/{}, RequiredArgs::All);
6762b6b257fSDimitry Andric }
6772b6b257fSDimitry Andric 
6782b6b257fSDimitry Andric const CGFunctionInfo &
arrangeBuiltinFunctionDeclaration(QualType resultType,const FunctionArgList & args)6792b6b257fSDimitry Andric CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType,
6802b6b257fSDimitry Andric                                                 const FunctionArgList &args) {
6812b6b257fSDimitry Andric   auto argTypes = getArgTypesForDeclaration(Context, args);
6822b6b257fSDimitry Andric 
683b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
684b1c73532SDimitry Andric                                  argTypes, FunctionType::ExtInfo(), {},
685b1c73532SDimitry Andric                                  RequiredArgs::All);
6862b6b257fSDimitry Andric }
6872b6b257fSDimitry Andric 
6882b6b257fSDimitry Andric const CGFunctionInfo &
arrangeBuiltinFunctionDeclaration(CanQualType resultType,ArrayRef<CanQualType> argTypes)6892b6b257fSDimitry Andric CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
6902b6b257fSDimitry Andric                                               ArrayRef<CanQualType> argTypes) {
691b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::None, argTypes,
692b1c73532SDimitry Andric                                  FunctionType::ExtInfo(), {},
693b1c73532SDimitry Andric                                  RequiredArgs::All);
694ec2b103cSEd Schouten }
695ec2b103cSEd Schouten 
69656d91b49SDimitry Andric /// Arrange a call to a C++ method, passing the given arguments.
6977442d6faSDimitry Andric ///
6987442d6faSDimitry Andric /// numPrefixArgs is the number of ABI-specific prefix arguments we have. It
6997442d6faSDimitry Andric /// does not count `this`.
70056d91b49SDimitry Andric const CGFunctionInfo &
arrangeCXXMethodCall(const CallArgList & args,const FunctionProtoType * proto,RequiredArgs required,unsigned numPrefixArgs)70156d91b49SDimitry Andric CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
7022b6b257fSDimitry Andric                                    const FunctionProtoType *proto,
7037442d6faSDimitry Andric                                    RequiredArgs required,
7047442d6faSDimitry Andric                                    unsigned numPrefixArgs) {
7057442d6faSDimitry Andric   assert(numPrefixArgs + 1 <= args.size() &&
7067442d6faSDimitry Andric          "Emitting a call with less args than the required prefix?");
7077442d6faSDimitry Andric   // Add one to account for `this`. It's a bit awkward here, but we don't count
7087442d6faSDimitry Andric   // `this` in similar places elsewhere.
7092b6b257fSDimitry Andric   auto paramInfos =
7107442d6faSDimitry Andric     getExtParameterInfosForCall(proto, numPrefixArgs + 1, args.size());
7112b6b257fSDimitry Andric 
71256d91b49SDimitry Andric   // FIXME: Kill copy.
7132b6b257fSDimitry Andric   auto argTypes = getArgTypesForCall(Context, args);
71456d91b49SDimitry Andric 
7152b6b257fSDimitry Andric   FunctionType::ExtInfo info = proto->getExtInfo();
716b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
717b1c73532SDimitry Andric                                  FnInfoOpts::IsInstanceMethod, argTypes, info,
718b1c73532SDimitry Andric                                  paramInfos, required);
719ec2b103cSEd Schouten }
720ec2b103cSEd Schouten 
arrangeNullaryFunction()721dbe13110SDimitry Andric const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
722b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(getContext().VoidTy, FnInfoOpts::None,
723b1c73532SDimitry Andric                                  std::nullopt, FunctionType::ExtInfo(), {},
724b1c73532SDimitry Andric                                  RequiredArgs::All);
7252b6b257fSDimitry Andric }
7262b6b257fSDimitry Andric 
7272b6b257fSDimitry Andric const CGFunctionInfo &
arrangeCall(const CGFunctionInfo & signature,const CallArgList & args)7282b6b257fSDimitry Andric CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
7292b6b257fSDimitry Andric                           const CallArgList &args) {
7302b6b257fSDimitry Andric   assert(signature.arg_size() <= args.size());
7312b6b257fSDimitry Andric   if (signature.arg_size() == args.size())
7322b6b257fSDimitry Andric     return signature;
7332b6b257fSDimitry Andric 
7342b6b257fSDimitry Andric   SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
7352b6b257fSDimitry Andric   auto sigParamInfos = signature.getExtParameterInfos();
7362b6b257fSDimitry Andric   if (!sigParamInfos.empty()) {
7372b6b257fSDimitry Andric     paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
7382b6b257fSDimitry Andric     paramInfos.resize(args.size());
7392b6b257fSDimitry Andric   }
7402b6b257fSDimitry Andric 
7412b6b257fSDimitry Andric   auto argTypes = getArgTypesForCall(Context, args);
7422b6b257fSDimitry Andric 
7432b6b257fSDimitry Andric   assert(signature.getRequiredArgs().allowsOptionalArgs());
744b1c73532SDimitry Andric   FnInfoOpts opts = FnInfoOpts::None;
745b1c73532SDimitry Andric   if (signature.isInstanceMethod())
746b1c73532SDimitry Andric     opts |= FnInfoOpts::IsInstanceMethod;
747b1c73532SDimitry Andric   if (signature.isChainCall())
748b1c73532SDimitry Andric     opts |= FnInfoOpts::IsChainCall;
749b1c73532SDimitry Andric   if (signature.isDelegateCall())
750b1c73532SDimitry Andric     opts |= FnInfoOpts::IsDelegateCall;
751b1c73532SDimitry Andric   return arrangeLLVMFunctionInfo(signature.getReturnType(), opts, argTypes,
752b1c73532SDimitry Andric                                  signature.getExtInfo(), paramInfos,
7532b6b257fSDimitry Andric                                  signature.getRequiredArgs());
75401af97d3SDimitry Andric }
75501af97d3SDimitry Andric 
756416ada0fSDimitry Andric namespace clang {
757416ada0fSDimitry Andric namespace CodeGen {
758416ada0fSDimitry Andric void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
759416ada0fSDimitry Andric }
760416ada0fSDimitry Andric }
761416ada0fSDimitry Andric 
762dbe13110SDimitry Andric /// Arrange the argument and result information for an abstract value
763dbe13110SDimitry Andric /// of a given function type.  This is the method which all of the
764dbe13110SDimitry Andric /// above functions ultimately defer to.
arrangeLLVMFunctionInfo(CanQualType resultType,FnInfoOpts opts,ArrayRef<CanQualType> argTypes,FunctionType::ExtInfo info,ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,RequiredArgs required)765b1c73532SDimitry Andric const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
766b1c73532SDimitry Andric     CanQualType resultType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
76756d91b49SDimitry Andric     FunctionType::ExtInfo info,
7682b6b257fSDimitry Andric     ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
769dbe13110SDimitry Andric     RequiredArgs required) {
770676fbe81SDimitry Andric   assert(llvm::all_of(argTypes,
7717442d6faSDimitry Andric                       [](CanQualType T) { return T.isCanonicalAsParam(); }));
77279ade4e0SRoman Divacky 
773ec2b103cSEd Schouten   // Lookup or create unique function info.
774ec2b103cSEd Schouten   llvm::FoldingSetNodeID ID;
775b1c73532SDimitry Andric   bool isInstanceMethod =
776b1c73532SDimitry Andric       (opts & FnInfoOpts::IsInstanceMethod) == FnInfoOpts::IsInstanceMethod;
777b1c73532SDimitry Andric   bool isChainCall =
778b1c73532SDimitry Andric       (opts & FnInfoOpts::IsChainCall) == FnInfoOpts::IsChainCall;
779b1c73532SDimitry Andric   bool isDelegateCall =
780b1c73532SDimitry Andric       (opts & FnInfoOpts::IsDelegateCall) == FnInfoOpts::IsDelegateCall;
781b1c73532SDimitry Andric   CGFunctionInfo::Profile(ID, isInstanceMethod, isChainCall, isDelegateCall,
782b1c73532SDimitry Andric                           info, paramInfos, required, resultType, argTypes);
783ec2b103cSEd Schouten 
7849f4dbff6SDimitry Andric   void *insertPos = nullptr;
785dbe13110SDimitry Andric   CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
786ec2b103cSEd Schouten   if (FI)
787ec2b103cSEd Schouten     return *FI;
788ec2b103cSEd Schouten 
7892b6b257fSDimitry Andric   unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
7902b6b257fSDimitry Andric 
791dbe13110SDimitry Andric   // Construct the function info.  We co-allocate the ArgInfos.
792b1c73532SDimitry Andric   FI = CGFunctionInfo::create(CC, isInstanceMethod, isChainCall, isDelegateCall,
793b1c73532SDimitry Andric                               info, paramInfos, resultType, argTypes, required);
794dbe13110SDimitry Andric   FunctionInfos.InsertNode(FI, insertPos);
795ec2b103cSEd Schouten 
79606d4ba38SDimitry Andric   bool inserted = FunctionsBeingProcessed.insert(FI).second;
79706d4ba38SDimitry Andric   (void)inserted;
798dbe13110SDimitry Andric   assert(inserted && "Recursively being processed?");
799180abc3dSDimitry Andric 
800ec2b103cSEd Schouten   // Compute ABI information.
801416ada0fSDimitry Andric   if (CC == llvm::CallingConv::SPIR_KERNEL) {
802416ada0fSDimitry Andric     // Force target independent argument handling for the host visible
803416ada0fSDimitry Andric     // kernel functions.
804416ada0fSDimitry Andric     computeSPIRKernelABIInfo(CGM, *FI);
805344a3780SDimitry Andric   } else if (info.getCC() == CC_Swift || info.getCC() == CC_SwiftAsync) {
8062b6b257fSDimitry Andric     swiftcall::computeABIInfo(CGM, *FI);
807416ada0fSDimitry Andric   } else {
808e6b73279SDimitry Andric     CGM.getABIInfo().computeInfo(*FI);
8092b6b257fSDimitry Andric   }
8103d1dcd9bSDimitry Andric 
8113d1dcd9bSDimitry Andric   // Loop over all of the computed argument and return value info.  If any of
8123d1dcd9bSDimitry Andric   // them are direct or extend without a specified coerce type, specify the
8133d1dcd9bSDimitry Andric   // default now.
814dbe13110SDimitry Andric   ABIArgInfo &retInfo = FI->getReturnInfo();
8159f4dbff6SDimitry Andric   if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
816dbe13110SDimitry Andric     retInfo.setCoerceToType(ConvertType(FI->getReturnType()));
8173d1dcd9bSDimitry Andric 
8189f4dbff6SDimitry Andric   for (auto &I : FI->arguments())
8199f4dbff6SDimitry Andric     if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() == nullptr)
8209f4dbff6SDimitry Andric       I.info.setCoerceToType(ConvertType(I.type));
8214ba67500SRoman Divacky 
822dbe13110SDimitry Andric   bool erased = FunctionsBeingProcessed.erase(FI); (void)erased;
823dbe13110SDimitry Andric   assert(erased && "Not in set?");
824ec2b103cSEd Schouten 
825ec2b103cSEd Schouten   return *FI;
826ec2b103cSEd Schouten }
827ec2b103cSEd Schouten 
create(unsigned llvmCC,bool instanceMethod,bool chainCall,bool delegateCall,const FunctionType::ExtInfo & info,ArrayRef<ExtParameterInfo> paramInfos,CanQualType resultType,ArrayRef<CanQualType> argTypes,RequiredArgs required)828b1c73532SDimitry Andric CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
829b1c73532SDimitry Andric                                        bool chainCall, bool delegateCall,
830dbe13110SDimitry Andric                                        const FunctionType::ExtInfo &info,
8312b6b257fSDimitry Andric                                        ArrayRef<ExtParameterInfo> paramInfos,
832dbe13110SDimitry Andric                                        CanQualType resultType,
833dbe13110SDimitry Andric                                        ArrayRef<CanQualType> argTypes,
834dbe13110SDimitry Andric                                        RequiredArgs required) {
8352b6b257fSDimitry Andric   assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
83622989816SDimitry Andric   assert(!required.allowsOptionalArgs() ||
83722989816SDimitry Andric          required.getNumRequiredArgs() <= argTypes.size());
8382b6b257fSDimitry Andric 
8392b6b257fSDimitry Andric   void *buffer =
8402b6b257fSDimitry Andric     operator new(totalSizeToAlloc<ArgInfo,             ExtParameterInfo>(
8412b6b257fSDimitry Andric                                   argTypes.size() + 1, paramInfos.size()));
8422b6b257fSDimitry Andric 
843dbe13110SDimitry Andric   CGFunctionInfo *FI = new(buffer) CGFunctionInfo();
844dbe13110SDimitry Andric   FI->CallingConvention = llvmCC;
845dbe13110SDimitry Andric   FI->EffectiveCallingConvention = llvmCC;
846dbe13110SDimitry Andric   FI->ASTCallingConvention = info.getCC();
84706d4ba38SDimitry Andric   FI->InstanceMethod = instanceMethod;
84806d4ba38SDimitry Andric   FI->ChainCall = chainCall;
849b1c73532SDimitry Andric   FI->DelegateCall = delegateCall;
850cfca06d7SDimitry Andric   FI->CmseNSCall = info.getCmseNSCall();
851dbe13110SDimitry Andric   FI->NoReturn = info.getNoReturn();
852dbe13110SDimitry Andric   FI->ReturnsRetained = info.getProducesResult();
85357091882SDimitry Andric   FI->NoCallerSavedRegs = info.getNoCallerSavedRegs();
85448675466SDimitry Andric   FI->NoCfCheck = info.getNoCfCheck();
855dbe13110SDimitry Andric   FI->Required = required;
856dbe13110SDimitry Andric   FI->HasRegParm = info.getHasRegParm();
857dbe13110SDimitry Andric   FI->RegParm = info.getRegParm();
8589f4dbff6SDimitry Andric   FI->ArgStruct = nullptr;
85945b53394SDimitry Andric   FI->ArgStructAlign = 0;
860dbe13110SDimitry Andric   FI->NumArgs = argTypes.size();
8612b6b257fSDimitry Andric   FI->HasExtParameterInfos = !paramInfos.empty();
862dbe13110SDimitry Andric   FI->getArgsBuffer()[0].type = resultType;
863145449b1SDimitry Andric   FI->MaxVectorWidth = 0;
864dbe13110SDimitry Andric   for (unsigned i = 0, e = argTypes.size(); i != e; ++i)
865dbe13110SDimitry Andric     FI->getArgsBuffer()[i + 1].type = argTypes[i];
8662b6b257fSDimitry Andric   for (unsigned i = 0, e = paramInfos.size(); i != e; ++i)
8672b6b257fSDimitry Andric     FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
868dbe13110SDimitry Andric   return FI;
869ec2b103cSEd Schouten }
870ec2b103cSEd Schouten 
871ec2b103cSEd Schouten /***/
872ec2b103cSEd Schouten 
87306d4ba38SDimitry Andric namespace {
87406d4ba38SDimitry Andric // ABIArgInfo::Expand implementation.
87506d4ba38SDimitry Andric 
87606d4ba38SDimitry Andric // Specifies the way QualType passed as ABIArgInfo::Expand is expanded.
87706d4ba38SDimitry Andric struct TypeExpansion {
87806d4ba38SDimitry Andric   enum TypeExpansionKind {
87906d4ba38SDimitry Andric     // Elements of constant arrays are expanded recursively.
88006d4ba38SDimitry Andric     TEK_ConstantArray,
88106d4ba38SDimitry Andric     // Record fields are expanded recursively (but if record is a union, only
88206d4ba38SDimitry Andric     // the field with the largest size is expanded).
88306d4ba38SDimitry Andric     TEK_Record,
88406d4ba38SDimitry Andric     // For complex types, real and imaginary parts are expanded recursively.
88506d4ba38SDimitry Andric     TEK_Complex,
88606d4ba38SDimitry Andric     // All other types are not expandable.
88706d4ba38SDimitry Andric     TEK_None
88806d4ba38SDimitry Andric   };
88906d4ba38SDimitry Andric 
89006d4ba38SDimitry Andric   const TypeExpansionKind Kind;
89106d4ba38SDimitry Andric 
TypeExpansion__anon748148590211::TypeExpansion89206d4ba38SDimitry Andric   TypeExpansion(TypeExpansionKind K) : Kind(K) {}
~TypeExpansion__anon748148590211::TypeExpansion89306d4ba38SDimitry Andric   virtual ~TypeExpansion() {}
89406d4ba38SDimitry Andric };
89506d4ba38SDimitry Andric 
89606d4ba38SDimitry Andric struct ConstantArrayExpansion : TypeExpansion {
89706d4ba38SDimitry Andric   QualType EltTy;
89806d4ba38SDimitry Andric   uint64_t NumElts;
89906d4ba38SDimitry Andric 
ConstantArrayExpansion__anon748148590211::ConstantArrayExpansion90006d4ba38SDimitry Andric   ConstantArrayExpansion(QualType EltTy, uint64_t NumElts)
90106d4ba38SDimitry Andric       : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
classof__anon748148590211::ConstantArrayExpansion90206d4ba38SDimitry Andric   static bool classof(const TypeExpansion *TE) {
90306d4ba38SDimitry Andric     return TE->Kind == TEK_ConstantArray;
90406d4ba38SDimitry Andric   }
90506d4ba38SDimitry Andric };
90606d4ba38SDimitry Andric 
90706d4ba38SDimitry Andric struct RecordExpansion : TypeExpansion {
90806d4ba38SDimitry Andric   SmallVector<const CXXBaseSpecifier *, 1> Bases;
90906d4ba38SDimitry Andric 
91006d4ba38SDimitry Andric   SmallVector<const FieldDecl *, 1> Fields;
91106d4ba38SDimitry Andric 
RecordExpansion__anon748148590211::RecordExpansion91206d4ba38SDimitry Andric   RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases,
91306d4ba38SDimitry Andric                   SmallVector<const FieldDecl *, 1> &&Fields)
9142b6b257fSDimitry Andric       : TypeExpansion(TEK_Record), Bases(std::move(Bases)),
9152b6b257fSDimitry Andric         Fields(std::move(Fields)) {}
classof__anon748148590211::RecordExpansion91606d4ba38SDimitry Andric   static bool classof(const TypeExpansion *TE) {
91706d4ba38SDimitry Andric     return TE->Kind == TEK_Record;
91806d4ba38SDimitry Andric   }
91906d4ba38SDimitry Andric };
92006d4ba38SDimitry Andric 
92106d4ba38SDimitry Andric struct ComplexExpansion : TypeExpansion {
92206d4ba38SDimitry Andric   QualType EltTy;
92306d4ba38SDimitry Andric 
ComplexExpansion__anon748148590211::ComplexExpansion92406d4ba38SDimitry Andric   ComplexExpansion(QualType EltTy) : TypeExpansion(TEK_Complex), EltTy(EltTy) {}
classof__anon748148590211::ComplexExpansion92506d4ba38SDimitry Andric   static bool classof(const TypeExpansion *TE) {
92606d4ba38SDimitry Andric     return TE->Kind == TEK_Complex;
92706d4ba38SDimitry Andric   }
92806d4ba38SDimitry Andric };
92906d4ba38SDimitry Andric 
93006d4ba38SDimitry Andric struct NoExpansion : TypeExpansion {
NoExpansion__anon748148590211::NoExpansion93106d4ba38SDimitry Andric   NoExpansion() : TypeExpansion(TEK_None) {}
classof__anon748148590211::NoExpansion93206d4ba38SDimitry Andric   static bool classof(const TypeExpansion *TE) {
93306d4ba38SDimitry Andric     return TE->Kind == TEK_None;
93406d4ba38SDimitry Andric   }
93506d4ba38SDimitry Andric };
93606d4ba38SDimitry Andric }  // namespace
93706d4ba38SDimitry Andric 
93806d4ba38SDimitry Andric static std::unique_ptr<TypeExpansion>
getTypeExpansion(QualType Ty,const ASTContext & Context)93906d4ba38SDimitry Andric getTypeExpansion(QualType Ty, const ASTContext &Context) {
94006d4ba38SDimitry Andric   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
941ac9a064cSDimitry Andric     return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
942ac9a064cSDimitry Andric                                                     AT->getZExtSize());
94306d4ba38SDimitry Andric   }
94406d4ba38SDimitry Andric   if (const RecordType *RT = Ty->getAs<RecordType>()) {
94506d4ba38SDimitry Andric     SmallVector<const CXXBaseSpecifier *, 1> Bases;
94606d4ba38SDimitry Andric     SmallVector<const FieldDecl *, 1> Fields;
947ec2b103cSEd Schouten     const RecordDecl *RD = RT->getDecl();
948ec2b103cSEd Schouten     assert(!RD->hasFlexibleArrayMember() &&
949ec2b103cSEd Schouten            "Cannot expand structure with flexible array.");
9506b9a6e39SDimitry Andric     if (RD->isUnion()) {
9516b9a6e39SDimitry Andric       // Unions can be here only in degenerative cases - all the fields are same
9526b9a6e39SDimitry Andric       // after flattening. Thus we have to use the "largest" field.
9539f4dbff6SDimitry Andric       const FieldDecl *LargestFD = nullptr;
9546b9a6e39SDimitry Andric       CharUnits UnionSize = CharUnits::Zero();
9556b9a6e39SDimitry Andric 
9569f4dbff6SDimitry Andric       for (const auto *FD : RD->fields()) {
95748675466SDimitry Andric         if (FD->isZeroLengthBitField(Context))
95806d4ba38SDimitry Andric           continue;
9596b9a6e39SDimitry Andric         assert(!FD->isBitField() &&
9606b9a6e39SDimitry Andric                "Cannot expand structure with bit-field members.");
96106d4ba38SDimitry Andric         CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType());
9626b9a6e39SDimitry Andric         if (UnionSize < FieldSize) {
9636b9a6e39SDimitry Andric           UnionSize = FieldSize;
9646b9a6e39SDimitry Andric           LargestFD = FD;
9656b9a6e39SDimitry Andric         }
9666b9a6e39SDimitry Andric       }
9676b9a6e39SDimitry Andric       if (LargestFD)
96806d4ba38SDimitry Andric         Fields.push_back(LargestFD);
9696b9a6e39SDimitry Andric     } else {
97006d4ba38SDimitry Andric       if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
97106d4ba38SDimitry Andric         assert(!CXXRD->isDynamicClass() &&
97206d4ba38SDimitry Andric                "cannot expand vtable pointers in dynamic classes");
973145449b1SDimitry Andric         llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
974ec2b103cSEd Schouten       }
975ec2b103cSEd Schouten 
97606d4ba38SDimitry Andric       for (const auto *FD : RD->fields()) {
97748675466SDimitry Andric         if (FD->isZeroLengthBitField(Context))
97806d4ba38SDimitry Andric           continue;
97906d4ba38SDimitry Andric         assert(!FD->isBitField() &&
98006d4ba38SDimitry Andric                "Cannot expand structure with bit-field members.");
98106d4ba38SDimitry Andric         Fields.push_back(FD);
98206d4ba38SDimitry Andric       }
98306d4ba38SDimitry Andric     }
984519fc96cSDimitry Andric     return std::make_unique<RecordExpansion>(std::move(Bases),
98506d4ba38SDimitry Andric                                               std::move(Fields));
98606d4ba38SDimitry Andric   }
98706d4ba38SDimitry Andric   if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
988519fc96cSDimitry Andric     return std::make_unique<ComplexExpansion>(CT->getElementType());
98906d4ba38SDimitry Andric   }
990519fc96cSDimitry Andric   return std::make_unique<NoExpansion>();
99106d4ba38SDimitry Andric }
99206d4ba38SDimitry Andric 
getExpansionSize(QualType Ty,const ASTContext & Context)99306d4ba38SDimitry Andric static int getExpansionSize(QualType Ty, const ASTContext &Context) {
99406d4ba38SDimitry Andric   auto Exp = getTypeExpansion(Ty, Context);
99506d4ba38SDimitry Andric   if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
99606d4ba38SDimitry Andric     return CAExp->NumElts * getExpansionSize(CAExp->EltTy, Context);
99706d4ba38SDimitry Andric   }
99806d4ba38SDimitry Andric   if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
99906d4ba38SDimitry Andric     int Res = 0;
100006d4ba38SDimitry Andric     for (auto BS : RExp->Bases)
100106d4ba38SDimitry Andric       Res += getExpansionSize(BS->getType(), Context);
100206d4ba38SDimitry Andric     for (auto FD : RExp->Fields)
100306d4ba38SDimitry Andric       Res += getExpansionSize(FD->getType(), Context);
100406d4ba38SDimitry Andric     return Res;
100506d4ba38SDimitry Andric   }
100606d4ba38SDimitry Andric   if (isa<ComplexExpansion>(Exp.get()))
100706d4ba38SDimitry Andric     return 2;
100806d4ba38SDimitry Andric   assert(isa<NoExpansion>(Exp.get()));
100906d4ba38SDimitry Andric   return 1;
101006d4ba38SDimitry Andric }
101106d4ba38SDimitry Andric 
101206d4ba38SDimitry Andric void
getExpandedTypes(QualType Ty,SmallVectorImpl<llvm::Type * >::iterator & TI)101306d4ba38SDimitry Andric CodeGenTypes::getExpandedTypes(QualType Ty,
101406d4ba38SDimitry Andric                                SmallVectorImpl<llvm::Type *>::iterator &TI) {
101506d4ba38SDimitry Andric   auto Exp = getTypeExpansion(Ty, Context);
101606d4ba38SDimitry Andric   if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
101706d4ba38SDimitry Andric     for (int i = 0, n = CAExp->NumElts; i < n; i++) {
101806d4ba38SDimitry Andric       getExpandedTypes(CAExp->EltTy, TI);
101906d4ba38SDimitry Andric     }
102006d4ba38SDimitry Andric   } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
102106d4ba38SDimitry Andric     for (auto BS : RExp->Bases)
102206d4ba38SDimitry Andric       getExpandedTypes(BS->getType(), TI);
102306d4ba38SDimitry Andric     for (auto FD : RExp->Fields)
102406d4ba38SDimitry Andric       getExpandedTypes(FD->getType(), TI);
102506d4ba38SDimitry Andric   } else if (auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
102606d4ba38SDimitry Andric     llvm::Type *EltTy = ConvertType(CExp->EltTy);
102706d4ba38SDimitry Andric     *TI++ = EltTy;
102806d4ba38SDimitry Andric     *TI++ = EltTy;
102906d4ba38SDimitry Andric   } else {
103006d4ba38SDimitry Andric     assert(isa<NoExpansion>(Exp.get()));
103106d4ba38SDimitry Andric     *TI++ = ConvertType(Ty);
103206d4ba38SDimitry Andric   }
103306d4ba38SDimitry Andric }
103406d4ba38SDimitry Andric 
forConstantArrayExpansion(CodeGenFunction & CGF,ConstantArrayExpansion * CAE,Address BaseAddr,llvm::function_ref<void (Address)> Fn)103545b53394SDimitry Andric static void forConstantArrayExpansion(CodeGenFunction &CGF,
103645b53394SDimitry Andric                                       ConstantArrayExpansion *CAE,
103745b53394SDimitry Andric                                       Address BaseAddr,
103845b53394SDimitry Andric                                       llvm::function_ref<void(Address)> Fn) {
103945b53394SDimitry Andric   for (int i = 0, n = CAE->NumElts; i < n; i++) {
1040ac9a064cSDimitry Andric     Address EltAddr = CGF.Builder.CreateConstGEP2_32(BaseAddr, 0, i);
1041ac9a064cSDimitry Andric     Fn(EltAddr);
104245b53394SDimitry Andric   }
104345b53394SDimitry Andric }
104445b53394SDimitry Andric 
ExpandTypeFromArgs(QualType Ty,LValue LV,llvm::Function::arg_iterator & AI)1045cfca06d7SDimitry Andric void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
1046cfca06d7SDimitry Andric                                          llvm::Function::arg_iterator &AI) {
1047ec2b103cSEd Schouten   assert(LV.isSimple() &&
1048ec2b103cSEd Schouten          "Unexpected non-simple lvalue during struct expansion.");
104936981b17SDimitry Andric 
105006d4ba38SDimitry Andric   auto Exp = getTypeExpansion(Ty, getContext());
105106d4ba38SDimitry Andric   if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1052706b4fc4SDimitry Andric     forConstantArrayExpansion(
1053ac9a064cSDimitry Andric         *this, CAExp, LV.getAddress(), [&](Address EltAddr) {
105406d4ba38SDimitry Andric           LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
105506d4ba38SDimitry Andric           ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
105645b53394SDimitry Andric         });
105706d4ba38SDimitry Andric   } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1058ac9a064cSDimitry Andric     Address This = LV.getAddress();
105906d4ba38SDimitry Andric     for (const CXXBaseSpecifier *BS : RExp->Bases) {
106006d4ba38SDimitry Andric       // Perform a single step derived-to-base conversion.
106145b53394SDimitry Andric       Address Base =
106206d4ba38SDimitry Andric           GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1,
106306d4ba38SDimitry Andric                                 /*NullCheckValue=*/false, SourceLocation());
106406d4ba38SDimitry Andric       LValue SubLV = MakeAddrLValue(Base, BS->getType());
10656b9a6e39SDimitry Andric 
106606d4ba38SDimitry Andric       // Recurse onto bases.
106706d4ba38SDimitry Andric       ExpandTypeFromArgs(BS->getType(), SubLV, AI);
10686b9a6e39SDimitry Andric     }
106906d4ba38SDimitry Andric     for (auto FD : RExp->Fields) {
1070ec2b103cSEd Schouten       // FIXME: What are the right qualifiers here?
10712b6b257fSDimitry Andric       LValue SubLV = EmitLValueForFieldInitialization(LV, FD);
107206d4ba38SDimitry Andric       ExpandTypeFromArgs(FD->getType(), SubLV, AI);
10736b9a6e39SDimitry Andric     }
107445b53394SDimitry Andric   } else if (isa<ComplexExpansion>(Exp.get())) {
1075cfca06d7SDimitry Andric     auto realValue = &*AI++;
1076cfca06d7SDimitry Andric     auto imagValue = &*AI++;
107745b53394SDimitry Andric     EmitStoreOfComplex(ComplexPairTy(realValue, imagValue), LV, /*init*/ true);
1078ec2b103cSEd Schouten   } else {
1079706b4fc4SDimitry Andric     // Call EmitStoreOfScalar except when the lvalue is a bitfield to emit a
1080706b4fc4SDimitry Andric     // primitive store.
108106d4ba38SDimitry Andric     assert(isa<NoExpansion>(Exp.get()));
1082145449b1SDimitry Andric     llvm::Value *Arg = &*AI++;
1083145449b1SDimitry Andric     if (LV.isBitField()) {
1084145449b1SDimitry Andric       EmitStoreThroughLValue(RValue::get(Arg), LV);
1085145449b1SDimitry Andric     } else {
1086145449b1SDimitry Andric       // TODO: currently there are some places are inconsistent in what LLVM
1087145449b1SDimitry Andric       // pointer type they use (see D118744). Once clang uses opaque pointers
1088145449b1SDimitry Andric       // all LLVM pointer types will be the same and we can remove this check.
1089145449b1SDimitry Andric       if (Arg->getType()->isPointerTy()) {
1090ac9a064cSDimitry Andric         Address Addr = LV.getAddress();
1091145449b1SDimitry Andric         Arg = Builder.CreateBitCast(Arg, Addr.getElementType());
1092145449b1SDimitry Andric       }
1093145449b1SDimitry Andric       EmitStoreOfScalar(Arg, LV);
1094145449b1SDimitry Andric     }
109506d4ba38SDimitry Andric   }
1096ec2b103cSEd Schouten }
1097ec2b103cSEd Schouten 
ExpandTypeToArgs(QualType Ty,CallArg Arg,llvm::FunctionType * IRFuncTy,SmallVectorImpl<llvm::Value * > & IRCallArgs,unsigned & IRCallArgPos)109806d4ba38SDimitry Andric void CodeGenFunction::ExpandTypeToArgs(
109948675466SDimitry Andric     QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
110006d4ba38SDimitry Andric     SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos) {
110106d4ba38SDimitry Andric   auto Exp = getTypeExpansion(Ty, getContext());
110206d4ba38SDimitry Andric   if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1103ac9a064cSDimitry Andric     Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().getAddress()
110448675466SDimitry Andric                                    : Arg.getKnownRValue().getAggregateAddress();
110548675466SDimitry Andric     forConstantArrayExpansion(
110648675466SDimitry Andric         *this, CAExp, Addr, [&](Address EltAddr) {
110748675466SDimitry Andric           CallArg EltArg = CallArg(
110848675466SDimitry Andric               convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
110948675466SDimitry Andric               CAExp->EltTy);
111048675466SDimitry Andric           ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
111148675466SDimitry Andric                            IRCallArgPos);
111245b53394SDimitry Andric         });
111306d4ba38SDimitry Andric   } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
1114ac9a064cSDimitry Andric     Address This = Arg.hasLValue() ? Arg.getKnownLValue().getAddress()
111548675466SDimitry Andric                                    : Arg.getKnownRValue().getAggregateAddress();
111606d4ba38SDimitry Andric     for (const CXXBaseSpecifier *BS : RExp->Bases) {
111706d4ba38SDimitry Andric       // Perform a single step derived-to-base conversion.
111845b53394SDimitry Andric       Address Base =
111906d4ba38SDimitry Andric           GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1,
112006d4ba38SDimitry Andric                                 /*NullCheckValue=*/false, SourceLocation());
112148675466SDimitry Andric       CallArg BaseArg = CallArg(RValue::getAggregate(Base), BS->getType());
112206d4ba38SDimitry Andric 
112306d4ba38SDimitry Andric       // Recurse onto bases.
112448675466SDimitry Andric       ExpandTypeToArgs(BS->getType(), BaseArg, IRFuncTy, IRCallArgs,
112506d4ba38SDimitry Andric                        IRCallArgPos);
112606d4ba38SDimitry Andric     }
112706d4ba38SDimitry Andric 
112806d4ba38SDimitry Andric     LValue LV = MakeAddrLValue(This, Ty);
112906d4ba38SDimitry Andric     for (auto FD : RExp->Fields) {
113048675466SDimitry Andric       CallArg FldArg =
113148675466SDimitry Andric           CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
113248675466SDimitry Andric       ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
113306d4ba38SDimitry Andric                        IRCallArgPos);
113406d4ba38SDimitry Andric     }
113506d4ba38SDimitry Andric   } else if (isa<ComplexExpansion>(Exp.get())) {
113648675466SDimitry Andric     ComplexPairTy CV = Arg.getKnownRValue().getComplexVal();
113706d4ba38SDimitry Andric     IRCallArgs[IRCallArgPos++] = CV.first;
113806d4ba38SDimitry Andric     IRCallArgs[IRCallArgPos++] = CV.second;
113906d4ba38SDimitry Andric   } else {
114006d4ba38SDimitry Andric     assert(isa<NoExpansion>(Exp.get()));
114148675466SDimitry Andric     auto RV = Arg.getKnownRValue();
114206d4ba38SDimitry Andric     assert(RV.isScalar() &&
114306d4ba38SDimitry Andric            "Unexpected non-scalar rvalue during struct expansion.");
114406d4ba38SDimitry Andric 
114506d4ba38SDimitry Andric     // Insert a bitcast as needed.
114606d4ba38SDimitry Andric     llvm::Value *V = RV.getScalarVal();
114706d4ba38SDimitry Andric     if (IRCallArgPos < IRFuncTy->getNumParams() &&
114806d4ba38SDimitry Andric         V->getType() != IRFuncTy->getParamType(IRCallArgPos))
114906d4ba38SDimitry Andric       V = Builder.CreateBitCast(V, IRFuncTy->getParamType(IRCallArgPos));
115006d4ba38SDimitry Andric 
115106d4ba38SDimitry Andric     IRCallArgs[IRCallArgPos++] = V;
115206d4ba38SDimitry Andric   }
1153ec2b103cSEd Schouten }
1154ec2b103cSEd Schouten 
115545b53394SDimitry Andric /// Create a temporary allocation for the purposes of coercion.
CreateTempAllocaForCoercion(CodeGenFunction & CGF,llvm::Type * Ty,CharUnits MinAlign,const Twine & Name="tmp")1156ac9a064cSDimitry Andric static RawAddress CreateTempAllocaForCoercion(CodeGenFunction &CGF,
1157ac9a064cSDimitry Andric                                               llvm::Type *Ty,
1158b60736ecSDimitry Andric                                               CharUnits MinAlign,
1159b60736ecSDimitry Andric                                               const Twine &Name = "tmp") {
116045b53394SDimitry Andric   // Don't use an alignment that's worse than what LLVM would prefer.
1161e3b55780SDimitry Andric   auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlign(Ty);
116245b53394SDimitry Andric   CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign));
116345b53394SDimitry Andric 
1164b60736ecSDimitry Andric   return CGF.CreateTempAlloca(Ty, Align, Name + ".coerce");
116545b53394SDimitry Andric }
116645b53394SDimitry Andric 
11674ba67500SRoman Divacky /// EnterStructPointerForCoercedAccess - Given a struct pointer that we are
11684ba67500SRoman Divacky /// accessing some number of bytes out of it, try to gep into the struct to get
11694ba67500SRoman Divacky /// at its inner goodness.  Dive as deep as possible without entering an element
11704ba67500SRoman Divacky /// with an in-memory size smaller than DstSize.
117145b53394SDimitry Andric static Address
EnterStructPointerForCoercedAccess(Address SrcPtr,llvm::StructType * SrcSTy,uint64_t DstSize,CodeGenFunction & CGF)117245b53394SDimitry Andric EnterStructPointerForCoercedAccess(Address SrcPtr,
117336981b17SDimitry Andric                                    llvm::StructType *SrcSTy,
11744ba67500SRoman Divacky                                    uint64_t DstSize, CodeGenFunction &CGF) {
11754ba67500SRoman Divacky   // We can't dive into a zero-element struct.
11764ba67500SRoman Divacky   if (SrcSTy->getNumElements() == 0) return SrcPtr;
11774ba67500SRoman Divacky 
117836981b17SDimitry Andric   llvm::Type *FirstElt = SrcSTy->getElementType(0);
11794ba67500SRoman Divacky 
11804ba67500SRoman Divacky   // If the first elt is at least as large as what we're looking for, or if the
118106d4ba38SDimitry Andric   // first element is the same size as the whole struct, we can enter it. The
118206d4ba38SDimitry Andric   // comparison must be made on the store size and not the alloca size. Using
118306d4ba38SDimitry Andric   // the alloca size may overstate the size of the load.
11844ba67500SRoman Divacky   uint64_t FirstEltSize =
118506d4ba38SDimitry Andric     CGF.CGM.getDataLayout().getTypeStoreSize(FirstElt);
11864ba67500SRoman Divacky   if (FirstEltSize < DstSize &&
118706d4ba38SDimitry Andric       FirstEltSize < CGF.CGM.getDataLayout().getTypeStoreSize(SrcSTy))
11884ba67500SRoman Divacky     return SrcPtr;
11894ba67500SRoman Divacky 
11904ba67500SRoman Divacky   // GEP into the first element.
119122989816SDimitry Andric   SrcPtr = CGF.Builder.CreateStructGEP(SrcPtr, 0, "coerce.dive");
11924ba67500SRoman Divacky 
11934ba67500SRoman Divacky   // If the first element is a struct, recurse.
119445b53394SDimitry Andric   llvm::Type *SrcTy = SrcPtr.getElementType();
119536981b17SDimitry Andric   if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
11964ba67500SRoman Divacky     return EnterStructPointerForCoercedAccess(SrcPtr, SrcSTy, DstSize, CGF);
11974ba67500SRoman Divacky 
11984ba67500SRoman Divacky   return SrcPtr;
11994ba67500SRoman Divacky }
12004ba67500SRoman Divacky 
12014ba67500SRoman Divacky /// CoerceIntOrPtrToIntOrPtr - Convert a value Val to the specific Ty where both
12024ba67500SRoman Divacky /// are either integers or pointers.  This does a truncation of the value if it
12034ba67500SRoman Divacky /// is too large or a zero extension if it is too small.
1204bfef3995SDimitry Andric ///
1205bfef3995SDimitry Andric /// This behaves as if the value were coerced through memory, so on big-endian
1206bfef3995SDimitry Andric /// targets the high bits are preserved in a truncation, while little-endian
1207bfef3995SDimitry Andric /// targets preserve the low bits.
CoerceIntOrPtrToIntOrPtr(llvm::Value * Val,llvm::Type * Ty,CodeGenFunction & CGF)12084ba67500SRoman Divacky static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val,
120936981b17SDimitry Andric                                              llvm::Type *Ty,
12104ba67500SRoman Divacky                                              CodeGenFunction &CGF) {
12114ba67500SRoman Divacky   if (Val->getType() == Ty)
12124ba67500SRoman Divacky     return Val;
12134ba67500SRoman Divacky 
12144ba67500SRoman Divacky   if (isa<llvm::PointerType>(Val->getType())) {
12154ba67500SRoman Divacky     // If this is Pointer->Pointer avoid conversion to and from int.
12164ba67500SRoman Divacky     if (isa<llvm::PointerType>(Ty))
12174ba67500SRoman Divacky       return CGF.Builder.CreateBitCast(Val, Ty, "coerce.val");
12184ba67500SRoman Divacky 
12194ba67500SRoman Divacky     // Convert the pointer to an integer so we can play with its width.
12204ba67500SRoman Divacky     Val = CGF.Builder.CreatePtrToInt(Val, CGF.IntPtrTy, "coerce.val.pi");
12214ba67500SRoman Divacky   }
12224ba67500SRoman Divacky 
122336981b17SDimitry Andric   llvm::Type *DestIntTy = Ty;
12244ba67500SRoman Divacky   if (isa<llvm::PointerType>(DestIntTy))
12254ba67500SRoman Divacky     DestIntTy = CGF.IntPtrTy;
12264ba67500SRoman Divacky 
1227bfef3995SDimitry Andric   if (Val->getType() != DestIntTy) {
1228bfef3995SDimitry Andric     const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
1229bfef3995SDimitry Andric     if (DL.isBigEndian()) {
1230bfef3995SDimitry Andric       // Preserve the high bits on big-endian targets.
1231bfef3995SDimitry Andric       // That is what memory coercion does.
12329f4dbff6SDimitry Andric       uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
12339f4dbff6SDimitry Andric       uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
12349f4dbff6SDimitry Andric 
1235bfef3995SDimitry Andric       if (SrcSize > DstSize) {
1236bfef3995SDimitry Andric         Val = CGF.Builder.CreateLShr(Val, SrcSize - DstSize, "coerce.highbits");
1237bfef3995SDimitry Andric         Val = CGF.Builder.CreateTrunc(Val, DestIntTy, "coerce.val.ii");
1238bfef3995SDimitry Andric       } else {
1239bfef3995SDimitry Andric         Val = CGF.Builder.CreateZExt(Val, DestIntTy, "coerce.val.ii");
1240bfef3995SDimitry Andric         Val = CGF.Builder.CreateShl(Val, DstSize - SrcSize, "coerce.highbits");
1241bfef3995SDimitry Andric       }
1242bfef3995SDimitry Andric     } else {
1243bfef3995SDimitry Andric       // Little-endian targets preserve the low bits. No shifts required.
12444ba67500SRoman Divacky       Val = CGF.Builder.CreateIntCast(Val, DestIntTy, false, "coerce.val.ii");
1245bfef3995SDimitry Andric     }
1246bfef3995SDimitry Andric   }
12474ba67500SRoman Divacky 
12484ba67500SRoman Divacky   if (isa<llvm::PointerType>(Ty))
12494ba67500SRoman Divacky     Val = CGF.Builder.CreateIntToPtr(Val, Ty, "coerce.val.ip");
12504ba67500SRoman Divacky   return Val;
12514ba67500SRoman Divacky }
12524ba67500SRoman Divacky 
12534ba67500SRoman Divacky 
12544ba67500SRoman Divacky 
1255ec2b103cSEd Schouten /// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
125651ece4aaSDimitry Andric /// a pointer to an object of type \arg Ty, known to be aligned to
125751ece4aaSDimitry Andric /// \arg SrcAlign bytes.
1258ec2b103cSEd Schouten ///
1259ec2b103cSEd Schouten /// This safely handles the case when the src type is smaller than the
1260ec2b103cSEd Schouten /// destination type; in this situation the values of bits which not
1261ec2b103cSEd Schouten /// present in the src are undefined.
CreateCoercedLoad(Address Src,llvm::Type * Ty,CodeGenFunction & CGF)126245b53394SDimitry Andric static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
1263ec2b103cSEd Schouten                                       CodeGenFunction &CGF) {
126445b53394SDimitry Andric   llvm::Type *SrcTy = Src.getElementType();
12654ba67500SRoman Divacky 
12664ba67500SRoman Divacky   // If SrcTy and Ty are the same, just do a load.
12674ba67500SRoman Divacky   if (SrcTy == Ty)
126845b53394SDimitry Andric     return CGF.Builder.CreateLoad(Src);
12694ba67500SRoman Divacky 
1270b60736ecSDimitry Andric   llvm::TypeSize DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty);
1271ec2b103cSEd Schouten 
127236981b17SDimitry Andric   if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1273b60736ecSDimitry Andric     Src = EnterStructPointerForCoercedAccess(Src, SrcSTy,
1274e3b55780SDimitry Andric                                              DstSize.getFixedValue(), CGF);
1275cfca06d7SDimitry Andric     SrcTy = Src.getElementType();
12764ba67500SRoman Divacky   }
12774ba67500SRoman Divacky 
1278b60736ecSDimitry Andric   llvm::TypeSize SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy);
12794ba67500SRoman Divacky 
12804ba67500SRoman Divacky   // If the source and destination are integer or pointer types, just do an
12814ba67500SRoman Divacky   // extension or truncation to the desired type.
12824ba67500SRoman Divacky   if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
12834ba67500SRoman Divacky       (isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
128445b53394SDimitry Andric     llvm::Value *Load = CGF.Builder.CreateLoad(Src);
12854ba67500SRoman Divacky     return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF);
12864ba67500SRoman Divacky   }
12874ba67500SRoman Divacky 
1288ec2b103cSEd Schouten   // If load is legal, just bitcast the src pointer.
1289b60736ecSDimitry Andric   if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1290e3b55780SDimitry Andric       SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
1291ec2b103cSEd Schouten     // Generally SrcSize is never greater than DstSize, since this means we are
1292ec2b103cSEd Schouten     // losing bits. However, this can happen in cases where the structure has
1293ec2b103cSEd Schouten     // additional padding, for example due to a user specified alignment.
1294ec2b103cSEd Schouten     //
1295ec2b103cSEd Schouten     // FIXME: Assert that we aren't truncating non-padding bits when have access
1296ec2b103cSEd Schouten     // to that information.
12977fa27ce4SDimitry Andric     Src = Src.withElementType(Ty);
129845b53394SDimitry Andric     return CGF.Builder.CreateLoad(Src);
12994ba67500SRoman Divacky   }
13004ba67500SRoman Divacky 
1301b60736ecSDimitry Andric   // If coercing a fixed vector to a scalable vector for ABI compatibility, and
1302145449b1SDimitry Andric   // the types match, use the llvm.vector.insert intrinsic to perform the
1303145449b1SDimitry Andric   // conversion.
1304ac9a064cSDimitry Andric   if (auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
1305ac9a064cSDimitry Andric     if (auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
1306ac9a064cSDimitry Andric       // If we are casting a fixed i8 vector to a scalable i1 predicate
1307c0981da4SDimitry Andric       // vector, use a vector insert and bitcast the result.
1308ac9a064cSDimitry Andric       if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
1309ac9a064cSDimitry Andric           ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
1310ac9a064cSDimitry Andric           FixedSrcTy->getElementType()->isIntegerTy(8)) {
1311ac9a064cSDimitry Andric         ScalableDstTy = llvm::ScalableVectorType::get(
1312ac9a064cSDimitry Andric             FixedSrcTy->getElementType(),
1313ac9a064cSDimitry Andric             ScalableDstTy->getElementCount().getKnownMinValue() / 8);
1314c0981da4SDimitry Andric       }
1315ac9a064cSDimitry Andric       if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1316b60736ecSDimitry Andric         auto *Load = CGF.Builder.CreateLoad(Src);
1317ac9a064cSDimitry Andric         auto *UndefVec = llvm::UndefValue::get(ScalableDstTy);
1318b60736ecSDimitry Andric         auto *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
1319c0981da4SDimitry Andric         llvm::Value *Result = CGF.Builder.CreateInsertVector(
1320ac9a064cSDimitry Andric             ScalableDstTy, UndefVec, Load, Zero, "cast.scalable");
1321ac9a064cSDimitry Andric         if (ScalableDstTy != Ty)
1322ac9a064cSDimitry Andric           Result = CGF.Builder.CreateBitCast(Result, Ty);
1323c0981da4SDimitry Andric         return Result;
1324b60736ecSDimitry Andric       }
1325b60736ecSDimitry Andric     }
1326b60736ecSDimitry Andric   }
1327b60736ecSDimitry Andric 
132845b53394SDimitry Andric   // Otherwise do coercion through memory. This is stupid, but simple.
1329ac9a064cSDimitry Andric   RawAddress Tmp =
1330b60736ecSDimitry Andric       CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment(), Src.getName());
1331b60736ecSDimitry Andric   CGF.Builder.CreateMemCpy(
1332ac9a064cSDimitry Andric       Tmp.getPointer(), Tmp.getAlignment().getAsAlign(),
1333ac9a064cSDimitry Andric       Src.emitRawPointer(CGF), Src.getAlignment().getAsAlign(),
1334e3b55780SDimitry Andric       llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinValue()));
133545b53394SDimitry Andric   return CGF.Builder.CreateLoad(Tmp);
1336ec2b103cSEd Schouten }
1337ec2b103cSEd Schouten 
CreateCoercedStore(llvm::Value * Src,Address Dst,llvm::TypeSize DstSize,bool DstIsVolatile)13381de139fdSDimitry Andric void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
13391de139fdSDimitry Andric                                          llvm::TypeSize DstSize,
13401de139fdSDimitry Andric                                          bool DstIsVolatile) {
13411de139fdSDimitry Andric   if (!DstSize)
13421de139fdSDimitry Andric     return;
13431de139fdSDimitry Andric 
13441de139fdSDimitry Andric   llvm::Type *SrcTy = Src->getType();
13451de139fdSDimitry Andric   llvm::TypeSize SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
13461de139fdSDimitry Andric 
13471de139fdSDimitry Andric   // GEP into structs to try to make types match.
13481de139fdSDimitry Andric   // FIXME: This isn't really that useful with opaque types, but it impacts a
13491de139fdSDimitry Andric   // lot of regression tests.
13501de139fdSDimitry Andric   if (SrcTy != Dst.getElementType()) {
13511de139fdSDimitry Andric     if (llvm::StructType *DstSTy =
13521de139fdSDimitry Andric             dyn_cast<llvm::StructType>(Dst.getElementType())) {
13531de139fdSDimitry Andric       assert(!SrcSize.isScalable());
13541de139fdSDimitry Andric       Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy,
13551de139fdSDimitry Andric                                                SrcSize.getFixedValue(), *this);
13561de139fdSDimitry Andric     }
13571de139fdSDimitry Andric   }
13581de139fdSDimitry Andric 
13591de139fdSDimitry Andric   if (SrcSize.isScalable() || SrcSize <= DstSize) {
13601de139fdSDimitry Andric     if (SrcTy->isIntegerTy() && Dst.getElementType()->isPointerTy() &&
13611de139fdSDimitry Andric         SrcSize == CGM.getDataLayout().getTypeAllocSize(Dst.getElementType())) {
13621de139fdSDimitry Andric       // If the value is supposed to be a pointer, convert it before storing it.
13631de139fdSDimitry Andric       Src = CoerceIntOrPtrToIntOrPtr(Src, Dst.getElementType(), *this);
13641de139fdSDimitry Andric       Builder.CreateStore(Src, Dst, DstIsVolatile);
13651de139fdSDimitry Andric     } else if (llvm::StructType *STy =
13661de139fdSDimitry Andric                    dyn_cast<llvm::StructType>(Src->getType())) {
136729cafa66SDimitry Andric       // Prefer scalar stores to first-class aggregate stores.
13681de139fdSDimitry Andric       Dst = Dst.withElementType(SrcTy);
136929cafa66SDimitry Andric       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
13701de139fdSDimitry Andric         Address EltPtr = Builder.CreateStructGEP(Dst, i);
13711de139fdSDimitry Andric         llvm::Value *Elt = Builder.CreateExtractValue(Src, i);
13721de139fdSDimitry Andric         Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
137329cafa66SDimitry Andric       }
137429cafa66SDimitry Andric     } else {
13751de139fdSDimitry Andric       Builder.CreateStore(Src, Dst.withElementType(SrcTy), DstIsVolatile);
137629cafa66SDimitry Andric     }
13771de139fdSDimitry Andric   } else if (SrcTy->isIntegerTy()) {
13781de139fdSDimitry Andric     // If the source is a simple integer, coerce it directly.
13791de139fdSDimitry Andric     llvm::Type *DstIntTy = Builder.getIntNTy(DstSize.getFixedValue() * 8);
13801de139fdSDimitry Andric     Src = CoerceIntOrPtrToIntOrPtr(Src, DstIntTy, *this);
13811de139fdSDimitry Andric     Builder.CreateStore(Src, Dst.withElementType(DstIntTy), DstIsVolatile);
1382ec2b103cSEd Schouten   } else {
1383ec2b103cSEd Schouten     // Otherwise do coercion through memory. This is stupid, but
1384ec2b103cSEd Schouten     // simple.
138537f6c480SEd Schouten 
138637f6c480SEd Schouten     // Generally SrcSize is never greater than DstSize, since this means we are
138737f6c480SEd Schouten     // losing bits. However, this can happen in cases where the structure has
138837f6c480SEd Schouten     // additional padding, for example due to a user specified alignment.
138937f6c480SEd Schouten     //
139037f6c480SEd Schouten     // FIXME: Assert that we aren't truncating non-padding bits when have access
139137f6c480SEd Schouten     // to that information.
1392ac9a064cSDimitry Andric     RawAddress Tmp =
13931de139fdSDimitry Andric         CreateTempAllocaForCoercion(*this, SrcTy, Dst.getAlignment());
13941de139fdSDimitry Andric     Builder.CreateStore(Src, Tmp);
13951de139fdSDimitry Andric     Builder.CreateMemCpy(Dst.emitRawPointer(*this),
13961de139fdSDimitry Andric                          Dst.getAlignment().getAsAlign(), Tmp.getPointer(),
13971de139fdSDimitry Andric                          Tmp.getAlignment().getAsAlign(),
13981de139fdSDimitry Andric                          Builder.CreateTypeSize(IntPtrTy, DstSize));
1399ec2b103cSEd Schouten   }
1400ec2b103cSEd Schouten }
1401ec2b103cSEd Schouten 
emitAddressAtOffset(CodeGenFunction & CGF,Address addr,const ABIArgInfo & info)140245b53394SDimitry Andric static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr,
140345b53394SDimitry Andric                                    const ABIArgInfo &info) {
140445b53394SDimitry Andric   if (unsigned offset = info.getDirectOffset()) {
14057fa27ce4SDimitry Andric     addr = addr.withElementType(CGF.Int8Ty);
140645b53394SDimitry Andric     addr = CGF.Builder.CreateConstInBoundsByteGEP(addr,
140745b53394SDimitry Andric                                              CharUnits::fromQuantity(offset));
14087fa27ce4SDimitry Andric     addr = addr.withElementType(info.getCoerceToType());
140945b53394SDimitry Andric   }
141045b53394SDimitry Andric   return addr;
141145b53394SDimitry Andric }
141245b53394SDimitry Andric 
141306d4ba38SDimitry Andric namespace {
141406d4ba38SDimitry Andric 
141506d4ba38SDimitry Andric /// Encapsulates information about the way function arguments from
141606d4ba38SDimitry Andric /// CGFunctionInfo should be passed to actual LLVM IR function.
141706d4ba38SDimitry Andric class ClangToLLVMArgMapping {
141806d4ba38SDimitry Andric   static const unsigned InvalidIndex = ~0U;
141906d4ba38SDimitry Andric   unsigned InallocaArgNo;
142006d4ba38SDimitry Andric   unsigned SRetArgNo;
142106d4ba38SDimitry Andric   unsigned TotalIRArgs;
142206d4ba38SDimitry Andric 
142306d4ba38SDimitry Andric   /// Arguments of LLVM IR function corresponding to single Clang argument.
142406d4ba38SDimitry Andric   struct IRArgs {
142506d4ba38SDimitry Andric     unsigned PaddingArgIndex;
142606d4ba38SDimitry Andric     // Argument is expanded to IR arguments at positions
142706d4ba38SDimitry Andric     // [FirstArgIndex, FirstArgIndex + NumberOfArgs).
142806d4ba38SDimitry Andric     unsigned FirstArgIndex;
142906d4ba38SDimitry Andric     unsigned NumberOfArgs;
143006d4ba38SDimitry Andric 
IRArgs__anon748148590511::ClangToLLVMArgMapping::IRArgs143106d4ba38SDimitry Andric     IRArgs()
143206d4ba38SDimitry Andric         : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
143306d4ba38SDimitry Andric           NumberOfArgs(0) {}
143406d4ba38SDimitry Andric   };
143506d4ba38SDimitry Andric 
143606d4ba38SDimitry Andric   SmallVector<IRArgs, 8> ArgInfo;
143706d4ba38SDimitry Andric 
143806d4ba38SDimitry Andric public:
ClangToLLVMArgMapping(const ASTContext & Context,const CGFunctionInfo & FI,bool OnlyRequiredArgs=false)143906d4ba38SDimitry Andric   ClangToLLVMArgMapping(const ASTContext &Context, const CGFunctionInfo &FI,
144006d4ba38SDimitry Andric                         bool OnlyRequiredArgs = false)
144106d4ba38SDimitry Andric       : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
144206d4ba38SDimitry Andric         ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
144306d4ba38SDimitry Andric     construct(Context, FI, OnlyRequiredArgs);
144406d4ba38SDimitry Andric   }
144506d4ba38SDimitry Andric 
hasInallocaArg() const144606d4ba38SDimitry Andric   bool hasInallocaArg() const { return InallocaArgNo != InvalidIndex; }
getInallocaArgNo() const144706d4ba38SDimitry Andric   unsigned getInallocaArgNo() const {
144806d4ba38SDimitry Andric     assert(hasInallocaArg());
144906d4ba38SDimitry Andric     return InallocaArgNo;
145006d4ba38SDimitry Andric   }
145106d4ba38SDimitry Andric 
hasSRetArg() const145206d4ba38SDimitry Andric   bool hasSRetArg() const { return SRetArgNo != InvalidIndex; }
getSRetArgNo() const145306d4ba38SDimitry Andric   unsigned getSRetArgNo() const {
145406d4ba38SDimitry Andric     assert(hasSRetArg());
145506d4ba38SDimitry Andric     return SRetArgNo;
145606d4ba38SDimitry Andric   }
145706d4ba38SDimitry Andric 
totalIRArgs() const145806d4ba38SDimitry Andric   unsigned totalIRArgs() const { return TotalIRArgs; }
145906d4ba38SDimitry Andric 
hasPaddingArg(unsigned ArgNo) const146006d4ba38SDimitry Andric   bool hasPaddingArg(unsigned ArgNo) const {
146106d4ba38SDimitry Andric     assert(ArgNo < ArgInfo.size());
146206d4ba38SDimitry Andric     return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
146306d4ba38SDimitry Andric   }
getPaddingArgNo(unsigned ArgNo) const146406d4ba38SDimitry Andric   unsigned getPaddingArgNo(unsigned ArgNo) const {
146506d4ba38SDimitry Andric     assert(hasPaddingArg(ArgNo));
146606d4ba38SDimitry Andric     return ArgInfo[ArgNo].PaddingArgIndex;
146706d4ba38SDimitry Andric   }
146806d4ba38SDimitry Andric 
146906d4ba38SDimitry Andric   /// Returns index of first IR argument corresponding to ArgNo, and their
147006d4ba38SDimitry Andric   /// quantity.
getIRArgs(unsigned ArgNo) const147106d4ba38SDimitry Andric   std::pair<unsigned, unsigned> getIRArgs(unsigned ArgNo) const {
147206d4ba38SDimitry Andric     assert(ArgNo < ArgInfo.size());
147306d4ba38SDimitry Andric     return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
147406d4ba38SDimitry Andric                           ArgInfo[ArgNo].NumberOfArgs);
147506d4ba38SDimitry Andric   }
147606d4ba38SDimitry Andric 
147706d4ba38SDimitry Andric private:
147806d4ba38SDimitry Andric   void construct(const ASTContext &Context, const CGFunctionInfo &FI,
147906d4ba38SDimitry Andric                  bool OnlyRequiredArgs);
148006d4ba38SDimitry Andric };
148106d4ba38SDimitry Andric 
construct(const ASTContext & Context,const CGFunctionInfo & FI,bool OnlyRequiredArgs)148206d4ba38SDimitry Andric void ClangToLLVMArgMapping::construct(const ASTContext &Context,
148306d4ba38SDimitry Andric                                       const CGFunctionInfo &FI,
148406d4ba38SDimitry Andric                                       bool OnlyRequiredArgs) {
148506d4ba38SDimitry Andric   unsigned IRArgNo = 0;
148606d4ba38SDimitry Andric   bool SwapThisWithSRet = false;
148706d4ba38SDimitry Andric   const ABIArgInfo &RetAI = FI.getReturnInfo();
148806d4ba38SDimitry Andric 
148906d4ba38SDimitry Andric   if (RetAI.getKind() == ABIArgInfo::Indirect) {
149006d4ba38SDimitry Andric     SwapThisWithSRet = RetAI.isSRetAfterThis();
149106d4ba38SDimitry Andric     SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
149206d4ba38SDimitry Andric   }
149306d4ba38SDimitry Andric 
149406d4ba38SDimitry Andric   unsigned ArgNo = 0;
149506d4ba38SDimitry Andric   unsigned NumArgs = OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size();
149606d4ba38SDimitry Andric   for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(); ArgNo < NumArgs;
149706d4ba38SDimitry Andric        ++I, ++ArgNo) {
149806d4ba38SDimitry Andric     assert(I != FI.arg_end());
149906d4ba38SDimitry Andric     QualType ArgType = I->type;
150006d4ba38SDimitry Andric     const ABIArgInfo &AI = I->info;
150106d4ba38SDimitry Andric     // Collect data about IR arguments corresponding to Clang argument ArgNo.
150206d4ba38SDimitry Andric     auto &IRArgs = ArgInfo[ArgNo];
150306d4ba38SDimitry Andric 
150406d4ba38SDimitry Andric     if (AI.getPaddingType())
150506d4ba38SDimitry Andric       IRArgs.PaddingArgIndex = IRArgNo++;
150606d4ba38SDimitry Andric 
150706d4ba38SDimitry Andric     switch (AI.getKind()) {
150806d4ba38SDimitry Andric     case ABIArgInfo::Extend:
150906d4ba38SDimitry Andric     case ABIArgInfo::Direct: {
151006d4ba38SDimitry Andric       // FIXME: handle sseregparm someday...
151106d4ba38SDimitry Andric       llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.getCoerceToType());
151206d4ba38SDimitry Andric       if (AI.isDirect() && AI.getCanBeFlattened() && STy) {
151306d4ba38SDimitry Andric         IRArgs.NumberOfArgs = STy->getNumElements();
151406d4ba38SDimitry Andric       } else {
151506d4ba38SDimitry Andric         IRArgs.NumberOfArgs = 1;
151606d4ba38SDimitry Andric       }
151706d4ba38SDimitry Andric       break;
151806d4ba38SDimitry Andric     }
151906d4ba38SDimitry Andric     case ABIArgInfo::Indirect:
1520b60736ecSDimitry Andric     case ABIArgInfo::IndirectAliased:
152106d4ba38SDimitry Andric       IRArgs.NumberOfArgs = 1;
152206d4ba38SDimitry Andric       break;
152306d4ba38SDimitry Andric     case ABIArgInfo::Ignore:
152406d4ba38SDimitry Andric     case ABIArgInfo::InAlloca:
152506d4ba38SDimitry Andric       // ignore and inalloca doesn't have matching LLVM parameters.
152606d4ba38SDimitry Andric       IRArgs.NumberOfArgs = 0;
152706d4ba38SDimitry Andric       break;
15282b6b257fSDimitry Andric     case ABIArgInfo::CoerceAndExpand:
15292b6b257fSDimitry Andric       IRArgs.NumberOfArgs = AI.getCoerceAndExpandTypeSequence().size();
15302b6b257fSDimitry Andric       break;
15312b6b257fSDimitry Andric     case ABIArgInfo::Expand:
153206d4ba38SDimitry Andric       IRArgs.NumberOfArgs = getExpansionSize(ArgType, Context);
153306d4ba38SDimitry Andric       break;
153406d4ba38SDimitry Andric     }
153506d4ba38SDimitry Andric 
153606d4ba38SDimitry Andric     if (IRArgs.NumberOfArgs > 0) {
153706d4ba38SDimitry Andric       IRArgs.FirstArgIndex = IRArgNo;
153806d4ba38SDimitry Andric       IRArgNo += IRArgs.NumberOfArgs;
153906d4ba38SDimitry Andric     }
154006d4ba38SDimitry Andric 
154106d4ba38SDimitry Andric     // Skip over the sret parameter when it comes second.  We already handled it
154206d4ba38SDimitry Andric     // above.
154306d4ba38SDimitry Andric     if (IRArgNo == 1 && SwapThisWithSRet)
154406d4ba38SDimitry Andric       IRArgNo++;
154506d4ba38SDimitry Andric   }
154606d4ba38SDimitry Andric   assert(ArgNo == ArgInfo.size());
154706d4ba38SDimitry Andric 
154806d4ba38SDimitry Andric   if (FI.usesInAlloca())
154906d4ba38SDimitry Andric     InallocaArgNo = IRArgNo++;
155006d4ba38SDimitry Andric 
155106d4ba38SDimitry Andric   TotalIRArgs = IRArgNo;
155206d4ba38SDimitry Andric }
155306d4ba38SDimitry Andric }  // namespace
155406d4ba38SDimitry Andric 
1555ec2b103cSEd Schouten /***/
1556ec2b103cSEd Schouten 
ReturnTypeUsesSRet(const CGFunctionInfo & FI)15574e58654bSRoman Divacky bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
155848675466SDimitry Andric   const auto &RI = FI.getReturnInfo();
155948675466SDimitry Andric   return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
1560ec2b103cSEd Schouten }
1561ec2b103cSEd Schouten 
ReturnTypeHasInReg(const CGFunctionInfo & FI)1562ac9a064cSDimitry Andric bool CodeGenModule::ReturnTypeHasInReg(const CGFunctionInfo &FI) {
1563ac9a064cSDimitry Andric   const auto &RI = FI.getReturnInfo();
1564ac9a064cSDimitry Andric   return RI.getInReg();
1565ac9a064cSDimitry Andric }
1566ac9a064cSDimitry Andric 
ReturnSlotInterferesWithArgs(const CGFunctionInfo & FI)15679f4dbff6SDimitry Andric bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
15689f4dbff6SDimitry Andric   return ReturnTypeUsesSRet(FI) &&
15699f4dbff6SDimitry Andric          getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs();
15709f4dbff6SDimitry Andric }
15719f4dbff6SDimitry Andric 
ReturnTypeUsesFPRet(QualType ResultType)15724e58654bSRoman Divacky bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) {
15734e58654bSRoman Divacky   if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
15744e58654bSRoman Divacky     switch (BT->getKind()) {
15754e58654bSRoman Divacky     default:
15764e58654bSRoman Divacky       return false;
15774e58654bSRoman Divacky     case BuiltinType::Float:
1578c0981da4SDimitry Andric       return getTarget().useObjCFPRetForRealType(FloatModeKind::Float);
15794e58654bSRoman Divacky     case BuiltinType::Double:
1580c0981da4SDimitry Andric       return getTarget().useObjCFPRetForRealType(FloatModeKind::Double);
15814e58654bSRoman Divacky     case BuiltinType::LongDouble:
1582c0981da4SDimitry Andric       return getTarget().useObjCFPRetForRealType(FloatModeKind::LongDouble);
15834e58654bSRoman Divacky     }
15844e58654bSRoman Divacky   }
15854e58654bSRoman Divacky 
15864e58654bSRoman Divacky   return false;
15874e58654bSRoman Divacky }
15884e58654bSRoman Divacky 
ReturnTypeUsesFP2Ret(QualType ResultType)1589dbe13110SDimitry Andric bool CodeGenModule::ReturnTypeUsesFP2Ret(QualType ResultType) {
1590dbe13110SDimitry Andric   if (const ComplexType *CT = ResultType->getAs<ComplexType>()) {
1591dbe13110SDimitry Andric     if (const BuiltinType *BT = CT->getElementType()->getAs<BuiltinType>()) {
1592dbe13110SDimitry Andric       if (BT->getKind() == BuiltinType::LongDouble)
15936a037251SDimitry Andric         return getTarget().useObjCFP2RetForComplexLongDouble();
1594dbe13110SDimitry Andric     }
1595dbe13110SDimitry Andric   }
1596dbe13110SDimitry Andric 
1597dbe13110SDimitry Andric   return false;
1598dbe13110SDimitry Andric }
1599dbe13110SDimitry Andric 
GetFunctionType(GlobalDecl GD)1600180abc3dSDimitry Andric llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) {
1601dbe13110SDimitry Andric   const CGFunctionInfo &FI = arrangeGlobalDeclaration(GD);
1602dbe13110SDimitry Andric   return GetFunctionType(FI);
160379ade4e0SRoman Divacky }
160479ade4e0SRoman Divacky 
1605180abc3dSDimitry Andric llvm::FunctionType *
GetFunctionType(const CGFunctionInfo & FI)1606dbe13110SDimitry Andric CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
1607180abc3dSDimitry Andric 
160806d4ba38SDimitry Andric   bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
160906d4ba38SDimitry Andric   (void)Inserted;
1610180abc3dSDimitry Andric   assert(Inserted && "Recursively being processed?");
1611180abc3dSDimitry Andric 
16129f4dbff6SDimitry Andric   llvm::Type *resultType = nullptr;
161329cafa66SDimitry Andric   const ABIArgInfo &retAI = FI.getReturnInfo();
161429cafa66SDimitry Andric   switch (retAI.getKind()) {
1615ec2b103cSEd Schouten   case ABIArgInfo::Expand:
1616b60736ecSDimitry Andric   case ABIArgInfo::IndirectAliased:
161729cafa66SDimitry Andric     llvm_unreachable("Invalid ABI kind for return argument");
1618ec2b103cSEd Schouten 
161970b4596dSEd Schouten   case ABIArgInfo::Extend:
1620ec2b103cSEd Schouten   case ABIArgInfo::Direct:
162129cafa66SDimitry Andric     resultType = retAI.getCoerceToType();
1622ec2b103cSEd Schouten     break;
1623ec2b103cSEd Schouten 
16249f4dbff6SDimitry Andric   case ABIArgInfo::InAlloca:
16259f4dbff6SDimitry Andric     if (retAI.getInAllocaSRet()) {
16269f4dbff6SDimitry Andric       // sret things on win32 aren't void, they return the sret pointer.
16279f4dbff6SDimitry Andric       QualType ret = FI.getReturnType();
1628e3b55780SDimitry Andric       unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
16297fa27ce4SDimitry Andric       resultType = llvm::PointerType::get(getLLVMContext(), addressSpace);
16309f4dbff6SDimitry Andric     } else {
16319f4dbff6SDimitry Andric       resultType = llvm::Type::getVoidTy(getLLVMContext());
16329f4dbff6SDimitry Andric     }
16339f4dbff6SDimitry Andric     break;
16349f4dbff6SDimitry Andric 
16357e86edd6SDimitry Andric   case ABIArgInfo::Indirect:
1636ec2b103cSEd Schouten   case ABIArgInfo::Ignore:
163729cafa66SDimitry Andric     resultType = llvm::Type::getVoidTy(getLLVMContext());
1638ec2b103cSEd Schouten     break;
16392b6b257fSDimitry Andric 
16402b6b257fSDimitry Andric   case ABIArgInfo::CoerceAndExpand:
16412b6b257fSDimitry Andric     resultType = retAI.getUnpaddedCoerceAndExpandType();
16422b6b257fSDimitry Andric     break;
1643ec2b103cSEd Schouten   }
1644ec2b103cSEd Schouten 
164506d4ba38SDimitry Andric   ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI, true);
164606d4ba38SDimitry Andric   SmallVector<llvm::Type*, 8> ArgTypes(IRFunctionArgs.totalIRArgs());
164706d4ba38SDimitry Andric 
164806d4ba38SDimitry Andric   // Add type for sret argument.
164906d4ba38SDimitry Andric   if (IRFunctionArgs.hasSRetArg()) {
165006d4ba38SDimitry Andric     QualType Ret = FI.getReturnType();
1651e3b55780SDimitry Andric     unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(Ret);
165206d4ba38SDimitry Andric     ArgTypes[IRFunctionArgs.getSRetArgNo()] =
16537fa27ce4SDimitry Andric         llvm::PointerType::get(getLLVMContext(), AddressSpace);
1654809500fcSDimitry Andric   }
165506d4ba38SDimitry Andric 
165606d4ba38SDimitry Andric   // Add type for inalloca argument.
16577fa27ce4SDimitry Andric   if (IRFunctionArgs.hasInallocaArg())
16587fa27ce4SDimitry Andric     ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
16597fa27ce4SDimitry Andric         llvm::PointerType::getUnqual(getLLVMContext());
166006d4ba38SDimitry Andric 
166106d4ba38SDimitry Andric   // Add in all of the required arguments.
166206d4ba38SDimitry Andric   unsigned ArgNo = 0;
166306d4ba38SDimitry Andric   CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
166406d4ba38SDimitry Andric                                      ie = it + FI.getNumRequiredArgs();
166506d4ba38SDimitry Andric   for (; it != ie; ++it, ++ArgNo) {
166606d4ba38SDimitry Andric     const ABIArgInfo &ArgInfo = it->info;
1667ec2b103cSEd Schouten 
166813cc256eSDimitry Andric     // Insert a padding type to ensure proper alignment.
166906d4ba38SDimitry Andric     if (IRFunctionArgs.hasPaddingArg(ArgNo))
167006d4ba38SDimitry Andric       ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
167106d4ba38SDimitry Andric           ArgInfo.getPaddingType();
167213cc256eSDimitry Andric 
167306d4ba38SDimitry Andric     unsigned FirstIRArg, NumIRArgs;
167406d4ba38SDimitry Andric     std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
167506d4ba38SDimitry Andric 
167606d4ba38SDimitry Andric     switch (ArgInfo.getKind()) {
1677ec2b103cSEd Schouten     case ABIArgInfo::Ignore:
16789f4dbff6SDimitry Andric     case ABIArgInfo::InAlloca:
167906d4ba38SDimitry Andric       assert(NumIRArgs == 0);
1680ec2b103cSEd Schouten       break;
1681ec2b103cSEd Schouten 
16827fa27ce4SDimitry Andric     case ABIArgInfo::Indirect:
168306d4ba38SDimitry Andric       assert(NumIRArgs == 1);
1684583e75ccSDimitry Andric       // indirect arguments are always on the stack, which is alloca addr space.
16857fa27ce4SDimitry Andric       ArgTypes[FirstIRArg] = llvm::PointerType::get(
16867fa27ce4SDimitry Andric           getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace());
16873d1dcd9bSDimitry Andric       break;
16887fa27ce4SDimitry Andric     case ABIArgInfo::IndirectAliased:
1689b60736ecSDimitry Andric       assert(NumIRArgs == 1);
16907fa27ce4SDimitry Andric       ArgTypes[FirstIRArg] = llvm::PointerType::get(
16917fa27ce4SDimitry Andric           getLLVMContext(), ArgInfo.getIndirectAddrSpace());
1692b60736ecSDimitry Andric       break;
16933d1dcd9bSDimitry Andric     case ABIArgInfo::Extend:
16943d1dcd9bSDimitry Andric     case ABIArgInfo::Direct: {
169506d4ba38SDimitry Andric       // Fast-isel and the optimizer generally like scalar values better than
169606d4ba38SDimitry Andric       // FCAs, so we flatten them if this is safe to do for this argument.
169706d4ba38SDimitry Andric       llvm::Type *argType = ArgInfo.getCoerceToType();
16989f4dbff6SDimitry Andric       llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
169906d4ba38SDimitry Andric       if (st && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) {
170006d4ba38SDimitry Andric         assert(NumIRArgs == st->getNumElements());
170129cafa66SDimitry Andric         for (unsigned i = 0, e = st->getNumElements(); i != e; ++i)
170206d4ba38SDimitry Andric           ArgTypes[FirstIRArg + i] = st->getElementType(i);
17034ba67500SRoman Divacky       } else {
170406d4ba38SDimitry Andric         assert(NumIRArgs == 1);
170506d4ba38SDimitry Andric         ArgTypes[FirstIRArg] = argType;
17064ba67500SRoman Divacky       }
1707ec2b103cSEd Schouten       break;
17084ba67500SRoman Divacky     }
1709ec2b103cSEd Schouten 
17102b6b257fSDimitry Andric     case ABIArgInfo::CoerceAndExpand: {
17112b6b257fSDimitry Andric       auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1712e3b55780SDimitry Andric       for (auto *EltTy : ArgInfo.getCoerceAndExpandTypeSequence()) {
17132b6b257fSDimitry Andric         *ArgTypesIter++ = EltTy;
17142b6b257fSDimitry Andric       }
17152b6b257fSDimitry Andric       assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
17162b6b257fSDimitry Andric       break;
17172b6b257fSDimitry Andric     }
17182b6b257fSDimitry Andric 
1719ec2b103cSEd Schouten     case ABIArgInfo::Expand:
172006d4ba38SDimitry Andric       auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
172106d4ba38SDimitry Andric       getExpandedTypes(it->type, ArgTypesIter);
172206d4ba38SDimitry Andric       assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
1723ec2b103cSEd Schouten       break;
1724ec2b103cSEd Schouten     }
1725ec2b103cSEd Schouten   }
1726ec2b103cSEd Schouten 
1727180abc3dSDimitry Andric   bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased;
1728180abc3dSDimitry Andric   assert(Erased && "Not in set?");
1729180abc3dSDimitry Andric 
173006d4ba38SDimitry Andric   return llvm::FunctionType::get(resultType, ArgTypes, FI.isVariadic());
1731ec2b103cSEd Schouten }
1732ec2b103cSEd Schouten 
GetFunctionTypeForVTable(GlobalDecl GD)173336981b17SDimitry Andric llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) {
17343d1dcd9bSDimitry Andric   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
17357fa27ce4SDimitry Andric   const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
17361569ce68SRoman Divacky 
1737180abc3dSDimitry Andric   if (!isFuncTypeConvertible(FPT))
1738180abc3dSDimitry Andric     return llvm::StructType::get(getLLVMContext());
1739180abc3dSDimitry Andric 
174022989816SDimitry Andric   return GetFunctionType(GD);
17411569ce68SRoman Divacky }
17421569ce68SRoman Divacky 
AddAttributesFromFunctionProtoType(ASTContext & Ctx,llvm::AttrBuilder & FuncAttrs,const FunctionProtoType * FPT)174345b53394SDimitry Andric static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
174445b53394SDimitry Andric                                                llvm::AttrBuilder &FuncAttrs,
174545b53394SDimitry Andric                                                const FunctionProtoType *FPT) {
174645b53394SDimitry Andric   if (!FPT)
174745b53394SDimitry Andric     return;
174845b53394SDimitry Andric 
174945b53394SDimitry Andric   if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
175048675466SDimitry Andric       FPT->isNothrow())
175145b53394SDimitry Andric     FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1752b1c73532SDimitry Andric 
17534df029ccSDimitry Andric   unsigned SMEBits = FPT->getAArch64SMEAttributes();
17544df029ccSDimitry Andric   if (SMEBits & FunctionType::SME_PStateSMEnabledMask)
1755b1c73532SDimitry Andric     FuncAttrs.addAttribute("aarch64_pstate_sm_enabled");
17564df029ccSDimitry Andric   if (SMEBits & FunctionType::SME_PStateSMCompatibleMask)
1757b1c73532SDimitry Andric     FuncAttrs.addAttribute("aarch64_pstate_sm_compatible");
17584df029ccSDimitry Andric 
17594df029ccSDimitry Andric   // ZA
1760ac9a064cSDimitry Andric   if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Preserves)
1761ac9a064cSDimitry Andric     FuncAttrs.addAttribute("aarch64_preserves_za");
1762ac9a064cSDimitry Andric   if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_In)
1763ac9a064cSDimitry Andric     FuncAttrs.addAttribute("aarch64_in_za");
1764ac9a064cSDimitry Andric   if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Out)
1765ac9a064cSDimitry Andric     FuncAttrs.addAttribute("aarch64_out_za");
1766ac9a064cSDimitry Andric   if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
1767ac9a064cSDimitry Andric     FuncAttrs.addAttribute("aarch64_inout_za");
176845b53394SDimitry Andric 
17694df029ccSDimitry Andric   // ZT0
17704df029ccSDimitry Andric   if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)
17714df029ccSDimitry Andric     FuncAttrs.addAttribute("aarch64_preserves_zt0");
17724df029ccSDimitry Andric   if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)
17734df029ccSDimitry Andric     FuncAttrs.addAttribute("aarch64_in_zt0");
17744df029ccSDimitry Andric   if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)
17754df029ccSDimitry Andric     FuncAttrs.addAttribute("aarch64_out_zt0");
17764df029ccSDimitry Andric   if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)
17774df029ccSDimitry Andric     FuncAttrs.addAttribute("aarch64_inout_zt0");
17784df029ccSDimitry Andric }
17794df029ccSDimitry Andric 
AddAttributesFromOMPAssumes(llvm::AttrBuilder & FuncAttrs,const Decl * Callee)1780ac9a064cSDimitry Andric static void AddAttributesFromOMPAssumes(llvm::AttrBuilder &FuncAttrs,
1781c0981da4SDimitry Andric                                         const Decl *Callee) {
1782c0981da4SDimitry Andric   if (!Callee)
1783c0981da4SDimitry Andric     return;
1784c0981da4SDimitry Andric 
1785c0981da4SDimitry Andric   SmallVector<StringRef, 4> Attrs;
1786c0981da4SDimitry Andric 
1787ac9a064cSDimitry Andric   for (const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
1788c0981da4SDimitry Andric     AA->getAssumption().split(Attrs, ",");
1789c0981da4SDimitry Andric 
1790c0981da4SDimitry Andric   if (!Attrs.empty())
1791c0981da4SDimitry Andric     FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
1792c0981da4SDimitry Andric                            llvm::join(Attrs.begin(), Attrs.end(), ","));
1793c0981da4SDimitry Andric }
1794c0981da4SDimitry Andric 
MayDropFunctionReturn(const ASTContext & Context,QualType ReturnType) const1795344a3780SDimitry Andric bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context,
1796e3b55780SDimitry Andric                                           QualType ReturnType) const {
1797344a3780SDimitry Andric   // We can't just discard the return value for a record type with a
1798344a3780SDimitry Andric   // complex destructor or a non-trivially copyable type.
1799344a3780SDimitry Andric   if (const RecordType *RT =
1800344a3780SDimitry Andric           ReturnType.getCanonicalType()->getAs<RecordType>()) {
1801344a3780SDimitry Andric     if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
1802344a3780SDimitry Andric       return ClassDecl->hasTrivialDestructor();
1803344a3780SDimitry Andric   }
1804344a3780SDimitry Andric   return ReturnType.isTriviallyCopyableType(Context);
1805344a3780SDimitry Andric }
1806344a3780SDimitry Andric 
HasStrictReturn(const CodeGenModule & Module,QualType RetTy,const Decl * TargetDecl)1807e3b55780SDimitry Andric static bool HasStrictReturn(const CodeGenModule &Module, QualType RetTy,
1808e3b55780SDimitry Andric                             const Decl *TargetDecl) {
1809e3b55780SDimitry Andric   // As-is msan can not tolerate noundef mismatch between caller and
1810e3b55780SDimitry Andric   // implementation. Mismatch is possible for e.g. indirect calls from C-caller
1811e3b55780SDimitry Andric   // into C++. Such mismatches lead to confusing false reports. To avoid
1812e3b55780SDimitry Andric   // expensive workaround on msan we enforce initialization event in uncommon
1813e3b55780SDimitry Andric   // cases where it's allowed.
1814e3b55780SDimitry Andric   if (Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
1815e3b55780SDimitry Andric     return true;
1816e3b55780SDimitry Andric   // C++ explicitly makes returning undefined values UB. C's rule only applies
1817e3b55780SDimitry Andric   // to used values, so we never mark them noundef for now.
1818e3b55780SDimitry Andric   if (!Module.getLangOpts().CPlusPlus)
1819e3b55780SDimitry Andric     return false;
1820e3b55780SDimitry Andric   if (TargetDecl) {
1821e3b55780SDimitry Andric     if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
1822e3b55780SDimitry Andric       if (FDecl->isExternC())
1823e3b55780SDimitry Andric         return false;
1824e3b55780SDimitry Andric     } else if (const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
1825e3b55780SDimitry Andric       // Function pointer.
1826e3b55780SDimitry Andric       if (VDecl->isExternC())
1827e3b55780SDimitry Andric         return false;
1828e3b55780SDimitry Andric     }
1829e3b55780SDimitry Andric   }
1830e3b55780SDimitry Andric 
1831e3b55780SDimitry Andric   // We don't want to be too aggressive with the return checking, unless
1832e3b55780SDimitry Andric   // it's explicit in the code opts or we're using an appropriate sanitizer.
1833e3b55780SDimitry Andric   // Try to respect what the programmer intended.
1834e3b55780SDimitry Andric   return Module.getCodeGenOpts().StrictReturn ||
1835e3b55780SDimitry Andric          !Module.MayDropFunctionReturn(Module.getContext(), RetTy) ||
1836e3b55780SDimitry Andric          Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
1837e3b55780SDimitry Andric }
1838e3b55780SDimitry Andric 
18397fa27ce4SDimitry Andric /// Add denormal-fp-math and denormal-fp-math-f32 as appropriate for the
18407fa27ce4SDimitry Andric /// requested denormal behavior, accounting for the overriding behavior of the
18417fa27ce4SDimitry Andric /// -f32 case.
addDenormalModeAttrs(llvm::DenormalMode FPDenormalMode,llvm::DenormalMode FP32DenormalMode,llvm::AttrBuilder & FuncAttrs)18427fa27ce4SDimitry Andric static void addDenormalModeAttrs(llvm::DenormalMode FPDenormalMode,
18437fa27ce4SDimitry Andric                                  llvm::DenormalMode FP32DenormalMode,
18447fa27ce4SDimitry Andric                                  llvm::AttrBuilder &FuncAttrs) {
18457fa27ce4SDimitry Andric   if (FPDenormalMode != llvm::DenormalMode::getDefault())
18467fa27ce4SDimitry Andric     FuncAttrs.addAttribute("denormal-fp-math", FPDenormalMode.str());
18477fa27ce4SDimitry Andric 
18487fa27ce4SDimitry Andric   if (FP32DenormalMode != FPDenormalMode && FP32DenormalMode.isValid())
18497fa27ce4SDimitry Andric     FuncAttrs.addAttribute("denormal-fp-math-f32", FP32DenormalMode.str());
18507fa27ce4SDimitry Andric }
18517fa27ce4SDimitry Andric 
18527fa27ce4SDimitry Andric /// Add default attributes to a function, which have merge semantics under
18537fa27ce4SDimitry Andric /// -mlink-builtin-bitcode and should not simply overwrite any existing
18547fa27ce4SDimitry Andric /// attributes in the linked library.
18557fa27ce4SDimitry Andric static void
addMergableDefaultFunctionAttributes(const CodeGenOptions & CodeGenOpts,llvm::AttrBuilder & FuncAttrs)18567fa27ce4SDimitry Andric addMergableDefaultFunctionAttributes(const CodeGenOptions &CodeGenOpts,
18577fa27ce4SDimitry Andric                                      llvm::AttrBuilder &FuncAttrs) {
18587fa27ce4SDimitry Andric   addDenormalModeAttrs(CodeGenOpts.FPDenormalMode, CodeGenOpts.FP32DenormalMode,
18597fa27ce4SDimitry Andric                        FuncAttrs);
18607fa27ce4SDimitry Andric }
18617fa27ce4SDimitry Andric 
getTrivialDefaultFunctionAttributes(StringRef Name,bool HasOptnone,const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts,bool AttrOnCallSite,llvm::AttrBuilder & FuncAttrs)18627fa27ce4SDimitry Andric static void getTrivialDefaultFunctionAttributes(
18637fa27ce4SDimitry Andric     StringRef Name, bool HasOptnone, const CodeGenOptions &CodeGenOpts,
18647fa27ce4SDimitry Andric     const LangOptions &LangOpts, bool AttrOnCallSite,
18657442d6faSDimitry Andric     llvm::AttrBuilder &FuncAttrs) {
18667442d6faSDimitry Andric   // OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
18677442d6faSDimitry Andric   if (!HasOptnone) {
18687442d6faSDimitry Andric     if (CodeGenOpts.OptimizeSize)
18697442d6faSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
18707442d6faSDimitry Andric     if (CodeGenOpts.OptimizeSize == 2)
18717442d6faSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::MinSize);
18727442d6faSDimitry Andric   }
18737442d6faSDimitry Andric 
18747442d6faSDimitry Andric   if (CodeGenOpts.DisableRedZone)
18757442d6faSDimitry Andric     FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
1876676fbe81SDimitry Andric   if (CodeGenOpts.IndirectTlsSegRefs)
1877676fbe81SDimitry Andric     FuncAttrs.addAttribute("indirect-tls-seg-refs");
18787442d6faSDimitry Andric   if (CodeGenOpts.NoImplicitFloat)
18797442d6faSDimitry Andric     FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
18807442d6faSDimitry Andric 
18817442d6faSDimitry Andric   if (AttrOnCallSite) {
18827442d6faSDimitry Andric     // Attributes that should go on the call site only.
1883145449b1SDimitry Andric     // FIXME: Look for 'BuiltinAttr' on the function rather than re-checking
1884145449b1SDimitry Andric     // the -fno-builtin-foo list.
1885344a3780SDimitry Andric     if (!CodeGenOpts.SimplifyLibCalls || LangOpts.isNoBuiltinFunc(Name))
18867442d6faSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
18877442d6faSDimitry Andric     if (!CodeGenOpts.TrapFuncName.empty())
18887442d6faSDimitry Andric       FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
18897442d6faSDimitry Andric   } else {
1890519fc96cSDimitry Andric     switch (CodeGenOpts.getFramePointer()) {
1891519fc96cSDimitry Andric     case CodeGenOptions::FramePointerKind::None:
1892e3b55780SDimitry Andric       // This is the default behavior.
1893519fc96cSDimitry Andric       break;
1894ac9a064cSDimitry Andric     case CodeGenOptions::FramePointerKind::Reserved:
1895519fc96cSDimitry Andric     case CodeGenOptions::FramePointerKind::NonLeaf:
1896519fc96cSDimitry Andric     case CodeGenOptions::FramePointerKind::All:
1897e3b55780SDimitry Andric       FuncAttrs.addAttribute("frame-pointer",
1898e3b55780SDimitry Andric                              CodeGenOptions::getFramePointerKindName(
1899e3b55780SDimitry Andric                                  CodeGenOpts.getFramePointer()));
19007442d6faSDimitry Andric     }
19017442d6faSDimitry Andric 
1902344a3780SDimitry Andric     if (CodeGenOpts.LessPreciseFPMAD)
1903344a3780SDimitry Andric       FuncAttrs.addAttribute("less-precise-fpmad", "true");
19047442d6faSDimitry Andric 
190548675466SDimitry Andric     if (CodeGenOpts.NullPointerIsValid)
1906cfca06d7SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
1907cfca06d7SDimitry Andric 
1908145449b1SDimitry Andric     if (LangOpts.getDefaultExceptionMode() == LangOptions::FPE_Ignore)
1909344a3780SDimitry Andric       FuncAttrs.addAttribute("no-trapping-math", "true");
19107442d6faSDimitry Andric 
19117442d6faSDimitry Andric     // TODO: Are these all needed?
19127442d6faSDimitry Andric     // unsafe/inf/nan/nsz are handled by instruction-level FastMathFlags.
1913344a3780SDimitry Andric     if (LangOpts.NoHonorInfs)
1914344a3780SDimitry Andric       FuncAttrs.addAttribute("no-infs-fp-math", "true");
1915344a3780SDimitry Andric     if (LangOpts.NoHonorNaNs)
1916344a3780SDimitry Andric       FuncAttrs.addAttribute("no-nans-fp-math", "true");
1917c0981da4SDimitry Andric     if (LangOpts.ApproxFunc)
1918c0981da4SDimitry Andric       FuncAttrs.addAttribute("approx-func-fp-math", "true");
1919e3b55780SDimitry Andric     if (LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
1920e3b55780SDimitry Andric         LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
1921e3b55780SDimitry Andric         (LangOpts.getDefaultFPContractMode() ==
1922e3b55780SDimitry Andric              LangOptions::FPModeKind::FPM_Fast ||
1923e3b55780SDimitry Andric          LangOpts.getDefaultFPContractMode() ==
1924e3b55780SDimitry Andric              LangOptions::FPModeKind::FPM_FastHonorPragmas))
1925344a3780SDimitry Andric       FuncAttrs.addAttribute("unsafe-fp-math", "true");
1926344a3780SDimitry Andric     if (CodeGenOpts.SoftFloat)
1927344a3780SDimitry Andric       FuncAttrs.addAttribute("use-soft-float", "true");
19287442d6faSDimitry Andric     FuncAttrs.addAttribute("stack-protector-buffer-size",
19297442d6faSDimitry Andric                            llvm::utostr(CodeGenOpts.SSPBufferSize));
1930344a3780SDimitry Andric     if (LangOpts.NoSignedZero)
1931344a3780SDimitry Andric       FuncAttrs.addAttribute("no-signed-zeros-fp-math", "true");
19327442d6faSDimitry Andric 
19337442d6faSDimitry Andric     // TODO: Reciprocal estimate codegen options should apply to instructions?
1934461a67faSDimitry Andric     const std::vector<std::string> &Recips = CodeGenOpts.Reciprocals;
19357442d6faSDimitry Andric     if (!Recips.empty())
19367442d6faSDimitry Andric       FuncAttrs.addAttribute("reciprocal-estimates",
1937461a67faSDimitry Andric                              llvm::join(Recips, ","));
1938461a67faSDimitry Andric 
1939461a67faSDimitry Andric     if (!CodeGenOpts.PreferVectorWidth.empty() &&
1940461a67faSDimitry Andric         CodeGenOpts.PreferVectorWidth != "none")
1941461a67faSDimitry Andric       FuncAttrs.addAttribute("prefer-vector-width",
1942461a67faSDimitry Andric                              CodeGenOpts.PreferVectorWidth);
19437442d6faSDimitry Andric 
19447442d6faSDimitry Andric     if (CodeGenOpts.StackRealignment)
19457442d6faSDimitry Andric       FuncAttrs.addAttribute("stackrealign");
19467442d6faSDimitry Andric     if (CodeGenOpts.Backchain)
19477442d6faSDimitry Andric       FuncAttrs.addAttribute("backchain");
1948cfca06d7SDimitry Andric     if (CodeGenOpts.EnableSegmentedStacks)
1949cfca06d7SDimitry Andric       FuncAttrs.addAttribute("split-stack");
1950676fbe81SDimitry Andric 
1951676fbe81SDimitry Andric     if (CodeGenOpts.SpeculativeLoadHardening)
1952676fbe81SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
1953145449b1SDimitry Andric 
1954145449b1SDimitry Andric     // Add zero-call-used-regs attribute.
1955145449b1SDimitry Andric     switch (CodeGenOpts.getZeroCallUsedRegs()) {
1956145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
1957145449b1SDimitry Andric       FuncAttrs.removeAttribute("zero-call-used-regs");
1958145449b1SDimitry Andric       break;
1959145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
1960145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "used-gpr-arg");
1961145449b1SDimitry Andric       break;
1962145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
1963145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "used-gpr");
1964145449b1SDimitry Andric       break;
1965145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
1966145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "used-arg");
1967145449b1SDimitry Andric       break;
1968145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
1969145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "used");
1970145449b1SDimitry Andric       break;
1971145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
1972145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "all-gpr-arg");
1973145449b1SDimitry Andric       break;
1974145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
1975145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "all-gpr");
1976145449b1SDimitry Andric       break;
1977145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
1978145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "all-arg");
1979145449b1SDimitry Andric       break;
1980145449b1SDimitry Andric     case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
1981145449b1SDimitry Andric       FuncAttrs.addAttribute("zero-call-used-regs", "all");
1982145449b1SDimitry Andric       break;
1983145449b1SDimitry Andric     }
19847442d6faSDimitry Andric   }
19857442d6faSDimitry Andric 
19867fa27ce4SDimitry Andric   if (LangOpts.assumeFunctionsAreConvergent()) {
1987461a67faSDimitry Andric     // Conservatively, mark all functions and calls in CUDA and OpenCL as
1988461a67faSDimitry Andric     // convergent (meaning, they may call an intrinsically convergent op, such
1989461a67faSDimitry Andric     // as __syncthreads() / barrier(), and so can't have certain optimizations
1990461a67faSDimitry Andric     // applied around them).  LLVM will remove this attribute where it safely
1991461a67faSDimitry Andric     // can.
19927442d6faSDimitry Andric     FuncAttrs.addAttribute(llvm::Attribute::Convergent);
1993461a67faSDimitry Andric   }
19947442d6faSDimitry Andric 
1995e3b55780SDimitry Andric   // TODO: NoUnwind attribute should be added for other GPU modes HIP,
19967fa27ce4SDimitry Andric   // OpenMP offload. AFAIK, neither of them support exceptions in device code.
19977fa27ce4SDimitry Andric   if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
19987fa27ce4SDimitry Andric       LangOpts.SYCLIsDevice) {
19997442d6faSDimitry Andric     FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
20007442d6faSDimitry Andric   }
2001676fbe81SDimitry Andric 
2002676fbe81SDimitry Andric   for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) {
2003676fbe81SDimitry Andric     StringRef Var, Value;
2004676fbe81SDimitry Andric     std::tie(Var, Value) = Attr.split('=');
2005676fbe81SDimitry Andric     FuncAttrs.addAttribute(Var, Value);
2006676fbe81SDimitry Andric   }
2007ac9a064cSDimitry Andric 
2008ac9a064cSDimitry Andric   TargetInfo::BranchProtectionInfo BPI(LangOpts);
2009adf62863SDimitry Andric   TargetCodeGenInfo::initBranchProtectionFnAttributes(BPI, FuncAttrs);
20107442d6faSDimitry Andric }
20117442d6faSDimitry Andric 
2012b1c73532SDimitry Andric /// Merges `target-features` from \TargetOpts and \F, and sets the result in
2013b1c73532SDimitry Andric /// \FuncAttr
2014b1c73532SDimitry Andric /// * features from \F are always kept
2015b1c73532SDimitry Andric /// * a feature from \TargetOpts is kept if itself and its opposite are absent
2016b1c73532SDimitry Andric /// from \F
2017b1c73532SDimitry Andric static void
overrideFunctionFeaturesWithTargetFeatures(llvm::AttrBuilder & FuncAttr,const llvm::Function & F,const TargetOptions & TargetOpts)2018b1c73532SDimitry Andric overrideFunctionFeaturesWithTargetFeatures(llvm::AttrBuilder &FuncAttr,
2019b1c73532SDimitry Andric                                            const llvm::Function &F,
2020b1c73532SDimitry Andric                                            const TargetOptions &TargetOpts) {
2021b1c73532SDimitry Andric   auto FFeatures = F.getFnAttribute("target-features");
2022b1c73532SDimitry Andric 
2023b1c73532SDimitry Andric   llvm::StringSet<> MergedNames;
2024b1c73532SDimitry Andric   SmallVector<StringRef> MergedFeatures;
2025b1c73532SDimitry Andric   MergedFeatures.reserve(TargetOpts.Features.size());
2026b1c73532SDimitry Andric 
2027b1c73532SDimitry Andric   auto AddUnmergedFeatures = [&](auto &&FeatureRange) {
2028b1c73532SDimitry Andric     for (StringRef Feature : FeatureRange) {
2029b1c73532SDimitry Andric       if (Feature.empty())
2030b1c73532SDimitry Andric         continue;
2031b1c73532SDimitry Andric       assert(Feature[0] == '+' || Feature[0] == '-');
2032b1c73532SDimitry Andric       StringRef Name = Feature.drop_front(1);
2033b1c73532SDimitry Andric       bool Merged = !MergedNames.insert(Name).second;
2034b1c73532SDimitry Andric       if (!Merged)
2035b1c73532SDimitry Andric         MergedFeatures.push_back(Feature);
2036b1c73532SDimitry Andric     }
2037b1c73532SDimitry Andric   };
2038b1c73532SDimitry Andric 
2039b1c73532SDimitry Andric   if (FFeatures.isValid())
2040b1c73532SDimitry Andric     AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(), ','));
2041b1c73532SDimitry Andric   AddUnmergedFeatures(TargetOpts.Features);
2042b1c73532SDimitry Andric 
2043b1c73532SDimitry Andric   if (!MergedFeatures.empty()) {
2044b1c73532SDimitry Andric     llvm::sort(MergedFeatures);
2045b1c73532SDimitry Andric     FuncAttr.addAttribute("target-features", llvm::join(MergedFeatures, ","));
2046b1c73532SDimitry Andric   }
2047b1c73532SDimitry Andric }
2048b1c73532SDimitry Andric 
mergeDefaultFunctionDefinitionAttributes(llvm::Function & F,const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts,const TargetOptions & TargetOpts,bool WillInternalize)2049b1c73532SDimitry Andric void CodeGen::mergeDefaultFunctionDefinitionAttributes(
2050b1c73532SDimitry Andric     llvm::Function &F, const CodeGenOptions &CodeGenOpts,
20517fa27ce4SDimitry Andric     const LangOptions &LangOpts, const TargetOptions &TargetOpts,
20527fa27ce4SDimitry Andric     bool WillInternalize) {
20537fa27ce4SDimitry Andric 
20547fa27ce4SDimitry Andric   llvm::AttrBuilder FuncAttrs(F.getContext());
20557fa27ce4SDimitry Andric   // Here we only extract the options that are relevant compared to the version
20567fa27ce4SDimitry Andric   // from GetCPUAndFeaturesAttributes.
20577fa27ce4SDimitry Andric   if (!TargetOpts.CPU.empty())
20587fa27ce4SDimitry Andric     FuncAttrs.addAttribute("target-cpu", TargetOpts.CPU);
20597fa27ce4SDimitry Andric   if (!TargetOpts.TuneCPU.empty())
20607fa27ce4SDimitry Andric     FuncAttrs.addAttribute("tune-cpu", TargetOpts.TuneCPU);
20617fa27ce4SDimitry Andric 
20627fa27ce4SDimitry Andric   ::getTrivialDefaultFunctionAttributes(F.getName(), F.hasOptNone(),
20637fa27ce4SDimitry Andric                                         CodeGenOpts, LangOpts,
20647fa27ce4SDimitry Andric                                         /*AttrOnCallSite=*/false, FuncAttrs);
20657fa27ce4SDimitry Andric 
20667fa27ce4SDimitry Andric   if (!WillInternalize && F.isInterposable()) {
20677fa27ce4SDimitry Andric     // Do not promote "dynamic" denormal-fp-math to this translation unit's
20687fa27ce4SDimitry Andric     // setting for weak functions that won't be internalized. The user has no
20697fa27ce4SDimitry Andric     // real control for how builtin bitcode is linked, so we shouldn't assume
20707fa27ce4SDimitry Andric     // later copies will use a consistent mode.
20717fa27ce4SDimitry Andric     F.addFnAttrs(FuncAttrs);
20727fa27ce4SDimitry Andric     return;
20737fa27ce4SDimitry Andric   }
20747fa27ce4SDimitry Andric 
20757fa27ce4SDimitry Andric   llvm::AttributeMask AttrsToRemove;
20767fa27ce4SDimitry Andric 
20777fa27ce4SDimitry Andric   llvm::DenormalMode DenormModeToMerge = F.getDenormalModeRaw();
20787fa27ce4SDimitry Andric   llvm::DenormalMode DenormModeToMergeF32 = F.getDenormalModeF32Raw();
20797fa27ce4SDimitry Andric   llvm::DenormalMode Merged =
20807fa27ce4SDimitry Andric       CodeGenOpts.FPDenormalMode.mergeCalleeMode(DenormModeToMerge);
20817fa27ce4SDimitry Andric   llvm::DenormalMode MergedF32 = CodeGenOpts.FP32DenormalMode;
20827fa27ce4SDimitry Andric 
20837fa27ce4SDimitry Andric   if (DenormModeToMergeF32.isValid()) {
20847fa27ce4SDimitry Andric     MergedF32 =
20857fa27ce4SDimitry Andric         CodeGenOpts.FP32DenormalMode.mergeCalleeMode(DenormModeToMergeF32);
20867fa27ce4SDimitry Andric   }
20877fa27ce4SDimitry Andric 
20887fa27ce4SDimitry Andric   if (Merged == llvm::DenormalMode::getDefault()) {
20897fa27ce4SDimitry Andric     AttrsToRemove.addAttribute("denormal-fp-math");
20907fa27ce4SDimitry Andric   } else if (Merged != DenormModeToMerge) {
20917fa27ce4SDimitry Andric     // Overwrite existing attribute
20927fa27ce4SDimitry Andric     FuncAttrs.addAttribute("denormal-fp-math",
20937fa27ce4SDimitry Andric                            CodeGenOpts.FPDenormalMode.str());
20947fa27ce4SDimitry Andric   }
20957fa27ce4SDimitry Andric 
20967fa27ce4SDimitry Andric   if (MergedF32 == llvm::DenormalMode::getDefault()) {
20977fa27ce4SDimitry Andric     AttrsToRemove.addAttribute("denormal-fp-math-f32");
20987fa27ce4SDimitry Andric   } else if (MergedF32 != DenormModeToMergeF32) {
20997fa27ce4SDimitry Andric     // Overwrite existing attribute
21007fa27ce4SDimitry Andric     FuncAttrs.addAttribute("denormal-fp-math-f32",
21017fa27ce4SDimitry Andric                            CodeGenOpts.FP32DenormalMode.str());
21027fa27ce4SDimitry Andric   }
21037fa27ce4SDimitry Andric 
21047fa27ce4SDimitry Andric   F.removeFnAttrs(AttrsToRemove);
21057fa27ce4SDimitry Andric   addDenormalModeAttrs(Merged, MergedF32, FuncAttrs);
2106b1c73532SDimitry Andric 
2107b1c73532SDimitry Andric   overrideFunctionFeaturesWithTargetFeatures(FuncAttrs, F, TargetOpts);
2108b1c73532SDimitry Andric 
21097fa27ce4SDimitry Andric   F.addFnAttrs(FuncAttrs);
21107fa27ce4SDimitry Andric }
21117fa27ce4SDimitry Andric 
getTrivialDefaultFunctionAttributes(StringRef Name,bool HasOptnone,bool AttrOnCallSite,llvm::AttrBuilder & FuncAttrs)21127fa27ce4SDimitry Andric void CodeGenModule::getTrivialDefaultFunctionAttributes(
21137fa27ce4SDimitry Andric     StringRef Name, bool HasOptnone, bool AttrOnCallSite,
21147fa27ce4SDimitry Andric     llvm::AttrBuilder &FuncAttrs) {
21157fa27ce4SDimitry Andric   ::getTrivialDefaultFunctionAttributes(Name, HasOptnone, getCodeGenOpts(),
21167fa27ce4SDimitry Andric                                         getLangOpts(), AttrOnCallSite,
21177fa27ce4SDimitry Andric                                         FuncAttrs);
21187fa27ce4SDimitry Andric }
21197fa27ce4SDimitry Andric 
getDefaultFunctionAttributes(StringRef Name,bool HasOptnone,bool AttrOnCallSite,llvm::AttrBuilder & FuncAttrs)21207fa27ce4SDimitry Andric void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
21217fa27ce4SDimitry Andric                                                  bool HasOptnone,
21227fa27ce4SDimitry Andric                                                  bool AttrOnCallSite,
21237fa27ce4SDimitry Andric                                                  llvm::AttrBuilder &FuncAttrs) {
21247fa27ce4SDimitry Andric   getTrivialDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite,
21257fa27ce4SDimitry Andric                                       FuncAttrs);
21267fa27ce4SDimitry Andric   // If we're just getting the default, get the default values for mergeable
21277fa27ce4SDimitry Andric   // attributes.
21287fa27ce4SDimitry Andric   if (!AttrOnCallSite)
21297fa27ce4SDimitry Andric     addMergableDefaultFunctionAttributes(CodeGenOpts, FuncAttrs);
21307fa27ce4SDimitry Andric }
21317fa27ce4SDimitry Andric 
addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder & attrs)2132cfca06d7SDimitry Andric void CodeGenModule::addDefaultFunctionDefinitionAttributes(
2133cfca06d7SDimitry Andric     llvm::AttrBuilder &attrs) {
2134cfca06d7SDimitry Andric   getDefaultFunctionAttributes(/*function name*/ "", /*optnone*/ false,
2135cfca06d7SDimitry Andric                                /*for call*/ false, attrs);
2136cfca06d7SDimitry Andric   GetCPUAndFeaturesAttributes(GlobalDecl(), attrs);
2137cfca06d7SDimitry Andric }
2138cfca06d7SDimitry Andric 
addNoBuiltinAttributes(llvm::AttrBuilder & FuncAttrs,const LangOptions & LangOpts,const NoBuiltinAttr * NBA=nullptr)2139cfca06d7SDimitry Andric static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
2140cfca06d7SDimitry Andric                                    const LangOptions &LangOpts,
2141cfca06d7SDimitry Andric                                    const NoBuiltinAttr *NBA = nullptr) {
2142cfca06d7SDimitry Andric   auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
2143cfca06d7SDimitry Andric     SmallString<32> AttributeName;
2144cfca06d7SDimitry Andric     AttributeName += "no-builtin-";
2145cfca06d7SDimitry Andric     AttributeName += BuiltinName;
2146cfca06d7SDimitry Andric     FuncAttrs.addAttribute(AttributeName);
2147cfca06d7SDimitry Andric   };
2148cfca06d7SDimitry Andric 
2149cfca06d7SDimitry Andric   // First, handle the language options passed through -fno-builtin.
2150cfca06d7SDimitry Andric   if (LangOpts.NoBuiltin) {
2151cfca06d7SDimitry Andric     // -fno-builtin disables them all.
2152cfca06d7SDimitry Andric     FuncAttrs.addAttribute("no-builtins");
2153cfca06d7SDimitry Andric     return;
2154cfca06d7SDimitry Andric   }
2155cfca06d7SDimitry Andric 
2156cfca06d7SDimitry Andric   // Then, add attributes for builtins specified through -fno-builtin-<name>.
2157cfca06d7SDimitry Andric   llvm::for_each(LangOpts.NoBuiltinFuncs, AddNoBuiltinAttr);
2158cfca06d7SDimitry Andric 
2159cfca06d7SDimitry Andric   // Now, let's check the __attribute__((no_builtin("...")) attribute added to
2160cfca06d7SDimitry Andric   // the source.
2161cfca06d7SDimitry Andric   if (!NBA)
2162cfca06d7SDimitry Andric     return;
2163cfca06d7SDimitry Andric 
2164cfca06d7SDimitry Andric   // If there is a wildcard in the builtin names specified through the
2165cfca06d7SDimitry Andric   // attribute, disable them all.
2166cfca06d7SDimitry Andric   if (llvm::is_contained(NBA->builtinNames(), "*")) {
2167cfca06d7SDimitry Andric     FuncAttrs.addAttribute("no-builtins");
2168cfca06d7SDimitry Andric     return;
2169cfca06d7SDimitry Andric   }
2170cfca06d7SDimitry Andric 
2171cfca06d7SDimitry Andric   // And last, add the rest of the builtin names.
2172cfca06d7SDimitry Andric   llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
2173cfca06d7SDimitry Andric }
2174cfca06d7SDimitry Andric 
DetermineNoUndef(QualType QTy,CodeGenTypes & Types,const llvm::DataLayout & DL,const ABIArgInfo & AI,bool CheckCoerce=true)2175344a3780SDimitry Andric static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types,
2176344a3780SDimitry Andric                              const llvm::DataLayout &DL, const ABIArgInfo &AI,
2177344a3780SDimitry Andric                              bool CheckCoerce = true) {
2178344a3780SDimitry Andric   llvm::Type *Ty = Types.ConvertTypeForMem(QTy);
2179b1c73532SDimitry Andric   if (AI.getKind() == ABIArgInfo::Indirect ||
2180b1c73532SDimitry Andric       AI.getKind() == ABIArgInfo::IndirectAliased)
2181344a3780SDimitry Andric     return true;
2182344a3780SDimitry Andric   if (AI.getKind() == ABIArgInfo::Extend)
2183344a3780SDimitry Andric     return true;
2184344a3780SDimitry Andric   if (!DL.typeSizeEqualsStoreSize(Ty))
2185344a3780SDimitry Andric     // TODO: This will result in a modest amount of values not marked noundef
2186344a3780SDimitry Andric     // when they could be. We care about values that *invisibly* contain undef
2187344a3780SDimitry Andric     // bits from the perspective of LLVM IR.
2188344a3780SDimitry Andric     return false;
2189344a3780SDimitry Andric   if (CheckCoerce && AI.canHaveCoerceToType()) {
2190344a3780SDimitry Andric     llvm::Type *CoerceTy = AI.getCoerceToType();
2191344a3780SDimitry Andric     if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2192344a3780SDimitry Andric                                   DL.getTypeSizeInBits(Ty)))
2193344a3780SDimitry Andric       // If we're coercing to a type with a greater size than the canonical one,
2194344a3780SDimitry Andric       // we're introducing new undef bits.
2195344a3780SDimitry Andric       // Coercing to a type of smaller or equal size is ok, as we know that
2196344a3780SDimitry Andric       // there's no internal padding (typeSizeEqualsStoreSize).
2197344a3780SDimitry Andric       return false;
2198344a3780SDimitry Andric   }
219977fc4c14SDimitry Andric   if (QTy->isBitIntType())
2200344a3780SDimitry Andric     return true;
2201344a3780SDimitry Andric   if (QTy->isReferenceType())
2202344a3780SDimitry Andric     return true;
2203344a3780SDimitry Andric   if (QTy->isNullPtrType())
2204344a3780SDimitry Andric     return false;
2205344a3780SDimitry Andric   if (QTy->isMemberPointerType())
2206344a3780SDimitry Andric     // TODO: Some member pointers are `noundef`, but it depends on the ABI. For
2207344a3780SDimitry Andric     // now, never mark them.
2208344a3780SDimitry Andric     return false;
2209344a3780SDimitry Andric   if (QTy->isScalarType()) {
2210344a3780SDimitry Andric     if (const ComplexType *Complex = dyn_cast<ComplexType>(QTy))
2211344a3780SDimitry Andric       return DetermineNoUndef(Complex->getElementType(), Types, DL, AI, false);
2212344a3780SDimitry Andric     return true;
2213344a3780SDimitry Andric   }
2214344a3780SDimitry Andric   if (const VectorType *Vector = dyn_cast<VectorType>(QTy))
2215344a3780SDimitry Andric     return DetermineNoUndef(Vector->getElementType(), Types, DL, AI, false);
2216344a3780SDimitry Andric   if (const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2217344a3780SDimitry Andric     return DetermineNoUndef(Matrix->getElementType(), Types, DL, AI, false);
2218344a3780SDimitry Andric   if (const ArrayType *Array = dyn_cast<ArrayType>(QTy))
2219344a3780SDimitry Andric     return DetermineNoUndef(Array->getElementType(), Types, DL, AI, false);
2220344a3780SDimitry Andric 
2221344a3780SDimitry Andric   // TODO: Some structs may be `noundef`, in specific situations.
2222344a3780SDimitry Andric   return false;
2223344a3780SDimitry Andric }
2224344a3780SDimitry Andric 
2225e3b55780SDimitry Andric /// Check if the argument of a function has maybe_undef attribute.
IsArgumentMaybeUndef(const Decl * TargetDecl,unsigned NumRequiredArgs,unsigned ArgNo)2226e3b55780SDimitry Andric static bool IsArgumentMaybeUndef(const Decl *TargetDecl,
2227e3b55780SDimitry Andric                                  unsigned NumRequiredArgs, unsigned ArgNo) {
2228e3b55780SDimitry Andric   const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2229e3b55780SDimitry Andric   if (!FD)
2230e3b55780SDimitry Andric     return false;
2231e3b55780SDimitry Andric 
2232e3b55780SDimitry Andric   // Assume variadic arguments do not have maybe_undef attribute.
2233e3b55780SDimitry Andric   if (ArgNo >= NumRequiredArgs)
2234e3b55780SDimitry Andric     return false;
2235e3b55780SDimitry Andric 
2236e3b55780SDimitry Andric   // Check if argument has maybe_undef attribute.
2237e3b55780SDimitry Andric   if (ArgNo < FD->getNumParams()) {
2238e3b55780SDimitry Andric     const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2239e3b55780SDimitry Andric     if (Param && Param->hasAttr<MaybeUndefAttr>())
2240e3b55780SDimitry Andric       return true;
2241e3b55780SDimitry Andric   }
2242e3b55780SDimitry Andric 
2243e3b55780SDimitry Andric   return false;
2244e3b55780SDimitry Andric }
2245e3b55780SDimitry Andric 
22467fa27ce4SDimitry Andric /// Test if it's legal to apply nofpclass for the given parameter type and it's
22477fa27ce4SDimitry Andric /// lowered IR type.
canApplyNoFPClass(const ABIArgInfo & AI,QualType ParamType,bool IsReturn)22487fa27ce4SDimitry Andric static bool canApplyNoFPClass(const ABIArgInfo &AI, QualType ParamType,
22497fa27ce4SDimitry Andric                               bool IsReturn) {
22507fa27ce4SDimitry Andric   // Should only apply to FP types in the source, not ABI promoted.
22517fa27ce4SDimitry Andric   if (!ParamType->hasFloatingRepresentation())
22527fa27ce4SDimitry Andric     return false;
22537fa27ce4SDimitry Andric 
22547fa27ce4SDimitry Andric   // The promoted-to IR type also needs to support nofpclass.
22557fa27ce4SDimitry Andric   llvm::Type *IRTy = AI.getCoerceToType();
22567fa27ce4SDimitry Andric   if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
22577fa27ce4SDimitry Andric     return true;
22587fa27ce4SDimitry Andric 
22597fa27ce4SDimitry Andric   if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
22607fa27ce4SDimitry Andric     return !IsReturn && AI.getCanBeFlattened() &&
22617fa27ce4SDimitry Andric            llvm::all_of(ST->elements(), [](llvm::Type *Ty) {
22627fa27ce4SDimitry Andric              return llvm::AttributeFuncs::isNoFPClassCompatibleType(Ty);
22637fa27ce4SDimitry Andric            });
22647fa27ce4SDimitry Andric   }
22657fa27ce4SDimitry Andric 
22667fa27ce4SDimitry Andric   return false;
22677fa27ce4SDimitry Andric }
22687fa27ce4SDimitry Andric 
22697fa27ce4SDimitry Andric /// Return the nofpclass mask that can be applied to floating-point parameters.
getNoFPClassTestMask(const LangOptions & LangOpts)22707fa27ce4SDimitry Andric static llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts) {
22717fa27ce4SDimitry Andric   llvm::FPClassTest Mask = llvm::fcNone;
22727fa27ce4SDimitry Andric   if (LangOpts.NoHonorInfs)
22737fa27ce4SDimitry Andric     Mask |= llvm::fcInf;
22747fa27ce4SDimitry Andric   if (LangOpts.NoHonorNaNs)
22757fa27ce4SDimitry Andric     Mask |= llvm::fcNan;
22767fa27ce4SDimitry Andric   return Mask;
22777fa27ce4SDimitry Andric }
22787fa27ce4SDimitry Andric 
AdjustMemoryAttribute(StringRef Name,CGCalleeInfo CalleeInfo,llvm::AttributeList & Attrs)2279b1c73532SDimitry Andric void CodeGenModule::AdjustMemoryAttribute(StringRef Name,
2280b1c73532SDimitry Andric                                           CGCalleeInfo CalleeInfo,
2281b1c73532SDimitry Andric                                           llvm::AttributeList &Attrs) {
2282b1c73532SDimitry Andric   if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
2283b1c73532SDimitry Andric     Attrs = Attrs.removeFnAttribute(getLLVMContext(), llvm::Attribute::Memory);
2284b1c73532SDimitry Andric     llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
2285b1c73532SDimitry Andric         getLLVMContext(), llvm::MemoryEffects::writeOnly());
2286b1c73532SDimitry Andric     Attrs = Attrs.addFnAttribute(getLLVMContext(), MemoryAttr);
2287b1c73532SDimitry Andric   }
2288b1c73532SDimitry Andric }
2289b1c73532SDimitry Andric 
2290cfca06d7SDimitry Andric /// Construct the IR attribute list of a function or call.
2291cfca06d7SDimitry Andric ///
2292cfca06d7SDimitry Andric /// When adding an attribute, please consider where it should be handled:
2293cfca06d7SDimitry Andric ///
2294cfca06d7SDimitry Andric ///   - getDefaultFunctionAttributes is for attributes that are essentially
2295cfca06d7SDimitry Andric ///     part of the global target configuration (but perhaps can be
2296cfca06d7SDimitry Andric ///     overridden on a per-function basis).  Adding attributes there
2297cfca06d7SDimitry Andric ///     will cause them to also be set in frontends that build on Clang's
2298cfca06d7SDimitry Andric ///     target-configuration logic, as well as for code defined in library
2299cfca06d7SDimitry Andric ///     modules such as CUDA's libdevice.
2300cfca06d7SDimitry Andric ///
2301cfca06d7SDimitry Andric ///   - ConstructAttributeList builds on top of getDefaultFunctionAttributes
2302cfca06d7SDimitry Andric ///     and adds declaration-specific, convention-specific, and
2303cfca06d7SDimitry Andric ///     frontend-specific logic.  The last is of particular importance:
2304cfca06d7SDimitry Andric ///     attributes that restrict how the frontend generates code must be
2305cfca06d7SDimitry Andric ///     added here rather than getDefaultFunctionAttributes.
2306cfca06d7SDimitry Andric ///
ConstructAttributeList(StringRef Name,const CGFunctionInfo & FI,CGCalleeInfo CalleeInfo,llvm::AttributeList & AttrList,unsigned & CallingConv,bool AttrOnCallSite,bool IsThunk)2307344a3780SDimitry Andric void CodeGenModule::ConstructAttributeList(StringRef Name,
2308344a3780SDimitry Andric                                            const CGFunctionInfo &FI,
2309344a3780SDimitry Andric                                            CGCalleeInfo CalleeInfo,
2310344a3780SDimitry Andric                                            llvm::AttributeList &AttrList,
2311344a3780SDimitry Andric                                            unsigned &CallingConv,
2312344a3780SDimitry Andric                                            bool AttrOnCallSite, bool IsThunk) {
23136f8fc217SDimitry Andric   llvm::AttrBuilder FuncAttrs(getLLVMContext());
23146f8fc217SDimitry Andric   llvm::AttrBuilder RetAttrs(getLLVMContext());
2315ec2b103cSEd Schouten 
2316cfca06d7SDimitry Andric   // Collect function IR attributes from the CC lowering.
2317cfca06d7SDimitry Andric   // We'll collect the paramete and result attributes later.
23184c8b2481SRoman Divacky   CallingConv = FI.getEffectiveCallingConvention();
2319ecb7e5c8SRoman Divacky   if (FI.isNoReturn())
2320809500fcSDimitry Andric     FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2321cfca06d7SDimitry Andric   if (FI.isCmseNSCall())
2322cfca06d7SDimitry Andric     FuncAttrs.addAttribute("cmse_nonsecure_call");
2323ecb7e5c8SRoman Divacky 
2324cfca06d7SDimitry Andric   // Collect function IR attributes from the callee prototype if we have one.
232545b53394SDimitry Andric   AddAttributesFromFunctionProtoType(getContext(), FuncAttrs,
232645b53394SDimitry Andric                                      CalleeInfo.getCalleeFunctionProtoType());
232745b53394SDimitry Andric 
2328676fbe81SDimitry Andric   const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl();
232945b53394SDimitry Andric 
2330c0981da4SDimitry Andric   // Attach assumption attributes to the declaration. If this is a call
2331c0981da4SDimitry Andric   // site, attach assumptions from the caller to the call as well.
2332ac9a064cSDimitry Andric   AddAttributesFromOMPAssumes(FuncAttrs, TargetDecl);
2333c0981da4SDimitry Andric 
23347442d6faSDimitry Andric   bool HasOptnone = false;
2335cfca06d7SDimitry Andric   // The NoBuiltinAttr attached to the target FunctionDecl.
2336cfca06d7SDimitry Andric   const NoBuiltinAttr *NBA = nullptr;
2337cfca06d7SDimitry Andric 
2338e3b55780SDimitry Andric   // Some ABIs may result in additional accesses to arguments that may
2339e3b55780SDimitry Andric   // otherwise not be present.
2340e3b55780SDimitry Andric   auto AddPotentialArgAccess = [&]() {
2341e3b55780SDimitry Andric     llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2342e3b55780SDimitry Andric     if (A.isValid())
2343e3b55780SDimitry Andric       FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2344e3b55780SDimitry Andric                               llvm::MemoryEffects::argMemOnly());
2345e3b55780SDimitry Andric   };
2346e3b55780SDimitry Andric 
2347cfca06d7SDimitry Andric   // Collect function IR attributes based on declaration-specific
2348cfca06d7SDimitry Andric   // information.
2349ec2b103cSEd Schouten   // FIXME: handle sseregparm someday...
2350ec2b103cSEd Schouten   if (TargetDecl) {
235136981b17SDimitry Andric     if (TargetDecl->hasAttr<ReturnsTwiceAttr>())
2352809500fcSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
23535362a71cSEd Schouten     if (TargetDecl->hasAttr<NoThrowAttr>())
2354809500fcSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2355809500fcSDimitry Andric     if (TargetDecl->hasAttr<NoReturnAttr>())
2356809500fcSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2357325377b5SDimitry Andric     if (TargetDecl->hasAttr<ColdAttr>())
2358325377b5SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::Cold);
2359b60736ecSDimitry Andric     if (TargetDecl->hasAttr<HotAttr>())
2360b60736ecSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::Hot);
23619f4dbff6SDimitry Andric     if (TargetDecl->hasAttr<NoDuplicateAttr>())
23629f4dbff6SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
2363bab175ecSDimitry Andric     if (TargetDecl->hasAttr<ConvergentAttr>())
2364bab175ecSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::Convergent);
2365809500fcSDimitry Andric 
2366809500fcSDimitry Andric     if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
236745b53394SDimitry Andric       AddAttributesFromFunctionProtoType(
236845b53394SDimitry Andric           getContext(), FuncAttrs, Fn->getType()->getAs<FunctionProtoType>());
2369cfca06d7SDimitry Andric       if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
2370cfca06d7SDimitry Andric         // A sane operator new returns a non-aliasing pointer.
2371cfca06d7SDimitry Andric         auto Kind = Fn->getDeclName().getCXXOverloadedOperator();
2372cfca06d7SDimitry Andric         if (getCodeGenOpts().AssumeSaneOperatorNew &&
2373cfca06d7SDimitry Andric             (Kind == OO_New || Kind == OO_Array_New))
2374cfca06d7SDimitry Andric           RetAttrs.addAttribute(llvm::Attribute::NoAlias);
2375cfca06d7SDimitry Andric       }
2376809500fcSDimitry Andric       const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn);
2377706b4fc4SDimitry Andric       const bool IsVirtualCall = MD && MD->isVirtual();
2378706b4fc4SDimitry Andric       // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call to a
2379706b4fc4SDimitry Andric       // virtual function. These attributes are not inherited by overloads.
2380706b4fc4SDimitry Andric       if (!(AttrOnCallSite && IsVirtualCall)) {
2381706b4fc4SDimitry Andric         if (Fn->isNoReturn())
2382809500fcSDimitry Andric           FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
2383cfca06d7SDimitry Andric         NBA = Fn->getAttr<NoBuiltinAttr>();
2384706b4fc4SDimitry Andric       }
23857fa27ce4SDimitry Andric     }
23867fa27ce4SDimitry Andric 
23877fa27ce4SDimitry Andric     if (isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl)) {
2388b60736ecSDimitry Andric       // Only place nomerge attribute on call sites, never functions. This
2389b60736ecSDimitry Andric       // allows it to work on indirect virtual function calls.
2390b60736ecSDimitry Andric       if (AttrOnCallSite && TargetDecl->hasAttr<NoMergeAttr>())
2391b60736ecSDimitry Andric         FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
23924ba67500SRoman Divacky     }
23934ba67500SRoman Divacky 
239445b53394SDimitry Andric     // 'const', 'pure' and 'noalias' attributed functions are also nounwind.
239536981b17SDimitry Andric     if (TargetDecl->hasAttr<ConstAttr>()) {
2396e3b55780SDimitry Andric       FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
2397809500fcSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2398344a3780SDimitry Andric       // gcc specifies that 'const' functions have greater restrictions than
2399344a3780SDimitry Andric       // 'pure' functions, so they also cannot have infinite loops.
2400344a3780SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
240136981b17SDimitry Andric     } else if (TargetDecl->hasAttr<PureAttr>()) {
2402e3b55780SDimitry Andric       FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
2403809500fcSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2404344a3780SDimitry Andric       // gcc specifies that 'pure' functions cannot have infinite loops.
2405344a3780SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
240645b53394SDimitry Andric     } else if (TargetDecl->hasAttr<NoAliasAttr>()) {
2407b1c73532SDimitry Andric       FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
240845b53394SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
240936981b17SDimitry Andric     }
24105e20cdd8SDimitry Andric     if (TargetDecl->hasAttr<RestrictAttr>())
2411809500fcSDimitry Andric       RetAttrs.addAttribute(llvm::Attribute::NoAlias);
241248675466SDimitry Andric     if (TargetDecl->hasAttr<ReturnsNonNullAttr>() &&
241348675466SDimitry Andric         !CodeGenOpts.NullPointerIsValid)
24149f4dbff6SDimitry Andric       RetAttrs.addAttribute(llvm::Attribute::NonNull);
241557091882SDimitry Andric     if (TargetDecl->hasAttr<AnyX86NoCallerSavedRegistersAttr>())
241657091882SDimitry Andric       FuncAttrs.addAttribute("no_caller_saved_registers");
241748675466SDimitry Andric     if (TargetDecl->hasAttr<AnyX86NoCfCheckAttr>())
241848675466SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2419b60736ecSDimitry Andric     if (TargetDecl->hasAttr<LeafAttr>())
2420b60736ecSDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
242106d4ba38SDimitry Andric 
242206d4ba38SDimitry Andric     HasOptnone = TargetDecl->hasAttr<OptimizeNoneAttr>();
2423bab175ecSDimitry Andric     if (auto *AllocSize = TargetDecl->getAttr<AllocSizeAttr>()) {
2424e3b55780SDimitry Andric       std::optional<unsigned> NumElemsParam;
242548675466SDimitry Andric       if (AllocSize->getNumElemsParam().isValid())
242648675466SDimitry Andric         NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
242748675466SDimitry Andric       FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
2428bab175ecSDimitry Andric                                  NumElemsParam);
2429bab175ecSDimitry Andric     }
2430ec2b103cSEd Schouten 
2431cfca06d7SDimitry Andric     if (TargetDecl->hasAttr<OpenCLKernelAttr>()) {
243248675466SDimitry Andric       if (getLangOpts().OpenCLVersion <= 120) {
243348675466SDimitry Andric         // OpenCL v1.2 Work groups are always uniform
243448675466SDimitry Andric         FuncAttrs.addAttribute("uniform-work-group-size", "true");
243548675466SDimitry Andric       } else {
243648675466SDimitry Andric         // OpenCL v2.0 Work groups may be whether uniform or not.
243748675466SDimitry Andric         // '-cl-uniform-work-group-size' compile option gets a hint
243848675466SDimitry Andric         // to the compiler that the global work-size be a multiple of
243948675466SDimitry Andric         // the work-group size specified to clEnqueueNDRangeKernel
244048675466SDimitry Andric         // (i.e. work groups are uniform).
2441b1c73532SDimitry Andric         FuncAttrs.addAttribute(
2442b1c73532SDimitry Andric             "uniform-work-group-size",
2443b1c73532SDimitry Andric             llvm::toStringRef(getLangOpts().OffloadUniformBlock));
244448675466SDimitry Andric       }
244548675466SDimitry Andric     }
2446b1c73532SDimitry Andric 
2447b1c73532SDimitry Andric     if (TargetDecl->hasAttr<CUDAGlobalAttr>() &&
2448b1c73532SDimitry Andric         getLangOpts().OffloadUniformBlock)
2449b1c73532SDimitry Andric       FuncAttrs.addAttribute("uniform-work-group-size", "true");
2450b1c73532SDimitry Andric 
2451b1c73532SDimitry Andric     if (TargetDecl->hasAttr<ArmLocallyStreamingAttr>())
2452b1c73532SDimitry Andric       FuncAttrs.addAttribute("aarch64_pstate_sm_body");
2453cfca06d7SDimitry Andric   }
245448675466SDimitry Andric 
2455cfca06d7SDimitry Andric   // Attach "no-builtins" attributes to:
2456cfca06d7SDimitry Andric   // * call sites: both `nobuiltin` and "no-builtins" or "no-builtin-<name>".
2457cfca06d7SDimitry Andric   // * definitions: "no-builtins" or "no-builtin-<name>" only.
2458cfca06d7SDimitry Andric   // The attributes can come from:
2459cfca06d7SDimitry Andric   // * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name>
2460cfca06d7SDimitry Andric   // * FunctionDecl attributes: __attribute__((no_builtin(...)))
2461cfca06d7SDimitry Andric   addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
2462cfca06d7SDimitry Andric 
2463cfca06d7SDimitry Andric   // Collect function IR attributes based on global settiings.
2464cfca06d7SDimitry Andric   getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
2465cfca06d7SDimitry Andric 
2466cfca06d7SDimitry Andric   // Override some default IR attributes based on declaration-specific
2467cfca06d7SDimitry Andric   // information.
2468cfca06d7SDimitry Andric   if (TargetDecl) {
2469cfca06d7SDimitry Andric     if (TargetDecl->hasAttr<NoSpeculativeLoadHardeningAttr>())
2470cfca06d7SDimitry Andric       FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
2471cfca06d7SDimitry Andric     if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
2472cfca06d7SDimitry Andric       FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
2473cfca06d7SDimitry Andric     if (TargetDecl->hasAttr<NoSplitStackAttr>())
2474cfca06d7SDimitry Andric       FuncAttrs.removeAttribute("split-stack");
2475145449b1SDimitry Andric     if (TargetDecl->hasAttr<ZeroCallUsedRegsAttr>()) {
2476145449b1SDimitry Andric       // A function "__attribute__((...))" overrides the command-line flag.
2477145449b1SDimitry Andric       auto Kind =
2478145449b1SDimitry Andric           TargetDecl->getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
2479145449b1SDimitry Andric       FuncAttrs.removeAttribute("zero-call-used-regs");
2480145449b1SDimitry Andric       FuncAttrs.addAttribute(
2481145449b1SDimitry Andric           "zero-call-used-regs",
2482145449b1SDimitry Andric           ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
2483145449b1SDimitry Andric     }
2484cfca06d7SDimitry Andric 
2485cfca06d7SDimitry Andric     // Add NonLazyBind attribute to function declarations when -fno-plt
2486cfca06d7SDimitry Andric     // is used.
2487cfca06d7SDimitry Andric     // FIXME: what if we just haven't processed the function definition
2488cfca06d7SDimitry Andric     // yet, or if it's an external definition like C99 inline?
2489cfca06d7SDimitry Andric     if (CodeGenOpts.NoPLT) {
2490cfca06d7SDimitry Andric       if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
2491cfca06d7SDimitry Andric         if (!Fn->isDefined() && !AttrOnCallSite) {
2492cfca06d7SDimitry Andric           FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
2493cfca06d7SDimitry Andric         }
2494cfca06d7SDimitry Andric       }
2495cfca06d7SDimitry Andric     }
2496cfca06d7SDimitry Andric   }
2497cfca06d7SDimitry Andric 
2498344a3780SDimitry Andric   // Add "sample-profile-suffix-elision-policy" attribute for internal linkage
2499344a3780SDimitry Andric   // functions with -funique-internal-linkage-names.
2500344a3780SDimitry Andric   if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2501e3b55780SDimitry Andric     if (const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2502e3b55780SDimitry Andric       if (!FD->isExternallyVisible())
2503344a3780SDimitry Andric         FuncAttrs.addAttribute("sample-profile-suffix-elision-policy",
2504344a3780SDimitry Andric                                "selected");
2505344a3780SDimitry Andric     }
2506344a3780SDimitry Andric   }
2507344a3780SDimitry Andric 
2508cfca06d7SDimitry Andric   // Collect non-call-site function IR attributes from declaration-specific
2509cfca06d7SDimitry Andric   // information.
25107442d6faSDimitry Andric   if (!AttrOnCallSite) {
2511cfca06d7SDimitry Andric     if (TargetDecl && TargetDecl->hasAttr<CmseNSEntryAttr>())
2512cfca06d7SDimitry Andric       FuncAttrs.addAttribute("cmse_nonsecure_entry");
251348675466SDimitry Andric 
2514cfca06d7SDimitry Andric     // Whether tail calls are enabled.
2515cfca06d7SDimitry Andric     auto shouldDisableTailCalls = [&] {
2516cfca06d7SDimitry Andric       // Should this be honored in getDefaultFunctionAttributes?
251748675466SDimitry Andric       if (CodeGenOpts.DisableTailCalls)
2518cfca06d7SDimitry Andric         return true;
2519cfca06d7SDimitry Andric 
2520cfca06d7SDimitry Andric       if (!TargetDecl)
2521cfca06d7SDimitry Andric         return false;
2522cfca06d7SDimitry Andric 
252348675466SDimitry Andric       if (TargetDecl->hasAttr<DisableTailCallsAttr>() ||
252448675466SDimitry Andric           TargetDecl->hasAttr<AnyX86InterruptAttr>())
2525cfca06d7SDimitry Andric         return true;
2526cfca06d7SDimitry Andric 
2527cfca06d7SDimitry Andric       if (CodeGenOpts.NoEscapingBlockTailCalls) {
252848675466SDimitry Andric         if (const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
252948675466SDimitry Andric           if (!BD->doesNotEscape())
2530cfca06d7SDimitry Andric             return true;
253148675466SDimitry Andric       }
253248675466SDimitry Andric 
2533cfca06d7SDimitry Andric       return false;
2534cfca06d7SDimitry Andric     };
2535344a3780SDimitry Andric     if (shouldDisableTailCalls())
2536344a3780SDimitry Andric       FuncAttrs.addAttribute("disable-tail-calls", "true");
2537cfca06d7SDimitry Andric 
2538cfca06d7SDimitry Andric     // CPU/feature overrides.  addDefaultFunctionDefinitionAttributes
2539cfca06d7SDimitry Andric     // handles these separately to set them based on the global defaults.
2540676fbe81SDimitry Andric     GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
2541809500fcSDimitry Andric   }
254237f6c480SEd Schouten 
2543cfca06d7SDimitry Andric   // Collect attributes from arguments and return values.
254406d4ba38SDimitry Andric   ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI);
254506d4ba38SDimitry Andric 
2546ec2b103cSEd Schouten   QualType RetTy = FI.getReturnType();
2547ec2b103cSEd Schouten   const ABIArgInfo &RetAI = FI.getReturnInfo();
2548344a3780SDimitry Andric   const llvm::DataLayout &DL = getDataLayout();
2549344a3780SDimitry Andric 
2550344a3780SDimitry Andric   // Determine if the return type could be partially undef
2551e3b55780SDimitry Andric   if (CodeGenOpts.EnableNoundefAttrs &&
2552e3b55780SDimitry Andric       HasStrictReturn(*this, RetTy, TargetDecl)) {
2553344a3780SDimitry Andric     if (!RetTy->isVoidType() && RetAI.getKind() != ABIArgInfo::Indirect &&
2554344a3780SDimitry Andric         DetermineNoUndef(RetTy, getTypes(), DL, RetAI))
2555344a3780SDimitry Andric       RetAttrs.addAttribute(llvm::Attribute::NoUndef);
2556344a3780SDimitry Andric   }
2557344a3780SDimitry Andric 
2558ec2b103cSEd Schouten   switch (RetAI.getKind()) {
255970b4596dSEd Schouten   case ABIArgInfo::Extend:
256048675466SDimitry Andric     if (RetAI.isSignExt())
2561809500fcSDimitry Andric       RetAttrs.addAttribute(llvm::Attribute::SExt);
256248675466SDimitry Andric     else
2563809500fcSDimitry Andric       RetAttrs.addAttribute(llvm::Attribute::ZExt);
2564e3b55780SDimitry Andric     [[fallthrough]];
256570b4596dSEd Schouten   case ABIArgInfo::Direct:
2566bfef3995SDimitry Andric     if (RetAI.getInReg())
2567bfef3995SDimitry Andric       RetAttrs.addAttribute(llvm::Attribute::InReg);
25687fa27ce4SDimitry Andric 
25697fa27ce4SDimitry Andric     if (canApplyNoFPClass(RetAI, RetTy, true))
25707fa27ce4SDimitry Andric       RetAttrs.addNoFPClassAttr(getNoFPClassTestMask(getLangOpts()));
25717fa27ce4SDimitry Andric 
2572bfef3995SDimitry Andric     break;
25733d1dcd9bSDimitry Andric   case ABIArgInfo::Ignore:
2574ec2b103cSEd Schouten     break;
2575ec2b103cSEd Schouten 
257606d4ba38SDimitry Andric   case ABIArgInfo::InAlloca:
257756d91b49SDimitry Andric   case ABIArgInfo::Indirect: {
257806d4ba38SDimitry Andric     // inalloca and sret disable readnone and readonly
2579e3b55780SDimitry Andric     AddPotentialArgAccess();
2580ec2b103cSEd Schouten     break;
258156d91b49SDimitry Andric   }
2582ec2b103cSEd Schouten 
25832b6b257fSDimitry Andric   case ABIArgInfo::CoerceAndExpand:
25842b6b257fSDimitry Andric     break;
25852b6b257fSDimitry Andric 
2586ec2b103cSEd Schouten   case ABIArgInfo::Expand:
2587b60736ecSDimitry Andric   case ABIArgInfo::IndirectAliased:
258836981b17SDimitry Andric     llvm_unreachable("Invalid ABI kind for return argument");
2589ec2b103cSEd Schouten   }
2590ec2b103cSEd Schouten 
2591344a3780SDimitry Andric   if (!IsThunk) {
2592344a3780SDimitry Andric     // FIXME: fix this properly, https://reviews.llvm.org/D100388
25939f4dbff6SDimitry Andric     if (const auto *RefTy = RetTy->getAs<ReferenceType>()) {
25949f4dbff6SDimitry Andric       QualType PTy = RefTy->getPointeeType();
25959f4dbff6SDimitry Andric       if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
2596cfca06d7SDimitry Andric         RetAttrs.addDereferenceableAttr(
2597cfca06d7SDimitry Andric             getMinimumObjectSize(PTy).getQuantity());
2598e3b55780SDimitry Andric       if (getTypes().getTargetAddressSpace(PTy) == 0 &&
259948675466SDimitry Andric           !CodeGenOpts.NullPointerIsValid)
26009f4dbff6SDimitry Andric         RetAttrs.addAttribute(llvm::Attribute::NonNull);
2601cfca06d7SDimitry Andric       if (PTy->isObjectType()) {
2602cfca06d7SDimitry Andric         llvm::Align Alignment =
2603cfca06d7SDimitry Andric             getNaturalPointeeTypeAlignment(RetTy).getAsAlign();
2604cfca06d7SDimitry Andric         RetAttrs.addAlignmentAttr(Alignment);
2605cfca06d7SDimitry Andric       }
26069f4dbff6SDimitry Andric     }
2607344a3780SDimitry Andric   }
26089f4dbff6SDimitry Andric 
26092b6b257fSDimitry Andric   bool hasUsedSRet = false;
2610583e75ccSDimitry Andric   SmallVector<llvm::AttributeSet, 4> ArgAttrs(IRFunctionArgs.totalIRArgs());
26112b6b257fSDimitry Andric 
261206d4ba38SDimitry Andric   // Attach attributes to sret.
261306d4ba38SDimitry Andric   if (IRFunctionArgs.hasSRetArg()) {
26146f8fc217SDimitry Andric     llvm::AttrBuilder SRETAttrs(getLLVMContext());
2615b60736ecSDimitry Andric     SRETAttrs.addStructRetAttr(getTypes().ConvertTypeForMem(RetTy));
2616950076cdSDimitry Andric     SRETAttrs.addAttribute(llvm::Attribute::Writable);
2617950076cdSDimitry Andric     SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
26182b6b257fSDimitry Andric     hasUsedSRet = true;
261906d4ba38SDimitry Andric     if (RetAI.getInReg())
262006d4ba38SDimitry Andric       SRETAttrs.addAttribute(llvm::Attribute::InReg);
2621cfca06d7SDimitry Andric     SRETAttrs.addAlignmentAttr(RetAI.getIndirectAlign().getQuantity());
2622583e75ccSDimitry Andric     ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
2623583e75ccSDimitry Andric         llvm::AttributeSet::get(getLLVMContext(), SRETAttrs);
262406d4ba38SDimitry Andric   }
262506d4ba38SDimitry Andric 
262606d4ba38SDimitry Andric   // Attach attributes to inalloca argument.
262706d4ba38SDimitry Andric   if (IRFunctionArgs.hasInallocaArg()) {
26286f8fc217SDimitry Andric     llvm::AttrBuilder Attrs(getLLVMContext());
2629344a3780SDimitry Andric     Attrs.addInAllocaAttr(FI.getArgStruct());
2630583e75ccSDimitry Andric     ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
2631583e75ccSDimitry Andric         llvm::AttributeSet::get(getLLVMContext(), Attrs);
263206d4ba38SDimitry Andric   }
263306d4ba38SDimitry Andric 
2634344a3780SDimitry Andric   // Apply `nonnull`, `dereferencable(N)` and `align N` to the `this` argument,
2635344a3780SDimitry Andric   // unless this is a thunk function.
2636344a3780SDimitry Andric   // FIXME: fix this properly, https://reviews.llvm.org/D100388
2637b60736ecSDimitry Andric   if (FI.isInstanceMethod() && !IRFunctionArgs.hasInallocaArg() &&
2638344a3780SDimitry Andric       !FI.arg_begin()->type->isVoidPointerType() && !IsThunk) {
2639b60736ecSDimitry Andric     auto IRArgs = IRFunctionArgs.getIRArgs(0);
2640b60736ecSDimitry Andric 
2641b60736ecSDimitry Andric     assert(IRArgs.second == 1 && "Expected only a single `this` pointer.");
2642b60736ecSDimitry Andric 
26436f8fc217SDimitry Andric     llvm::AttrBuilder Attrs(getLLVMContext());
2644b60736ecSDimitry Andric 
2645344a3780SDimitry Andric     QualType ThisTy =
2646b1c73532SDimitry Andric         FI.arg_begin()->type.getTypePtr()->getPointeeType();
2647344a3780SDimitry Andric 
2648b60736ecSDimitry Andric     if (!CodeGenOpts.NullPointerIsValid &&
2649e3b55780SDimitry Andric         getTypes().getTargetAddressSpace(FI.arg_begin()->type) == 0) {
2650b60736ecSDimitry Andric       Attrs.addAttribute(llvm::Attribute::NonNull);
2651344a3780SDimitry Andric       Attrs.addDereferenceableAttr(getMinimumObjectSize(ThisTy).getQuantity());
2652b60736ecSDimitry Andric     } else {
2653b60736ecSDimitry Andric       // FIXME dereferenceable should be correct here, regardless of
2654b60736ecSDimitry Andric       // NullPointerIsValid. However, dereferenceable currently does not always
2655b60736ecSDimitry Andric       // respect NullPointerIsValid and may imply nonnull and break the program.
2656b60736ecSDimitry Andric       // See https://reviews.llvm.org/D66618 for discussions.
2657b60736ecSDimitry Andric       Attrs.addDereferenceableOrNullAttr(
2658b60736ecSDimitry Andric           getMinimumObjectSize(
2659b60736ecSDimitry Andric               FI.arg_begin()->type.castAs<PointerType>()->getPointeeType())
2660b60736ecSDimitry Andric               .getQuantity());
2661b60736ecSDimitry Andric     }
2662b60736ecSDimitry Andric 
2663344a3780SDimitry Andric     llvm::Align Alignment =
2664344a3780SDimitry Andric         getNaturalTypeAlignment(ThisTy, /*BaseInfo=*/nullptr,
2665344a3780SDimitry Andric                                 /*TBAAInfo=*/nullptr, /*forPointeeType=*/true)
2666344a3780SDimitry Andric             .getAsAlign();
2667344a3780SDimitry Andric     Attrs.addAlignmentAttr(Alignment);
2668344a3780SDimitry Andric 
2669b60736ecSDimitry Andric     ArgAttrs[IRArgs.first] = llvm::AttributeSet::get(getLLVMContext(), Attrs);
2670b60736ecSDimitry Andric   }
2671b60736ecSDimitry Andric 
267206d4ba38SDimitry Andric   unsigned ArgNo = 0;
267306d4ba38SDimitry Andric   for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(),
267406d4ba38SDimitry Andric                                           E = FI.arg_end();
267506d4ba38SDimitry Andric        I != E; ++I, ++ArgNo) {
267606d4ba38SDimitry Andric     QualType ParamType = I->type;
267706d4ba38SDimitry Andric     const ABIArgInfo &AI = I->info;
26786f8fc217SDimitry Andric     llvm::AttrBuilder Attrs(getLLVMContext());
267913cc256eSDimitry Andric 
268006d4ba38SDimitry Andric     // Add attribute for padding argument, if necessary.
268106d4ba38SDimitry Andric     if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
2682583e75ccSDimitry Andric       if (AI.getPaddingInReg()) {
2683583e75ccSDimitry Andric         ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
2684583e75ccSDimitry Andric             llvm::AttributeSet::get(
2685583e75ccSDimitry Andric                 getLLVMContext(),
26866f8fc217SDimitry Andric                 llvm::AttrBuilder(getLLVMContext()).addAttribute(llvm::Attribute::InReg));
2687583e75ccSDimitry Andric       }
268813cc256eSDimitry Andric     }
2689ec2b103cSEd Schouten 
2690344a3780SDimitry Andric     // Decide whether the argument we're handling could be partially undef
2691145449b1SDimitry Andric     if (CodeGenOpts.EnableNoundefAttrs &&
26926f8fc217SDimitry Andric         DetermineNoUndef(ParamType, getTypes(), DL, AI)) {
2693344a3780SDimitry Andric       Attrs.addAttribute(llvm::Attribute::NoUndef);
26946f8fc217SDimitry Andric     }
2695344a3780SDimitry Andric 
269611d2b2d2SRoman Divacky     // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
269711d2b2d2SRoman Divacky     // have the corresponding parameter variable.  It doesn't make
2698bca07a45SDimitry Andric     // sense to do it here because parameters are so messed up.
2699ec2b103cSEd Schouten     switch (AI.getKind()) {
27003d1dcd9bSDimitry Andric     case ABIArgInfo::Extend:
270148675466SDimitry Andric       if (AI.isSignExt())
27025e20cdd8SDimitry Andric         Attrs.addAttribute(llvm::Attribute::SExt);
27035e20cdd8SDimitry Andric       else
2704809500fcSDimitry Andric         Attrs.addAttribute(llvm::Attribute::ZExt);
2705e3b55780SDimitry Andric       [[fallthrough]];
270606d4ba38SDimitry Andric     case ABIArgInfo::Direct:
270706d4ba38SDimitry Andric       if (ArgNo == 0 && FI.isChainCall())
270806d4ba38SDimitry Andric         Attrs.addAttribute(llvm::Attribute::Nest);
270906d4ba38SDimitry Andric       else if (AI.getInReg())
2710809500fcSDimitry Andric         Attrs.addAttribute(llvm::Attribute::InReg);
2711344a3780SDimitry Andric       Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.getDirectAlign()));
271206d4ba38SDimitry Andric 
27137fa27ce4SDimitry Andric       if (canApplyNoFPClass(AI, ParamType, false))
27147fa27ce4SDimitry Andric         Attrs.addNoFPClassAttr(getNoFPClassTestMask(getLangOpts()));
27157fa27ce4SDimitry Andric       break;
271645b53394SDimitry Andric     case ABIArgInfo::Indirect: {
271713cc256eSDimitry Andric       if (AI.getInReg())
2718809500fcSDimitry Andric         Attrs.addAttribute(llvm::Attribute::InReg);
27194c8b2481SRoman Divacky 
272013cc256eSDimitry Andric       if (AI.getIndirectByVal())
272122989816SDimitry Andric         Attrs.addByValAttr(getTypes().ConvertTypeForMem(ParamType));
272213cc256eSDimitry Andric 
2723b60736ecSDimitry Andric       auto *Decl = ParamType->getAsRecordDecl();
2724b60736ecSDimitry Andric       if (CodeGenOpts.PassByValueIsNoAlias && Decl &&
2725b1c73532SDimitry Andric           Decl->getArgPassingRestrictions() ==
2726b1c73532SDimitry Andric               RecordArgPassingKind::CanPassInRegs)
2727b60736ecSDimitry Andric         // When calling the function, the pointer passed in will be the only
2728b60736ecSDimitry Andric         // reference to the underlying object. Mark it accordingly.
2729b60736ecSDimitry Andric         Attrs.addAttribute(llvm::Attribute::NoAlias);
2730b60736ecSDimitry Andric 
2731b60736ecSDimitry Andric       // TODO: We could add the byref attribute if not byval, but it would
2732b60736ecSDimitry Andric       // require updating many testcases.
2733b60736ecSDimitry Andric 
273445b53394SDimitry Andric       CharUnits Align = AI.getIndirectAlign();
273545b53394SDimitry Andric 
273645b53394SDimitry Andric       // In a byval argument, it is important that the required
273745b53394SDimitry Andric       // alignment of the type is honored, as LLVM might be creating a
273845b53394SDimitry Andric       // *new* stack object, and needs to know what alignment to give
273945b53394SDimitry Andric       // it. (Sometimes it can deduce a sensible alignment on its own,
274045b53394SDimitry Andric       // but not if clang decides it must emit a packed struct, or the
274145b53394SDimitry Andric       // user specifies increased alignment requirements.)
274245b53394SDimitry Andric       //
274345b53394SDimitry Andric       // This is different from indirect *not* byval, where the object
274445b53394SDimitry Andric       // exists already, and the align attribute is purely
274545b53394SDimitry Andric       // informative.
274645b53394SDimitry Andric       assert(!Align.isZero());
274745b53394SDimitry Andric 
274845b53394SDimitry Andric       // For now, only add this when we have a byval argument.
274945b53394SDimitry Andric       // TODO: be less lazy about updating test cases.
275045b53394SDimitry Andric       if (AI.getIndirectByVal())
275145b53394SDimitry Andric         Attrs.addAlignmentAttr(Align.getQuantity());
275213cc256eSDimitry Andric 
2753ec2b103cSEd Schouten       // byval disables readnone and readonly.
2754e3b55780SDimitry Andric       AddPotentialArgAccess();
2755b60736ecSDimitry Andric       break;
2756b60736ecSDimitry Andric     }
2757b60736ecSDimitry Andric     case ABIArgInfo::IndirectAliased: {
2758b60736ecSDimitry Andric       CharUnits Align = AI.getIndirectAlign();
2759b60736ecSDimitry Andric       Attrs.addByRefAttr(getTypes().ConvertTypeForMem(ParamType));
2760b60736ecSDimitry Andric       Attrs.addAlignmentAttr(Align.getQuantity());
2761ec2b103cSEd Schouten       break;
276245b53394SDimitry Andric     }
2763ec2b103cSEd Schouten     case ABIArgInfo::Ignore:
276406d4ba38SDimitry Andric     case ABIArgInfo::Expand:
27652b6b257fSDimitry Andric     case ABIArgInfo::CoerceAndExpand:
27662b6b257fSDimitry Andric       break;
2767ec2b103cSEd Schouten 
27689f4dbff6SDimitry Andric     case ABIArgInfo::InAlloca:
27699f4dbff6SDimitry Andric       // inalloca disables readnone and readonly.
2770e3b55780SDimitry Andric       AddPotentialArgAccess();
27719f4dbff6SDimitry Andric       continue;
2772ec2b103cSEd Schouten     }
2773ec2b103cSEd Schouten 
27749f4dbff6SDimitry Andric     if (const auto *RefTy = ParamType->getAs<ReferenceType>()) {
27759f4dbff6SDimitry Andric       QualType PTy = RefTy->getPointeeType();
27769f4dbff6SDimitry Andric       if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
2777cfca06d7SDimitry Andric         Attrs.addDereferenceableAttr(
2778cfca06d7SDimitry Andric             getMinimumObjectSize(PTy).getQuantity());
2779e3b55780SDimitry Andric       if (getTypes().getTargetAddressSpace(PTy) == 0 &&
278048675466SDimitry Andric           !CodeGenOpts.NullPointerIsValid)
27819f4dbff6SDimitry Andric         Attrs.addAttribute(llvm::Attribute::NonNull);
2782cfca06d7SDimitry Andric       if (PTy->isObjectType()) {
2783cfca06d7SDimitry Andric         llvm::Align Alignment =
2784cfca06d7SDimitry Andric             getNaturalPointeeTypeAlignment(ParamType).getAsAlign();
2785cfca06d7SDimitry Andric         Attrs.addAlignmentAttr(Alignment);
2786cfca06d7SDimitry Andric       }
27879f4dbff6SDimitry Andric     }
27889f4dbff6SDimitry Andric 
2789145449b1SDimitry Andric     // From OpenCL spec v3.0.10 section 6.3.5 Alignment of Types:
2790145449b1SDimitry Andric     // > For arguments to a __kernel function declared to be a pointer to a
2791145449b1SDimitry Andric     // > data type, the OpenCL compiler can assume that the pointee is always
2792145449b1SDimitry Andric     // > appropriately aligned as required by the data type.
2793145449b1SDimitry Andric     if (TargetDecl && TargetDecl->hasAttr<OpenCLKernelAttr>() &&
2794145449b1SDimitry Andric         ParamType->isPointerType()) {
2795145449b1SDimitry Andric       QualType PTy = ParamType->getPointeeType();
2796145449b1SDimitry Andric       if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
2797145449b1SDimitry Andric         llvm::Align Alignment =
2798145449b1SDimitry Andric             getNaturalPointeeTypeAlignment(ParamType).getAsAlign();
2799145449b1SDimitry Andric         Attrs.addAlignmentAttr(Alignment);
2800145449b1SDimitry Andric       }
2801145449b1SDimitry Andric     }
2802145449b1SDimitry Andric 
28032b6b257fSDimitry Andric     switch (FI.getExtParameterInfo(ArgNo).getABI()) {
28042b6b257fSDimitry Andric     case ParameterABI::Ordinary:
28052b6b257fSDimitry Andric       break;
28062b6b257fSDimitry Andric 
28072b6b257fSDimitry Andric     case ParameterABI::SwiftIndirectResult: {
28082b6b257fSDimitry Andric       // Add 'sret' if we haven't already used it for something, but
28092b6b257fSDimitry Andric       // only if the result is void.
28102b6b257fSDimitry Andric       if (!hasUsedSRet && RetTy->isVoidType()) {
2811b60736ecSDimitry Andric         Attrs.addStructRetAttr(getTypes().ConvertTypeForMem(ParamType));
28122b6b257fSDimitry Andric         hasUsedSRet = true;
28132b6b257fSDimitry Andric       }
28142b6b257fSDimitry Andric 
28152b6b257fSDimitry Andric       // Add 'noalias' in either case.
28162b6b257fSDimitry Andric       Attrs.addAttribute(llvm::Attribute::NoAlias);
28172b6b257fSDimitry Andric 
28182b6b257fSDimitry Andric       // Add 'dereferenceable' and 'alignment'.
28192b6b257fSDimitry Andric       auto PTy = ParamType->getPointeeType();
28202b6b257fSDimitry Andric       if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
28212b6b257fSDimitry Andric         auto info = getContext().getTypeInfoInChars(PTy);
2822b60736ecSDimitry Andric         Attrs.addDereferenceableAttr(info.Width.getQuantity());
2823b60736ecSDimitry Andric         Attrs.addAlignmentAttr(info.Align.getAsAlign());
28242b6b257fSDimitry Andric       }
28252b6b257fSDimitry Andric       break;
28262b6b257fSDimitry Andric     }
28272b6b257fSDimitry Andric 
28282b6b257fSDimitry Andric     case ParameterABI::SwiftErrorResult:
28292b6b257fSDimitry Andric       Attrs.addAttribute(llvm::Attribute::SwiftError);
28302b6b257fSDimitry Andric       break;
28312b6b257fSDimitry Andric 
28322b6b257fSDimitry Andric     case ParameterABI::SwiftContext:
28332b6b257fSDimitry Andric       Attrs.addAttribute(llvm::Attribute::SwiftSelf);
28342b6b257fSDimitry Andric       break;
2835344a3780SDimitry Andric 
2836344a3780SDimitry Andric     case ParameterABI::SwiftAsyncContext:
2837344a3780SDimitry Andric       Attrs.addAttribute(llvm::Attribute::SwiftAsync);
2838344a3780SDimitry Andric       break;
28392b6b257fSDimitry Andric     }
28402b6b257fSDimitry Andric 
2841461a67faSDimitry Andric     if (FI.getExtParameterInfo(ArgNo).isNoEscape())
2842461a67faSDimitry Andric       Attrs.addAttribute(llvm::Attribute::NoCapture);
2843461a67faSDimitry Andric 
284406d4ba38SDimitry Andric     if (Attrs.hasAttributes()) {
284506d4ba38SDimitry Andric       unsigned FirstIRArg, NumIRArgs;
284606d4ba38SDimitry Andric       std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
284706d4ba38SDimitry Andric       for (unsigned i = 0; i < NumIRArgs; i++)
28486f8fc217SDimitry Andric         ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes(
28496f8fc217SDimitry Andric             getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), Attrs));
2850ec2b103cSEd Schouten     }
28519f4dbff6SDimitry Andric   }
285206d4ba38SDimitry Andric   assert(ArgNo == FI.arg_size());
28539f4dbff6SDimitry Andric 
2854583e75ccSDimitry Andric   AttrList = llvm::AttributeList::get(
2855583e75ccSDimitry Andric       getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), FuncAttrs),
2856583e75ccSDimitry Andric       llvm::AttributeSet::get(getLLVMContext(), RetAttrs), ArgAttrs);
2857ec2b103cSEd Schouten }
2858ec2b103cSEd Schouten 
285901af97d3SDimitry Andric /// An argument came in as a promoted argument; demote it back to its
286001af97d3SDimitry Andric /// declared type.
emitArgumentDemotion(CodeGenFunction & CGF,const VarDecl * var,llvm::Value * value)286101af97d3SDimitry Andric static llvm::Value *emitArgumentDemotion(CodeGenFunction &CGF,
286201af97d3SDimitry Andric                                          const VarDecl *var,
286301af97d3SDimitry Andric                                          llvm::Value *value) {
286436981b17SDimitry Andric   llvm::Type *varType = CGF.ConvertType(var->getType());
286501af97d3SDimitry Andric 
286601af97d3SDimitry Andric   // This can happen with promotions that actually don't change the
286701af97d3SDimitry Andric   // underlying type, like the enum promotions.
286801af97d3SDimitry Andric   if (value->getType() == varType) return value;
286901af97d3SDimitry Andric 
287001af97d3SDimitry Andric   assert((varType->isIntegerTy() || varType->isFloatingPointTy())
287101af97d3SDimitry Andric          && "unexpected promotion type");
287201af97d3SDimitry Andric 
287301af97d3SDimitry Andric   if (isa<llvm::IntegerType>(varType))
287401af97d3SDimitry Andric     return CGF.Builder.CreateTrunc(value, varType, "arg.unpromote");
287501af97d3SDimitry Andric 
287601af97d3SDimitry Andric   return CGF.Builder.CreateFPCast(value, varType, "arg.unpromote");
287701af97d3SDimitry Andric }
287801af97d3SDimitry Andric 
287906d4ba38SDimitry Andric /// Returns the attribute (either parameter attribute, or function
288006d4ba38SDimitry Andric /// attribute), which declares argument ArgNo to be non-null.
getNonNullAttr(const Decl * FD,const ParmVarDecl * PVD,QualType ArgType,unsigned ArgNo)288106d4ba38SDimitry Andric static const NonNullAttr *getNonNullAttr(const Decl *FD, const ParmVarDecl *PVD,
288206d4ba38SDimitry Andric                                          QualType ArgType, unsigned ArgNo) {
288306d4ba38SDimitry Andric   // FIXME: __attribute__((nonnull)) can also be applied to:
288406d4ba38SDimitry Andric   //   - references to pointers, where the pointee is known to be
288506d4ba38SDimitry Andric   //     nonnull (apparently a Clang extension)
288606d4ba38SDimitry Andric   //   - transparent unions containing pointers
288706d4ba38SDimitry Andric   // In the former case, LLVM IR cannot represent the constraint. In
288806d4ba38SDimitry Andric   // the latter case, we have no guarantee that the transparent union
288906d4ba38SDimitry Andric   // is in fact passed as a pointer.
289006d4ba38SDimitry Andric   if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType())
289106d4ba38SDimitry Andric     return nullptr;
289206d4ba38SDimitry Andric   // First, check attribute on parameter itself.
289306d4ba38SDimitry Andric   if (PVD) {
289406d4ba38SDimitry Andric     if (auto ParmNNAttr = PVD->getAttr<NonNullAttr>())
289506d4ba38SDimitry Andric       return ParmNNAttr;
289606d4ba38SDimitry Andric   }
289706d4ba38SDimitry Andric   // Check function attributes.
289806d4ba38SDimitry Andric   if (!FD)
289906d4ba38SDimitry Andric     return nullptr;
290006d4ba38SDimitry Andric   for (const auto *NNAttr : FD->specific_attrs<NonNullAttr>()) {
290106d4ba38SDimitry Andric     if (NNAttr->isNonNull(ArgNo))
290206d4ba38SDimitry Andric       return NNAttr;
290306d4ba38SDimitry Andric   }
290406d4ba38SDimitry Andric   return nullptr;
290506d4ba38SDimitry Andric }
290606d4ba38SDimitry Andric 
29072b6b257fSDimitry Andric namespace {
29082b6b257fSDimitry Andric   struct CopyBackSwiftError final : EHScopeStack::Cleanup {
29092b6b257fSDimitry Andric     Address Temp;
29102b6b257fSDimitry Andric     Address Arg;
CopyBackSwiftError__anon748148590b11::CopyBackSwiftError29112b6b257fSDimitry Andric     CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(arg) {}
Emit__anon748148590b11::CopyBackSwiftError29122b6b257fSDimitry Andric     void Emit(CodeGenFunction &CGF, Flags flags) override {
29132b6b257fSDimitry Andric       llvm::Value *errorValue = CGF.Builder.CreateLoad(Temp);
29142b6b257fSDimitry Andric       CGF.Builder.CreateStore(errorValue, Arg);
29152b6b257fSDimitry Andric     }
29162b6b257fSDimitry Andric   };
29172b6b257fSDimitry Andric }
29182b6b257fSDimitry Andric 
EmitFunctionProlog(const CGFunctionInfo & FI,llvm::Function * Fn,const FunctionArgList & Args)2919ec2b103cSEd Schouten void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
2920ec2b103cSEd Schouten                                          llvm::Function *Fn,
2921ec2b103cSEd Schouten                                          const FunctionArgList &Args) {
292206d4ba38SDimitry Andric   if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>())
292306d4ba38SDimitry Andric     // Naked functions don't have prologues.
292406d4ba38SDimitry Andric     return;
292506d4ba38SDimitry Andric 
29264c8b2481SRoman Divacky   // If this is an implicit-return-zero function, go ahead and
29274c8b2481SRoman Divacky   // initialize the return value.  TODO: it might be nice to have
29284c8b2481SRoman Divacky   // a more general mechanism for this that didn't require synthesized
29294c8b2481SRoman Divacky   // return statements.
29306a037251SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl)) {
29314c8b2481SRoman Divacky     if (FD->hasImplicitReturnZero()) {
29329f4dbff6SDimitry Andric       QualType RetTy = FD->getReturnType().getUnqualifiedType();
293336981b17SDimitry Andric       llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy);
29344c8b2481SRoman Divacky       llvm::Constant* Zero = llvm::Constant::getNullValue(LLVMTy);
29354c8b2481SRoman Divacky       Builder.CreateStore(Zero, ReturnValue);
29364c8b2481SRoman Divacky     }
29374c8b2481SRoman Divacky   }
29384c8b2481SRoman Divacky 
2939ec2b103cSEd Schouten   // FIXME: We no longer need the types from FunctionArgList; lift up and
2940ec2b103cSEd Schouten   // simplify.
2941ec2b103cSEd Schouten 
294206d4ba38SDimitry Andric   ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), FI);
2943cfca06d7SDimitry Andric   assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
2944ec2b103cSEd Schouten 
29459f4dbff6SDimitry Andric   // If we're using inalloca, all the memory arguments are GEPs off of the last
29469f4dbff6SDimitry Andric   // parameter, which is a pointer to the complete memory area.
294745b53394SDimitry Andric   Address ArgStruct = Address::invalid();
29487fa27ce4SDimitry Andric   if (IRFunctionArgs.hasInallocaArg())
2949cfca06d7SDimitry Andric     ArgStruct = Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
2950145449b1SDimitry Andric                         FI.getArgStruct(), FI.getArgStructAlignment());
295145b53394SDimitry Andric 
295206d4ba38SDimitry Andric   // Name the struct return parameter.
295306d4ba38SDimitry Andric   if (IRFunctionArgs.hasSRetArg()) {
2954cfca06d7SDimitry Andric     auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
29559f4dbff6SDimitry Andric     AI->setName("agg.result");
2956583e75ccSDimitry Andric     AI->addAttr(llvm::Attribute::NoAlias);
29579f4dbff6SDimitry Andric   }
29589f4dbff6SDimitry Andric 
29599f4dbff6SDimitry Andric   // Track if we received the parameter as a pointer (indirect, byval, or
29609f4dbff6SDimitry Andric   // inalloca).  If already have a pointer, EmitParmDecl doesn't need to copy it
29619f4dbff6SDimitry Andric   // into a local alloca for us.
296245b53394SDimitry Andric   SmallVector<ParamValue, 16> ArgVals;
29639f4dbff6SDimitry Andric   ArgVals.reserve(Args.size());
29649f4dbff6SDimitry Andric 
29659f4dbff6SDimitry Andric   // Create a pointer value for every parameter declaration.  This usually
29669f4dbff6SDimitry Andric   // entails copying one or more LLVM IR arguments into an alloca.  Don't push
29679f4dbff6SDimitry Andric   // any cleanups or do anything that might unwind.  We do that separately, so
29689f4dbff6SDimitry Andric   // we can push the cleanups in the correct order for the ABI.
2969ec2b103cSEd Schouten   assert(FI.arg_size() == Args.size() &&
2970ec2b103cSEd Schouten          "Mismatch between function signature & arguments.");
297106d4ba38SDimitry Andric   unsigned ArgNo = 0;
2972ec2b103cSEd Schouten   CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin();
2973ec2b103cSEd Schouten   for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
297401af97d3SDimitry Andric        i != e; ++i, ++info_it, ++ArgNo) {
297501af97d3SDimitry Andric     const VarDecl *Arg = *i;
2976ec2b103cSEd Schouten     const ABIArgInfo &ArgI = info_it->info;
2977ec2b103cSEd Schouten 
297801af97d3SDimitry Andric     bool isPromoted =
297901af97d3SDimitry Andric       isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
298048675466SDimitry Andric     // We are converting from ABIArgInfo type to VarDecl type directly, unless
298148675466SDimitry Andric     // the parameter is promoted. In this case we convert to
298248675466SDimitry Andric     // CGFunctionInfo::ArgInfo type with subsequent argument demotion.
298348675466SDimitry Andric     QualType Ty = isPromoted ? info_it->type : Arg->getType();
298448675466SDimitry Andric     assert(hasScalarEvaluationKind(Ty) ==
298548675466SDimitry Andric            hasScalarEvaluationKind(Arg->getType()));
298601af97d3SDimitry Andric 
298706d4ba38SDimitry Andric     unsigned FirstIRArg, NumIRArgs;
298806d4ba38SDimitry Andric     std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
298913cc256eSDimitry Andric 
2990ec2b103cSEd Schouten     switch (ArgI.getKind()) {
29919f4dbff6SDimitry Andric     case ABIArgInfo::InAlloca: {
299206d4ba38SDimitry Andric       assert(NumIRArgs == 0);
299345b53394SDimitry Andric       auto FieldIndex = ArgI.getInAllocaFieldIndex();
299422989816SDimitry Andric       Address V =
299522989816SDimitry Andric           Builder.CreateStructGEP(ArgStruct, FieldIndex, Arg->getName());
2996cfca06d7SDimitry Andric       if (ArgI.getInAllocaIndirect())
2997145449b1SDimitry Andric         V = Address(Builder.CreateLoad(V), ConvertTypeForMem(Ty),
2998cfca06d7SDimitry Andric                     getContext().getTypeAlignInChars(Ty));
299945b53394SDimitry Andric       ArgVals.push_back(ParamValue::forIndirect(V));
300006d4ba38SDimitry Andric       break;
30019f4dbff6SDimitry Andric     }
30029f4dbff6SDimitry Andric 
3003b60736ecSDimitry Andric     case ABIArgInfo::Indirect:
3004b60736ecSDimitry Andric     case ABIArgInfo::IndirectAliased: {
300506d4ba38SDimitry Andric       assert(NumIRArgs == 1);
3006ac9a064cSDimitry Andric       Address ParamAddr = makeNaturalAddressForPointer(
3007ac9a064cSDimitry Andric           Fn->getArg(FirstIRArg), Ty, ArgI.getIndirectAlign(), false, nullptr,
3008ac9a064cSDimitry Andric           nullptr, KnownNonNull);
3009bca07a45SDimitry Andric 
3010809500fcSDimitry Andric       if (!hasScalarEvaluationKind(Ty)) {
3011bca07a45SDimitry Andric         // Aggregates and complex variables are accessed by reference. All we
3012b60736ecSDimitry Andric         // need to do is realign the value, if requested. Also, if the address
3013b60736ecSDimitry Andric         // may be aliased, copy it to ensure that the parameter variable is
3014b60736ecSDimitry Andric         // mutable and has a unique adress, as C requires.
3015b60736ecSDimitry Andric         if (ArgI.getIndirectRealign() || ArgI.isIndirectAliased()) {
3016ac9a064cSDimitry Andric           RawAddress AlignedTemp = CreateMemTemp(Ty, "coerce");
3017bca07a45SDimitry Andric 
3018bca07a45SDimitry Andric           // Copy from the incoming argument pointer to the temporary with the
3019bca07a45SDimitry Andric           // appropriate alignment.
3020bca07a45SDimitry Andric           //
3021bca07a45SDimitry Andric           // FIXME: We should have a common utility for generating an aggregate
3022bca07a45SDimitry Andric           // copy.
3023bca07a45SDimitry Andric           CharUnits Size = getContext().getTypeSizeInChars(Ty);
3024cfca06d7SDimitry Andric           Builder.CreateMemCpy(
3025cfca06d7SDimitry Andric               AlignedTemp.getPointer(), AlignedTemp.getAlignment().getAsAlign(),
3026ac9a064cSDimitry Andric               ParamAddr.emitRawPointer(*this),
3027ac9a064cSDimitry Andric               ParamAddr.getAlignment().getAsAlign(),
3028cfca06d7SDimitry Andric               llvm::ConstantInt::get(IntPtrTy, Size.getQuantity()));
3029ac9a064cSDimitry Andric           ParamAddr = AlignedTemp;
3030bca07a45SDimitry Andric         }
3031ac9a064cSDimitry Andric         ArgVals.push_back(ParamValue::forIndirect(ParamAddr));
3032ec2b103cSEd Schouten       } else {
3033ec2b103cSEd Schouten         // Load scalar value from indirect argument.
303445b53394SDimitry Andric         llvm::Value *V =
3035676fbe81SDimitry Andric             EmitLoadOfScalar(ParamAddr, false, Ty, Arg->getBeginLoc());
303601af97d3SDimitry Andric 
303701af97d3SDimitry Andric         if (isPromoted)
303801af97d3SDimitry Andric           V = emitArgumentDemotion(*this, Arg, V);
303945b53394SDimitry Andric         ArgVals.push_back(ParamValue::forDirect(V));
3040ec2b103cSEd Schouten       }
3041ec2b103cSEd Schouten       break;
3042ec2b103cSEd Schouten     }
3043ec2b103cSEd Schouten 
304470b4596dSEd Schouten     case ABIArgInfo::Extend:
3045ec2b103cSEd Schouten     case ABIArgInfo::Direct: {
3046cfca06d7SDimitry Andric       auto AI = Fn->getArg(FirstIRArg);
3047cfca06d7SDimitry Andric       llvm::Type *LTy = ConvertType(Arg->getType());
3048dbe13110SDimitry Andric 
3049cfca06d7SDimitry Andric       // Prepare parameter attributes. So far, only attributes for pointer
3050cfca06d7SDimitry Andric       // parameters are prepared. See
3051cfca06d7SDimitry Andric       // http://llvm.org/docs/LangRef.html#paramattrs.
3052cfca06d7SDimitry Andric       if (ArgI.getDirectOffset() == 0 && LTy->isPointerTy() &&
3053cfca06d7SDimitry Andric           ArgI.getCoerceToType()->isPointerTy()) {
305406d4ba38SDimitry Andric         assert(NumIRArgs == 1);
30553d1dcd9bSDimitry Andric 
30569f4dbff6SDimitry Andric         if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
3057cfca06d7SDimitry Andric           // Set `nonnull` attribute if any.
305806d4ba38SDimitry Andric           if (getNonNullAttr(CurCodeDecl, PVD, PVD->getType(),
305948675466SDimitry Andric                              PVD->getFunctionScopeIndex()) &&
306048675466SDimitry Andric               !CGM.getCodeGenOpts().NullPointerIsValid)
3061583e75ccSDimitry Andric             AI->addAttr(llvm::Attribute::NonNull);
30629f4dbff6SDimitry Andric 
30639f4dbff6SDimitry Andric           QualType OTy = PVD->getOriginalType();
30649f4dbff6SDimitry Andric           if (const auto *ArrTy =
30659f4dbff6SDimitry Andric               getContext().getAsConstantArrayType(OTy)) {
30669f4dbff6SDimitry Andric             // A C99 array parameter declaration with the static keyword also
30679f4dbff6SDimitry Andric             // indicates dereferenceability, and if the size is constant we can
30689f4dbff6SDimitry Andric             // use the dereferenceable attribute (which requires the size in
30699f4dbff6SDimitry Andric             // bytes).
3070b1c73532SDimitry Andric             if (ArrTy->getSizeModifier() == ArraySizeModifier::Static) {
30719f4dbff6SDimitry Andric               QualType ETy = ArrTy->getElementType();
3072b60736ecSDimitry Andric               llvm::Align Alignment =
3073b60736ecSDimitry Andric                   CGM.getNaturalTypeAlignment(ETy).getAsAlign();
30746f8fc217SDimitry Andric               AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment));
3075ac9a064cSDimitry Andric               uint64_t ArrSize = ArrTy->getZExtSize();
30769f4dbff6SDimitry Andric               if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
30779f4dbff6SDimitry Andric                   ArrSize) {
30786f8fc217SDimitry Andric                 llvm::AttrBuilder Attrs(getLLVMContext());
30799f4dbff6SDimitry Andric                 Attrs.addDereferenceableAttr(
3080cfca06d7SDimitry Andric                     getContext().getTypeSizeInChars(ETy).getQuantity() *
3081cfca06d7SDimitry Andric                     ArrSize);
3082583e75ccSDimitry Andric                 AI->addAttrs(Attrs);
3083cfca06d7SDimitry Andric               } else if (getContext().getTargetInfo().getNullPointerValue(
3084cfca06d7SDimitry Andric                              ETy.getAddressSpace()) == 0 &&
308548675466SDimitry Andric                          !CGM.getCodeGenOpts().NullPointerIsValid) {
3086583e75ccSDimitry Andric                 AI->addAttr(llvm::Attribute::NonNull);
30879f4dbff6SDimitry Andric               }
30889f4dbff6SDimitry Andric             }
30899f4dbff6SDimitry Andric           } else if (const auto *ArrTy =
30909f4dbff6SDimitry Andric                      getContext().getAsVariableArrayType(OTy)) {
30919f4dbff6SDimitry Andric             // For C99 VLAs with the static keyword, we don't know the size so
30929f4dbff6SDimitry Andric             // we can't use the dereferenceable attribute, but in addrspace(0)
30939f4dbff6SDimitry Andric             // we know that it must be nonnull.
3094b1c73532SDimitry Andric             if (ArrTy->getSizeModifier() == ArraySizeModifier::Static) {
3095b60736ecSDimitry Andric               QualType ETy = ArrTy->getElementType();
3096b60736ecSDimitry Andric               llvm::Align Alignment =
3097b60736ecSDimitry Andric                   CGM.getNaturalTypeAlignment(ETy).getAsAlign();
30986f8fc217SDimitry Andric               AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment));
3099e3b55780SDimitry Andric               if (!getTypes().getTargetAddressSpace(ETy) &&
310048675466SDimitry Andric                   !CGM.getCodeGenOpts().NullPointerIsValid)
3101583e75ccSDimitry Andric                 AI->addAttr(llvm::Attribute::NonNull);
31029f4dbff6SDimitry Andric             }
3103b60736ecSDimitry Andric           }
310406d4ba38SDimitry Andric 
3105cfca06d7SDimitry Andric           // Set `align` attribute if any.
310606d4ba38SDimitry Andric           const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
310706d4ba38SDimitry Andric           if (!AVAttr)
3108e3b55780SDimitry Andric             if (const auto *TOTy = OTy->getAs<TypedefType>())
310906d4ba38SDimitry Andric               AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
3110676fbe81SDimitry Andric           if (AVAttr && !SanOpts.has(SanitizerKind::Alignment)) {
3111676fbe81SDimitry Andric             // If alignment-assumption sanitizer is enabled, we do *not* add
3112676fbe81SDimitry Andric             // alignment attribute here, but emit normal alignment assumption,
3113676fbe81SDimitry Andric             // so the UBSAN check could function.
311406d4ba38SDimitry Andric             llvm::ConstantInt *AlignmentCI =
3115cfca06d7SDimitry Andric                 cast<llvm::ConstantInt>(EmitScalarExpr(AVAttr->getAlignment()));
3116c0981da4SDimitry Andric             uint64_t AlignmentInt =
3117cfca06d7SDimitry Andric                 AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
3118cfca06d7SDimitry Andric             if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
3119cfca06d7SDimitry Andric               AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
31206f8fc217SDimitry Andric               AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(
3121cfca06d7SDimitry Andric                   llvm::Align(AlignmentInt)));
3122cfca06d7SDimitry Andric             }
312306d4ba38SDimitry Andric           }
31249f4dbff6SDimitry Andric         }
31259f4dbff6SDimitry Andric 
3126cfca06d7SDimitry Andric         // Set 'noalias' if an argument type has the `restrict` qualifier.
312711d2b2d2SRoman Divacky         if (Arg->getType().isRestrictQualified())
3128583e75ccSDimitry Andric           AI->addAttr(llvm::Attribute::NoAlias);
3129cfca06d7SDimitry Andric       }
3130cfca06d7SDimitry Andric 
3131cfca06d7SDimitry Andric       // Prepare the argument value. If we have the trivial case, handle it
3132cfca06d7SDimitry Andric       // with no muss and fuss.
3133cfca06d7SDimitry Andric       if (!isa<llvm::StructType>(ArgI.getCoerceToType()) &&
3134cfca06d7SDimitry Andric           ArgI.getCoerceToType() == ConvertType(Ty) &&
3135cfca06d7SDimitry Andric           ArgI.getDirectOffset() == 0) {
3136cfca06d7SDimitry Andric         assert(NumIRArgs == 1);
313711d2b2d2SRoman Divacky 
31382b6b257fSDimitry Andric         // LLVM expects swifterror parameters to be used in very restricted
31392b6b257fSDimitry Andric         // ways.  Copy the value into a less-restricted temporary.
3140cfca06d7SDimitry Andric         llvm::Value *V = AI;
31412b6b257fSDimitry Andric         if (FI.getExtParameterInfo(ArgNo).getABI()
31422b6b257fSDimitry Andric               == ParameterABI::SwiftErrorResult) {
31432b6b257fSDimitry Andric           QualType pointeeTy = Ty->getPointeeType();
31442b6b257fSDimitry Andric           assert(pointeeTy->isPointerType());
3145ac9a064cSDimitry Andric           RawAddress temp =
31462b6b257fSDimitry Andric               CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
3147ac9a064cSDimitry Andric           Address arg = makeNaturalAddressForPointer(
3148ac9a064cSDimitry Andric               V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy));
31492b6b257fSDimitry Andric           llvm::Value *incomingErrorValue = Builder.CreateLoad(arg);
31502b6b257fSDimitry Andric           Builder.CreateStore(incomingErrorValue, temp);
31512b6b257fSDimitry Andric           V = temp.getPointer();
31522b6b257fSDimitry Andric 
31532b6b257fSDimitry Andric           // Push a cleanup to copy the value back at the end of the function.
31542b6b257fSDimitry Andric           // The convention does not guarantee that the value will be written
31552b6b257fSDimitry Andric           // back if the function exits with an unwind exception.
31562b6b257fSDimitry Andric           EHStack.pushCleanup<CopyBackSwiftError>(NormalCleanup, temp, arg);
31572b6b257fSDimitry Andric         }
31582b6b257fSDimitry Andric 
315936981b17SDimitry Andric         // Ensure the argument is the correct type.
316036981b17SDimitry Andric         if (V->getType() != ArgI.getCoerceToType())
316136981b17SDimitry Andric           V = Builder.CreateBitCast(V, ArgI.getCoerceToType());
316236981b17SDimitry Andric 
316301af97d3SDimitry Andric         if (isPromoted)
316401af97d3SDimitry Andric           V = emitArgumentDemotion(*this, Arg, V);
316501af97d3SDimitry Andric 
3166809500fcSDimitry Andric         // Because of merging of function types from multiple decls it is
3167809500fcSDimitry Andric         // possible for the type of an argument to not match the corresponding
3168809500fcSDimitry Andric         // type in the function type. Since we are codegening the callee
3169809500fcSDimitry Andric         // in here, add a cast to the argument type.
3170809500fcSDimitry Andric         llvm::Type *LTy = ConvertType(Arg->getType());
3171809500fcSDimitry Andric         if (V->getType() != LTy)
3172809500fcSDimitry Andric           V = Builder.CreateBitCast(V, LTy);
3173809500fcSDimitry Andric 
317445b53394SDimitry Andric         ArgVals.push_back(ParamValue::forDirect(V));
3175ec2b103cSEd Schouten         break;
3176ec2b103cSEd Schouten       }
3177ec2b103cSEd Schouten 
3178b60736ecSDimitry Andric       // VLST arguments are coerced to VLATs at the function boundary for
3179b60736ecSDimitry Andric       // ABI consistency. If this is a VLST that was coerced to
3180b60736ecSDimitry Andric       // a VLAT at the function boundary and the types match up, use
3181145449b1SDimitry Andric       // llvm.vector.extract to convert back to the original VLST.
3182b60736ecSDimitry Andric       if (auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(ConvertType(Ty))) {
3183c0981da4SDimitry Andric         llvm::Value *Coerced = Fn->getArg(FirstIRArg);
3184b60736ecSDimitry Andric         if (auto *VecTyFrom =
3185b60736ecSDimitry Andric                 dyn_cast<llvm::ScalableVectorType>(Coerced->getType())) {
3186ac9a064cSDimitry Andric           // If we are casting a scalable i1 predicate vector to a fixed i8
3187c0981da4SDimitry Andric           // vector, bitcast the source and use a vector extract.
3188ac9a064cSDimitry Andric           if (VecTyFrom->getElementType()->isIntegerTy(1) &&
3189ac9a064cSDimitry Andric               VecTyFrom->getElementCount().isKnownMultipleOf(8) &&
3190c0981da4SDimitry Andric               VecTyTo->getElementType() == Builder.getInt8Ty()) {
3191ac9a064cSDimitry Andric             VecTyFrom = llvm::ScalableVectorType::get(
3192ac9a064cSDimitry Andric                 VecTyTo->getElementType(),
3193ac9a064cSDimitry Andric                 VecTyFrom->getElementCount().getKnownMinValue() / 8);
3194c0981da4SDimitry Andric             Coerced = Builder.CreateBitCast(Coerced, VecTyFrom);
3195c0981da4SDimitry Andric           }
3196b60736ecSDimitry Andric           if (VecTyFrom->getElementType() == VecTyTo->getElementType()) {
3197b60736ecSDimitry Andric             llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int64Ty);
3198b60736ecSDimitry Andric 
3199b60736ecSDimitry Andric             assert(NumIRArgs == 1);
3200b60736ecSDimitry Andric             Coerced->setName(Arg->getName() + ".coerce");
3201b60736ecSDimitry Andric             ArgVals.push_back(ParamValue::forDirect(Builder.CreateExtractVector(
32027fa27ce4SDimitry Andric                 VecTyTo, Coerced, Zero, "cast.fixed")));
3203b60736ecSDimitry Andric             break;
3204b60736ecSDimitry Andric           }
3205b60736ecSDimitry Andric         }
3206b60736ecSDimitry Andric       }
3207b60736ecSDimitry Andric 
3208ac9a064cSDimitry Andric       llvm::StructType *STy =
3209ac9a064cSDimitry Andric           dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
3210ac9a064cSDimitry Andric       if (ArgI.isDirect() && !ArgI.getCanBeFlattened() && STy &&
3211ac9a064cSDimitry Andric           STy->getNumElements() > 1) {
3212ac9a064cSDimitry Andric         [[maybe_unused]] llvm::TypeSize StructSize =
3213ac9a064cSDimitry Andric             CGM.getDataLayout().getTypeAllocSize(STy);
3214ac9a064cSDimitry Andric         [[maybe_unused]] llvm::TypeSize PtrElementSize =
3215ac9a064cSDimitry Andric             CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(Ty));
3216ac9a064cSDimitry Andric         if (STy->containsHomogeneousScalableVectorTypes()) {
3217ac9a064cSDimitry Andric           assert(StructSize == PtrElementSize &&
3218ac9a064cSDimitry Andric                  "Only allow non-fractional movement of structure with"
3219ac9a064cSDimitry Andric                  "homogeneous scalable vector type");
3220ac9a064cSDimitry Andric 
3221ac9a064cSDimitry Andric           ArgVals.push_back(ParamValue::forDirect(AI));
3222ac9a064cSDimitry Andric           break;
3223ac9a064cSDimitry Andric         }
3224ac9a064cSDimitry Andric       }
3225ac9a064cSDimitry Andric 
322645b53394SDimitry Andric       Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg),
322745b53394SDimitry Andric                                      Arg->getName());
32283d1dcd9bSDimitry Andric 
322945b53394SDimitry Andric       // Pointer to store into.
323045b53394SDimitry Andric       Address Ptr = emitAddressAtOffset(*this, Alloca, ArgI);
32314ba67500SRoman Divacky 
323206d4ba38SDimitry Andric       // Fast-isel and the optimizer generally like scalar values better than
323306d4ba38SDimitry Andric       // FCAs, so we flatten them if this is safe to do for this argument.
323406d4ba38SDimitry Andric       if (ArgI.isDirect() && ArgI.getCanBeFlattened() && STy &&
323506d4ba38SDimitry Andric           STy->getNumElements() > 1) {
32367fa27ce4SDimitry Andric         llvm::TypeSize StructSize = CGM.getDataLayout().getTypeAllocSize(STy);
32377fa27ce4SDimitry Andric         llvm::TypeSize PtrElementSize =
32387fa27ce4SDimitry Andric             CGM.getDataLayout().getTypeAllocSize(Ptr.getElementType());
32397fa27ce4SDimitry Andric         if (StructSize.isScalable()) {
32407fa27ce4SDimitry Andric           assert(STy->containsHomogeneousScalableVectorTypes() &&
32417fa27ce4SDimitry Andric                  "ABI only supports structure with homogeneous scalable vector "
32427fa27ce4SDimitry Andric                  "type");
32437fa27ce4SDimitry Andric           assert(StructSize == PtrElementSize &&
32447fa27ce4SDimitry Andric                  "Only allow non-fractional movement of structure with"
32457fa27ce4SDimitry Andric                  "homogeneous scalable vector type");
32467fa27ce4SDimitry Andric           assert(STy->getNumElements() == NumIRArgs);
32477fa27ce4SDimitry Andric 
32487fa27ce4SDimitry Andric           llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
32497fa27ce4SDimitry Andric           for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
32507fa27ce4SDimitry Andric             auto *AI = Fn->getArg(FirstIRArg + i);
32517fa27ce4SDimitry Andric             AI->setName(Arg->getName() + ".coerce" + Twine(i));
32527fa27ce4SDimitry Andric             LoadedStructValue =
32537fa27ce4SDimitry Andric                 Builder.CreateInsertValue(LoadedStructValue, AI, i);
32547fa27ce4SDimitry Andric           }
32557fa27ce4SDimitry Andric 
32567fa27ce4SDimitry Andric           Builder.CreateStore(LoadedStructValue, Ptr);
32577fa27ce4SDimitry Andric         } else {
32587fa27ce4SDimitry Andric           uint64_t SrcSize = StructSize.getFixedValue();
32597fa27ce4SDimitry Andric           uint64_t DstSize = PtrElementSize.getFixedValue();
3260dbe13110SDimitry Andric 
326145b53394SDimitry Andric           Address AddrToStoreInto = Address::invalid();
3262dbe13110SDimitry Andric           if (SrcSize <= DstSize) {
32637fa27ce4SDimitry Andric             AddrToStoreInto = Ptr.withElementType(STy);
32644ba67500SRoman Divacky           } else {
326545b53394SDimitry Andric             AddrToStoreInto =
326645b53394SDimitry Andric                 CreateTempAlloca(STy, Alloca.getAlignment(), "coerce");
326745b53394SDimitry Andric           }
3268dbe13110SDimitry Andric 
326906d4ba38SDimitry Andric           assert(STy->getNumElements() == NumIRArgs);
3270dbe13110SDimitry Andric           for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
3271cfca06d7SDimitry Andric             auto AI = Fn->getArg(FirstIRArg + i);
3272dbe13110SDimitry Andric             AI->setName(Arg->getName() + ".coerce" + Twine(i));
327322989816SDimitry Andric             Address EltPtr = Builder.CreateStructGEP(AddrToStoreInto, i);
327406d4ba38SDimitry Andric             Builder.CreateStore(AI, EltPtr);
3275dbe13110SDimitry Andric           }
3276dbe13110SDimitry Andric 
327745b53394SDimitry Andric           if (SrcSize > DstSize) {
327845b53394SDimitry Andric             Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize);
3279dbe13110SDimitry Andric           }
32807fa27ce4SDimitry Andric         }
3281dbe13110SDimitry Andric       } else {
32824ba67500SRoman Divacky         // Simple case, just do a coerced store of the argument into the alloca.
328306d4ba38SDimitry Andric         assert(NumIRArgs == 1);
3284cfca06d7SDimitry Andric         auto AI = Fn->getArg(FirstIRArg);
32854ba67500SRoman Divacky         AI->setName(Arg->getName() + ".coerce");
32861de139fdSDimitry Andric         CreateCoercedStore(
32871de139fdSDimitry Andric             AI, Ptr,
32881de139fdSDimitry Andric             llvm::TypeSize::getFixed(
32891de139fdSDimitry Andric                 getContext().getTypeSizeInChars(Ty).getQuantity() -
32901de139fdSDimitry Andric                 ArgI.getDirectOffset()),
32911de139fdSDimitry Andric             /*DstIsVolatile=*/false);
32924ba67500SRoman Divacky       }
32934ba67500SRoman Divacky 
3294ec2b103cSEd Schouten       // Match to what EmitParmDecl is expecting for this type.
3295809500fcSDimitry Andric       if (CodeGenFunction::hasScalarEvaluationKind(Ty)) {
329645b53394SDimitry Andric         llvm::Value *V =
3297676fbe81SDimitry Andric             EmitLoadOfScalar(Alloca, false, Ty, Arg->getBeginLoc());
329801af97d3SDimitry Andric         if (isPromoted)
329901af97d3SDimitry Andric           V = emitArgumentDemotion(*this, Arg, V);
330045b53394SDimitry Andric         ArgVals.push_back(ParamValue::forDirect(V));
33019f4dbff6SDimitry Andric       } else {
330245b53394SDimitry Andric         ArgVals.push_back(ParamValue::forIndirect(Alloca));
3303ec2b103cSEd Schouten       }
330406d4ba38SDimitry Andric       break;
3305ec2b103cSEd Schouten     }
33063d1dcd9bSDimitry Andric 
33072b6b257fSDimitry Andric     case ABIArgInfo::CoerceAndExpand: {
33082b6b257fSDimitry Andric       // Reconstruct into a temporary.
33092b6b257fSDimitry Andric       Address alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg));
33102b6b257fSDimitry Andric       ArgVals.push_back(ParamValue::forIndirect(alloca));
33112b6b257fSDimitry Andric 
33122b6b257fSDimitry Andric       auto coercionType = ArgI.getCoerceAndExpandType();
33137fa27ce4SDimitry Andric       alloca = alloca.withElementType(coercionType);
33142b6b257fSDimitry Andric 
33152b6b257fSDimitry Andric       unsigned argIndex = FirstIRArg;
33162b6b257fSDimitry Andric       for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
33172b6b257fSDimitry Andric         llvm::Type *eltType = coercionType->getElementType(i);
33182b6b257fSDimitry Andric         if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType))
33192b6b257fSDimitry Andric           continue;
33202b6b257fSDimitry Andric 
332122989816SDimitry Andric         auto eltAddr = Builder.CreateStructGEP(alloca, i);
3322cfca06d7SDimitry Andric         auto elt = Fn->getArg(argIndex++);
33232b6b257fSDimitry Andric         Builder.CreateStore(elt, eltAddr);
33242b6b257fSDimitry Andric       }
33252b6b257fSDimitry Andric       assert(argIndex == FirstIRArg + NumIRArgs);
33262b6b257fSDimitry Andric       break;
33272b6b257fSDimitry Andric     }
33282b6b257fSDimitry Andric 
33293d1dcd9bSDimitry Andric     case ABIArgInfo::Expand: {
33303d1dcd9bSDimitry Andric       // If this structure was expanded into multiple arguments then
33313d1dcd9bSDimitry Andric       // we need to create a temporary and reconstruct it from the
33323d1dcd9bSDimitry Andric       // arguments.
333345b53394SDimitry Andric       Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg));
333445b53394SDimitry Andric       LValue LV = MakeAddrLValue(Alloca, Ty);
333545b53394SDimitry Andric       ArgVals.push_back(ParamValue::forIndirect(Alloca));
33363d1dcd9bSDimitry Andric 
3337cfca06d7SDimitry Andric       auto FnArgIter = Fn->arg_begin() + FirstIRArg;
333806d4ba38SDimitry Andric       ExpandTypeFromArgs(Ty, LV, FnArgIter);
3339cfca06d7SDimitry Andric       assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
334006d4ba38SDimitry Andric       for (unsigned i = 0, e = NumIRArgs; i != e; ++i) {
3341cfca06d7SDimitry Andric         auto AI = Fn->getArg(FirstIRArg + i);
334206d4ba38SDimitry Andric         AI->setName(Arg->getName() + "." + Twine(i));
334306d4ba38SDimitry Andric       }
334406d4ba38SDimitry Andric       break;
33453d1dcd9bSDimitry Andric     }
33463d1dcd9bSDimitry Andric 
33473d1dcd9bSDimitry Andric     case ABIArgInfo::Ignore:
334806d4ba38SDimitry Andric       assert(NumIRArgs == 0);
33493d1dcd9bSDimitry Andric       // Initialize the local variable appropriately.
33509f4dbff6SDimitry Andric       if (!hasScalarEvaluationKind(Ty)) {
335145b53394SDimitry Andric         ArgVals.push_back(ParamValue::forIndirect(CreateMemTemp(Ty)));
33529f4dbff6SDimitry Andric       } else {
33539f4dbff6SDimitry Andric         llvm::Value *U = llvm::UndefValue::get(ConvertType(Arg->getType()));
335445b53394SDimitry Andric         ArgVals.push_back(ParamValue::forDirect(U));
33559f4dbff6SDimitry Andric       }
335606d4ba38SDimitry Andric       break;
3357ec2b103cSEd Schouten     }
3358ec2b103cSEd Schouten   }
33599f4dbff6SDimitry Andric 
33609f4dbff6SDimitry Andric   if (getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
33619f4dbff6SDimitry Andric     for (int I = Args.size() - 1; I >= 0; --I)
336245b53394SDimitry Andric       EmitParmDecl(*Args[I], ArgVals[I], I + 1);
33639f4dbff6SDimitry Andric   } else {
33649f4dbff6SDimitry Andric     for (unsigned I = 0, E = Args.size(); I != E; ++I)
336545b53394SDimitry Andric       EmitParmDecl(*Args[I], ArgVals[I], I + 1);
33669f4dbff6SDimitry Andric   }
3367ec2b103cSEd Schouten }
3368ec2b103cSEd Schouten 
eraseUnusedBitCasts(llvm::Instruction * insn)3369dbe13110SDimitry Andric static void eraseUnusedBitCasts(llvm::Instruction *insn) {
3370dbe13110SDimitry Andric   while (insn->use_empty()) {
3371dbe13110SDimitry Andric     llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
3372dbe13110SDimitry Andric     if (!bitcast) return;
3373dbe13110SDimitry Andric 
3374dbe13110SDimitry Andric     // This is "safe" because we would have used a ConstantExpr otherwise.
3375dbe13110SDimitry Andric     insn = cast<llvm::Instruction>(bitcast->getOperand(0));
3376dbe13110SDimitry Andric     bitcast->eraseFromParent();
3377dbe13110SDimitry Andric   }
3378dbe13110SDimitry Andric }
3379dbe13110SDimitry Andric 
3380180abc3dSDimitry Andric /// Try to emit a fused autorelease of a return result.
tryEmitFusedAutoreleaseOfResult(CodeGenFunction & CGF,llvm::Value * result)3381180abc3dSDimitry Andric static llvm::Value *tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF,
3382180abc3dSDimitry Andric                                                     llvm::Value *result) {
3383180abc3dSDimitry Andric   // We must be immediately followed the cast.
3384180abc3dSDimitry Andric   llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock();
33859f4dbff6SDimitry Andric   if (BB->empty()) return nullptr;
33869f4dbff6SDimitry Andric   if (&BB->back() != result) return nullptr;
3387180abc3dSDimitry Andric 
338836981b17SDimitry Andric   llvm::Type *resultType = result->getType();
3389180abc3dSDimitry Andric 
3390180abc3dSDimitry Andric   // result is in a BasicBlock and is therefore an Instruction.
3391180abc3dSDimitry Andric   llvm::Instruction *generator = cast<llvm::Instruction>(result);
3392180abc3dSDimitry Andric 
3393bab175ecSDimitry Andric   SmallVector<llvm::Instruction *, 4> InstsToKill;
3394180abc3dSDimitry Andric 
3395180abc3dSDimitry Andric   // Look for:
3396180abc3dSDimitry Andric   //  %generator = bitcast %type1* %generator2 to %type2*
3397180abc3dSDimitry Andric   while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
3398180abc3dSDimitry Andric     // We would have emitted this as a constant if the operand weren't
3399180abc3dSDimitry Andric     // an Instruction.
3400180abc3dSDimitry Andric     generator = cast<llvm::Instruction>(bitcast->getOperand(0));
3401180abc3dSDimitry Andric 
3402180abc3dSDimitry Andric     // Require the generator to be immediately followed by the cast.
3403180abc3dSDimitry Andric     if (generator->getNextNode() != bitcast)
34049f4dbff6SDimitry Andric       return nullptr;
3405180abc3dSDimitry Andric 
3406bab175ecSDimitry Andric     InstsToKill.push_back(bitcast);
3407180abc3dSDimitry Andric   }
3408180abc3dSDimitry Andric 
3409180abc3dSDimitry Andric   // Look for:
3410180abc3dSDimitry Andric   //   %generator = call i8* @objc_retain(i8* %originalResult)
3411180abc3dSDimitry Andric   // or
3412180abc3dSDimitry Andric   //   %generator = call i8* @objc_retainAutoreleasedReturnValue(i8* %originalResult)
3413180abc3dSDimitry Andric   llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
34149f4dbff6SDimitry Andric   if (!call) return nullptr;
3415180abc3dSDimitry Andric 
3416180abc3dSDimitry Andric   bool doRetainAutorelease;
3417180abc3dSDimitry Andric 
3418cfca06d7SDimitry Andric   if (call->getCalledOperand() == CGF.CGM.getObjCEntrypoints().objc_retain) {
3419180abc3dSDimitry Andric     doRetainAutorelease = true;
3420cfca06d7SDimitry Andric   } else if (call->getCalledOperand() ==
3421cfca06d7SDimitry Andric              CGF.CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue) {
3422180abc3dSDimitry Andric     doRetainAutorelease = false;
3423180abc3dSDimitry Andric 
342413cc256eSDimitry Andric     // If we emitted an assembly marker for this call (and the
342513cc256eSDimitry Andric     // ARCEntrypoints field should have been set if so), go looking
342613cc256eSDimitry Andric     // for that call.  If we can't find it, we can't do this
342713cc256eSDimitry Andric     // optimization.  But it should always be the immediately previous
342813cc256eSDimitry Andric     // instruction, unless we needed bitcasts around the call.
342945b53394SDimitry Andric     if (CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker) {
3430180abc3dSDimitry Andric       llvm::Instruction *prev = call->getPrevNode();
343113cc256eSDimitry Andric       assert(prev);
343213cc256eSDimitry Andric       if (isa<llvm::BitCastInst>(prev)) {
343313cc256eSDimitry Andric         prev = prev->getPrevNode();
343413cc256eSDimitry Andric         assert(prev);
343513cc256eSDimitry Andric       }
343613cc256eSDimitry Andric       assert(isa<llvm::CallInst>(prev));
3437cfca06d7SDimitry Andric       assert(cast<llvm::CallInst>(prev)->getCalledOperand() ==
343845b53394SDimitry Andric              CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker);
3439bab175ecSDimitry Andric       InstsToKill.push_back(prev);
344013cc256eSDimitry Andric     }
3441180abc3dSDimitry Andric   } else {
34429f4dbff6SDimitry Andric     return nullptr;
3443180abc3dSDimitry Andric   }
3444180abc3dSDimitry Andric 
3445180abc3dSDimitry Andric   result = call->getArgOperand(0);
3446bab175ecSDimitry Andric   InstsToKill.push_back(call);
3447180abc3dSDimitry Andric 
3448180abc3dSDimitry Andric   // Keep killing bitcasts, for sanity.  Note that we no longer care
3449180abc3dSDimitry Andric   // about precise ordering as long as there's exactly one use.
3450180abc3dSDimitry Andric   while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
3451180abc3dSDimitry Andric     if (!bitcast->hasOneUse()) break;
3452bab175ecSDimitry Andric     InstsToKill.push_back(bitcast);
3453180abc3dSDimitry Andric     result = bitcast->getOperand(0);
3454180abc3dSDimitry Andric   }
3455180abc3dSDimitry Andric 
3456180abc3dSDimitry Andric   // Delete all the unnecessary instructions, from latest to earliest.
3457bab175ecSDimitry Andric   for (auto *I : InstsToKill)
3458bab175ecSDimitry Andric     I->eraseFromParent();
3459180abc3dSDimitry Andric 
3460180abc3dSDimitry Andric   // Do the fused retain/autorelease if we were asked to.
3461180abc3dSDimitry Andric   if (doRetainAutorelease)
3462180abc3dSDimitry Andric     result = CGF.EmitARCRetainAutoreleaseReturnValue(result);
3463180abc3dSDimitry Andric 
3464180abc3dSDimitry Andric   // Cast back to the result type.
3465180abc3dSDimitry Andric   return CGF.Builder.CreateBitCast(result, resultType);
3466180abc3dSDimitry Andric }
3467180abc3dSDimitry Andric 
3468dbe13110SDimitry Andric /// If this is a +1 of the value of an immutable 'self', remove it.
tryRemoveRetainOfSelf(CodeGenFunction & CGF,llvm::Value * result)3469dbe13110SDimitry Andric static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
3470dbe13110SDimitry Andric                                           llvm::Value *result) {
3471dbe13110SDimitry Andric   // This is only applicable to a method with an immutable 'self'.
347256d91b49SDimitry Andric   const ObjCMethodDecl *method =
347356d91b49SDimitry Andric     dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl);
34749f4dbff6SDimitry Andric   if (!method) return nullptr;
3475dbe13110SDimitry Andric   const VarDecl *self = method->getSelfDecl();
34769f4dbff6SDimitry Andric   if (!self->getType().isConstQualified()) return nullptr;
3477dbe13110SDimitry Andric 
3478b1c73532SDimitry Andric   // Look for a retain call. Note: stripPointerCasts looks through returned arg
3479b1c73532SDimitry Andric   // functions, which would cause us to miss the retain.
3480b1c73532SDimitry Andric   llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
3481cfca06d7SDimitry Andric   if (!retainCall || retainCall->getCalledOperand() !=
3482cfca06d7SDimitry Andric                          CGF.CGM.getObjCEntrypoints().objc_retain)
34839f4dbff6SDimitry Andric     return nullptr;
3484dbe13110SDimitry Andric 
3485dbe13110SDimitry Andric   // Look for an ordinary load of 'self'.
3486dbe13110SDimitry Andric   llvm::Value *retainedValue = retainCall->getArgOperand(0);
3487dbe13110SDimitry Andric   llvm::LoadInst *load =
3488dbe13110SDimitry Andric     dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
3489dbe13110SDimitry Andric   if (!load || load->isAtomic() || load->isVolatile() ||
3490ac9a064cSDimitry Andric       load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
34919f4dbff6SDimitry Andric     return nullptr;
3492dbe13110SDimitry Andric 
3493dbe13110SDimitry Andric   // Okay!  Burn it all down.  This relies for correctness on the
3494dbe13110SDimitry Andric   // assumption that the retain is emitted as part of the return and
3495dbe13110SDimitry Andric   // that thereafter everything is used "linearly".
3496dbe13110SDimitry Andric   llvm::Type *resultType = result->getType();
3497dbe13110SDimitry Andric   eraseUnusedBitCasts(cast<llvm::Instruction>(result));
3498dbe13110SDimitry Andric   assert(retainCall->use_empty());
3499dbe13110SDimitry Andric   retainCall->eraseFromParent();
3500dbe13110SDimitry Andric   eraseUnusedBitCasts(cast<llvm::Instruction>(retainedValue));
3501dbe13110SDimitry Andric 
3502dbe13110SDimitry Andric   return CGF.Builder.CreateBitCast(load, resultType);
3503dbe13110SDimitry Andric }
3504dbe13110SDimitry Andric 
3505180abc3dSDimitry Andric /// Emit an ARC autorelease of the result of a function.
3506dbe13110SDimitry Andric ///
3507dbe13110SDimitry Andric /// \return the value to actually return from the function
emitAutoreleaseOfResult(CodeGenFunction & CGF,llvm::Value * result)3508180abc3dSDimitry Andric static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
3509180abc3dSDimitry Andric                                             llvm::Value *result) {
3510dbe13110SDimitry Andric   // If we're returning 'self', kill the initial retain.  This is a
3511dbe13110SDimitry Andric   // heuristic attempt to "encourage correctness" in the really unfortunate
3512dbe13110SDimitry Andric   // case where we have a return of self during a dealloc and we desperately
3513dbe13110SDimitry Andric   // need to avoid the possible autorelease.
3514dbe13110SDimitry Andric   if (llvm::Value *self = tryRemoveRetainOfSelf(CGF, result))
3515dbe13110SDimitry Andric     return self;
3516dbe13110SDimitry Andric 
3517180abc3dSDimitry Andric   // At -O0, try to emit a fused retain/autorelease.
3518180abc3dSDimitry Andric   if (CGF.shouldUseFusedARCCalls())
3519180abc3dSDimitry Andric     if (llvm::Value *fused = tryEmitFusedAutoreleaseOfResult(CGF, result))
3520180abc3dSDimitry Andric       return fused;
3521180abc3dSDimitry Andric 
3522180abc3dSDimitry Andric   return CGF.EmitARCAutoreleaseReturnValue(result);
3523180abc3dSDimitry Andric }
3524180abc3dSDimitry Andric 
3525dbe13110SDimitry Andric /// Heuristically search for a dominating store to the return-value slot.
findDominatingStoreToReturnValue(CodeGenFunction & CGF)3526dbe13110SDimitry Andric static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
3527ac9a064cSDimitry Andric   llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer();
3528ac9a064cSDimitry Andric 
352945b53394SDimitry Andric   // Check if a User is a store which pointerOperand is the ReturnValue.
353045b53394SDimitry Andric   // We are looking for stores to the ReturnValue, not for stores of the
353145b53394SDimitry Andric   // ReturnValue to some other location.
3532ac9a064cSDimitry Andric   auto GetStoreIfValid = [&CGF,
3533ac9a064cSDimitry Andric                           ReturnValuePtr](llvm::User *U) -> llvm::StoreInst * {
353445b53394SDimitry Andric     auto *SI = dyn_cast<llvm::StoreInst>(U);
3535ac9a064cSDimitry Andric     if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
3536145449b1SDimitry Andric         SI->getValueOperand()->getType() != CGF.ReturnValue.getElementType())
353745b53394SDimitry Andric       return nullptr;
353845b53394SDimitry Andric     // These aren't actually possible for non-coerced returns, and we
353945b53394SDimitry Andric     // only care about non-coerced returns on this code path.
3540b1c73532SDimitry Andric     // All memory instructions inside __try block are volatile.
3541b1c73532SDimitry Andric     assert(!SI->isAtomic() &&
3542b1c73532SDimitry Andric            (!SI->isVolatile() || CGF.currentFunctionUsesSEHTry()));
354345b53394SDimitry Andric     return SI;
354445b53394SDimitry Andric   };
3545dbe13110SDimitry Andric   // If there are multiple uses of the return-value slot, just check
3546dbe13110SDimitry Andric   // for something immediately preceding the IP.  Sometimes this can
3547dbe13110SDimitry Andric   // happen with how we generate implicit-returns; it can also happen
3548dbe13110SDimitry Andric   // with noreturn cleanups.
3549ac9a064cSDimitry Andric   if (!ReturnValuePtr->hasOneUse()) {
3550dbe13110SDimitry Andric     llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
35519f4dbff6SDimitry Andric     if (IP->empty()) return nullptr;
35525e20cdd8SDimitry Andric 
3553145449b1SDimitry Andric     // Look at directly preceding instruction, skipping bitcasts and lifetime
3554145449b1SDimitry Andric     // markers.
3555145449b1SDimitry Andric     for (llvm::Instruction &I : make_range(IP->rbegin(), IP->rend())) {
3556145449b1SDimitry Andric       if (isa<llvm::BitCastInst>(&I))
35575e20cdd8SDimitry Andric         continue;
3558145449b1SDimitry Andric       if (auto *II = dyn_cast<llvm::IntrinsicInst>(&I))
3559145449b1SDimitry Andric         if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
3560145449b1SDimitry Andric           continue;
35615e20cdd8SDimitry Andric 
3562145449b1SDimitry Andric       return GetStoreIfValid(&I);
3563145449b1SDimitry Andric     }
3564145449b1SDimitry Andric     return nullptr;
3565dbe13110SDimitry Andric   }
3566dbe13110SDimitry Andric 
3567ac9a064cSDimitry Andric   llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
35689f4dbff6SDimitry Andric   if (!store) return nullptr;
3569dbe13110SDimitry Andric 
3570dbe13110SDimitry Andric   // Now do a first-and-dirty dominance check: just walk up the
3571dbe13110SDimitry Andric   // single-predecessors chain from the current insertion point.
3572dbe13110SDimitry Andric   llvm::BasicBlock *StoreBB = store->getParent();
3573dbe13110SDimitry Andric   llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
35747fa27ce4SDimitry Andric   llvm::SmallPtrSet<llvm::BasicBlock *, 4> SeenBBs;
3575dbe13110SDimitry Andric   while (IP != StoreBB) {
35767fa27ce4SDimitry Andric     if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
35779f4dbff6SDimitry Andric       return nullptr;
3578dbe13110SDimitry Andric   }
3579dbe13110SDimitry Andric 
3580dbe13110SDimitry Andric   // Okay, the store's basic block dominates the insertion point; we
3581dbe13110SDimitry Andric   // can do our thing.
3582dbe13110SDimitry Andric   return store;
3583dbe13110SDimitry Andric }
3584dbe13110SDimitry Andric 
3585cfca06d7SDimitry Andric // Helper functions for EmitCMSEClearRecord
3586cfca06d7SDimitry Andric 
3587cfca06d7SDimitry Andric // Set the bits corresponding to a field having width `BitWidth` and located at
3588cfca06d7SDimitry Andric // offset `BitOffset` (from the least significant bit) within a storage unit of
3589cfca06d7SDimitry Andric // `Bits.size()` bytes. Each element of `Bits` corresponds to one target byte.
3590cfca06d7SDimitry Andric // Use little-endian layout, i.e.`Bits[0]` is the LSB.
setBitRange(SmallVectorImpl<uint64_t> & Bits,int BitOffset,int BitWidth,int CharWidth)3591cfca06d7SDimitry Andric static void setBitRange(SmallVectorImpl<uint64_t> &Bits, int BitOffset,
3592cfca06d7SDimitry Andric                         int BitWidth, int CharWidth) {
3593cfca06d7SDimitry Andric   assert(CharWidth <= 64);
3594cfca06d7SDimitry Andric   assert(static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
3595cfca06d7SDimitry Andric 
3596cfca06d7SDimitry Andric   int Pos = 0;
3597cfca06d7SDimitry Andric   if (BitOffset >= CharWidth) {
3598cfca06d7SDimitry Andric     Pos += BitOffset / CharWidth;
3599cfca06d7SDimitry Andric     BitOffset = BitOffset % CharWidth;
3600cfca06d7SDimitry Andric   }
3601cfca06d7SDimitry Andric 
3602cfca06d7SDimitry Andric   const uint64_t Used = (uint64_t(1) << CharWidth) - 1;
3603cfca06d7SDimitry Andric   if (BitOffset + BitWidth >= CharWidth) {
3604cfca06d7SDimitry Andric     Bits[Pos++] |= (Used << BitOffset) & Used;
3605cfca06d7SDimitry Andric     BitWidth -= CharWidth - BitOffset;
3606cfca06d7SDimitry Andric     BitOffset = 0;
3607cfca06d7SDimitry Andric   }
3608cfca06d7SDimitry Andric 
3609cfca06d7SDimitry Andric   while (BitWidth >= CharWidth) {
3610cfca06d7SDimitry Andric     Bits[Pos++] = Used;
3611cfca06d7SDimitry Andric     BitWidth -= CharWidth;
3612cfca06d7SDimitry Andric   }
3613cfca06d7SDimitry Andric 
3614cfca06d7SDimitry Andric   if (BitWidth > 0)
3615cfca06d7SDimitry Andric     Bits[Pos++] |= (Used >> (CharWidth - BitWidth)) << BitOffset;
3616cfca06d7SDimitry Andric }
3617cfca06d7SDimitry Andric 
3618cfca06d7SDimitry Andric // Set the bits corresponding to a field having width `BitWidth` and located at
3619cfca06d7SDimitry Andric // offset `BitOffset` (from the least significant bit) within a storage unit of
3620cfca06d7SDimitry Andric // `StorageSize` bytes, located at `StorageOffset` in `Bits`. Each element of
3621cfca06d7SDimitry Andric // `Bits` corresponds to one target byte. Use target endian layout.
setBitRange(SmallVectorImpl<uint64_t> & Bits,int StorageOffset,int StorageSize,int BitOffset,int BitWidth,int CharWidth,bool BigEndian)3622cfca06d7SDimitry Andric static void setBitRange(SmallVectorImpl<uint64_t> &Bits, int StorageOffset,
3623cfca06d7SDimitry Andric                         int StorageSize, int BitOffset, int BitWidth,
3624cfca06d7SDimitry Andric                         int CharWidth, bool BigEndian) {
3625cfca06d7SDimitry Andric 
3626cfca06d7SDimitry Andric   SmallVector<uint64_t, 8> TmpBits(StorageSize);
3627cfca06d7SDimitry Andric   setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
3628cfca06d7SDimitry Andric 
3629cfca06d7SDimitry Andric   if (BigEndian)
3630cfca06d7SDimitry Andric     std::reverse(TmpBits.begin(), TmpBits.end());
3631cfca06d7SDimitry Andric 
3632cfca06d7SDimitry Andric   for (uint64_t V : TmpBits)
3633cfca06d7SDimitry Andric     Bits[StorageOffset++] |= V;
3634cfca06d7SDimitry Andric }
3635cfca06d7SDimitry Andric 
3636cfca06d7SDimitry Andric static void setUsedBits(CodeGenModule &, QualType, int,
3637cfca06d7SDimitry Andric                         SmallVectorImpl<uint64_t> &);
3638cfca06d7SDimitry Andric 
3639cfca06d7SDimitry Andric // Set the bits in `Bits`, which correspond to the value representations of
3640cfca06d7SDimitry Andric // the actual members of the record type `RTy`. Note that this function does
3641cfca06d7SDimitry Andric // not handle base classes, virtual tables, etc, since they cannot happen in
3642cfca06d7SDimitry Andric // CMSE function arguments or return. The bit mask corresponds to the target
3643cfca06d7SDimitry Andric // memory layout, i.e. it's endian dependent.
setUsedBits(CodeGenModule & CGM,const RecordType * RTy,int Offset,SmallVectorImpl<uint64_t> & Bits)3644cfca06d7SDimitry Andric static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset,
3645cfca06d7SDimitry Andric                         SmallVectorImpl<uint64_t> &Bits) {
3646cfca06d7SDimitry Andric   ASTContext &Context = CGM.getContext();
3647cfca06d7SDimitry Andric   int CharWidth = Context.getCharWidth();
3648cfca06d7SDimitry Andric   const RecordDecl *RD = RTy->getDecl()->getDefinition();
3649cfca06d7SDimitry Andric   const ASTRecordLayout &ASTLayout = Context.getASTRecordLayout(RD);
3650cfca06d7SDimitry Andric   const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD);
3651cfca06d7SDimitry Andric 
3652cfca06d7SDimitry Andric   int Idx = 0;
3653cfca06d7SDimitry Andric   for (auto I = RD->field_begin(), E = RD->field_end(); I != E; ++I, ++Idx) {
3654cfca06d7SDimitry Andric     const FieldDecl *F = *I;
3655cfca06d7SDimitry Andric 
3656ac9a064cSDimitry Andric     if (F->isUnnamedBitField() || F->isZeroLengthBitField(Context) ||
3657cfca06d7SDimitry Andric         F->getType()->isIncompleteArrayType())
3658cfca06d7SDimitry Andric       continue;
3659cfca06d7SDimitry Andric 
3660cfca06d7SDimitry Andric     if (F->isBitField()) {
3661cfca06d7SDimitry Andric       const CGBitFieldInfo &BFI = Layout.getBitFieldInfo(F);
3662cfca06d7SDimitry Andric       setBitRange(Bits, Offset + BFI.StorageOffset.getQuantity(),
3663cfca06d7SDimitry Andric                   BFI.StorageSize / CharWidth, BFI.Offset,
3664cfca06d7SDimitry Andric                   BFI.Size, CharWidth,
3665cfca06d7SDimitry Andric                   CGM.getDataLayout().isBigEndian());
3666cfca06d7SDimitry Andric       continue;
3667cfca06d7SDimitry Andric     }
3668cfca06d7SDimitry Andric 
3669cfca06d7SDimitry Andric     setUsedBits(CGM, F->getType(),
3670cfca06d7SDimitry Andric                 Offset + ASTLayout.getFieldOffset(Idx) / CharWidth, Bits);
3671cfca06d7SDimitry Andric   }
3672cfca06d7SDimitry Andric }
3673cfca06d7SDimitry Andric 
3674cfca06d7SDimitry Andric // Set the bits in `Bits`, which correspond to the value representations of
3675cfca06d7SDimitry Andric // the elements of an array type `ATy`.
setUsedBits(CodeGenModule & CGM,const ConstantArrayType * ATy,int Offset,SmallVectorImpl<uint64_t> & Bits)3676cfca06d7SDimitry Andric static void setUsedBits(CodeGenModule &CGM, const ConstantArrayType *ATy,
3677cfca06d7SDimitry Andric                         int Offset, SmallVectorImpl<uint64_t> &Bits) {
3678cfca06d7SDimitry Andric   const ASTContext &Context = CGM.getContext();
3679cfca06d7SDimitry Andric 
3680cfca06d7SDimitry Andric   QualType ETy = Context.getBaseElementType(ATy);
3681cfca06d7SDimitry Andric   int Size = Context.getTypeSizeInChars(ETy).getQuantity();
3682cfca06d7SDimitry Andric   SmallVector<uint64_t, 4> TmpBits(Size);
3683cfca06d7SDimitry Andric   setUsedBits(CGM, ETy, 0, TmpBits);
3684cfca06d7SDimitry Andric 
3685cfca06d7SDimitry Andric   for (int I = 0, N = Context.getConstantArrayElementCount(ATy); I < N; ++I) {
3686cfca06d7SDimitry Andric     auto Src = TmpBits.begin();
3687cfca06d7SDimitry Andric     auto Dst = Bits.begin() + Offset + I * Size;
3688cfca06d7SDimitry Andric     for (int J = 0; J < Size; ++J)
3689cfca06d7SDimitry Andric       *Dst++ |= *Src++;
3690cfca06d7SDimitry Andric   }
3691cfca06d7SDimitry Andric }
3692cfca06d7SDimitry Andric 
3693cfca06d7SDimitry Andric // Set the bits in `Bits`, which correspond to the value representations of
3694cfca06d7SDimitry Andric // the type `QTy`.
setUsedBits(CodeGenModule & CGM,QualType QTy,int Offset,SmallVectorImpl<uint64_t> & Bits)3695cfca06d7SDimitry Andric static void setUsedBits(CodeGenModule &CGM, QualType QTy, int Offset,
3696cfca06d7SDimitry Andric                         SmallVectorImpl<uint64_t> &Bits) {
3697cfca06d7SDimitry Andric   if (const auto *RTy = QTy->getAs<RecordType>())
3698cfca06d7SDimitry Andric     return setUsedBits(CGM, RTy, Offset, Bits);
3699cfca06d7SDimitry Andric 
3700cfca06d7SDimitry Andric   ASTContext &Context = CGM.getContext();
3701cfca06d7SDimitry Andric   if (const auto *ATy = Context.getAsConstantArrayType(QTy))
3702cfca06d7SDimitry Andric     return setUsedBits(CGM, ATy, Offset, Bits);
3703cfca06d7SDimitry Andric 
3704cfca06d7SDimitry Andric   int Size = Context.getTypeSizeInChars(QTy).getQuantity();
3705cfca06d7SDimitry Andric   if (Size <= 0)
3706cfca06d7SDimitry Andric     return;
3707cfca06d7SDimitry Andric 
3708cfca06d7SDimitry Andric   std::fill_n(Bits.begin() + Offset, Size,
3709cfca06d7SDimitry Andric               (uint64_t(1) << Context.getCharWidth()) - 1);
3710cfca06d7SDimitry Andric }
3711cfca06d7SDimitry Andric 
buildMultiCharMask(const SmallVectorImpl<uint64_t> & Bits,int Pos,int Size,int CharWidth,bool BigEndian)3712cfca06d7SDimitry Andric static uint64_t buildMultiCharMask(const SmallVectorImpl<uint64_t> &Bits,
3713cfca06d7SDimitry Andric                                    int Pos, int Size, int CharWidth,
3714cfca06d7SDimitry Andric                                    bool BigEndian) {
3715cfca06d7SDimitry Andric   assert(Size > 0);
3716cfca06d7SDimitry Andric   uint64_t Mask = 0;
3717cfca06d7SDimitry Andric   if (BigEndian) {
3718cfca06d7SDimitry Andric     for (auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size; P != E;
3719cfca06d7SDimitry Andric          ++P)
3720cfca06d7SDimitry Andric       Mask = (Mask << CharWidth) | *P;
3721cfca06d7SDimitry Andric   } else {
3722cfca06d7SDimitry Andric     auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
3723cfca06d7SDimitry Andric     do
3724cfca06d7SDimitry Andric       Mask = (Mask << CharWidth) | *--P;
3725cfca06d7SDimitry Andric     while (P != End);
3726cfca06d7SDimitry Andric   }
3727cfca06d7SDimitry Andric   return Mask;
3728cfca06d7SDimitry Andric }
3729cfca06d7SDimitry Andric 
3730cfca06d7SDimitry Andric // Emit code to clear the bits in a record, which aren't a part of any user
3731cfca06d7SDimitry Andric // declared member, when the record is a function return.
EmitCMSEClearRecord(llvm::Value * Src,llvm::IntegerType * ITy,QualType QTy)3732cfca06d7SDimitry Andric llvm::Value *CodeGenFunction::EmitCMSEClearRecord(llvm::Value *Src,
3733cfca06d7SDimitry Andric                                                   llvm::IntegerType *ITy,
3734cfca06d7SDimitry Andric                                                   QualType QTy) {
3735cfca06d7SDimitry Andric   assert(Src->getType() == ITy);
3736cfca06d7SDimitry Andric   assert(ITy->getScalarSizeInBits() <= 64);
3737cfca06d7SDimitry Andric 
3738cfca06d7SDimitry Andric   const llvm::DataLayout &DataLayout = CGM.getDataLayout();
3739cfca06d7SDimitry Andric   int Size = DataLayout.getTypeStoreSize(ITy);
3740cfca06d7SDimitry Andric   SmallVector<uint64_t, 4> Bits(Size);
3741b60736ecSDimitry Andric   setUsedBits(CGM, QTy->castAs<RecordType>(), 0, Bits);
3742cfca06d7SDimitry Andric 
3743cfca06d7SDimitry Andric   int CharWidth = CGM.getContext().getCharWidth();
3744cfca06d7SDimitry Andric   uint64_t Mask =
3745cfca06d7SDimitry Andric       buildMultiCharMask(Bits, 0, Size, CharWidth, DataLayout.isBigEndian());
3746cfca06d7SDimitry Andric 
3747cfca06d7SDimitry Andric   return Builder.CreateAnd(Src, Mask, "cmse.clear");
3748cfca06d7SDimitry Andric }
3749cfca06d7SDimitry Andric 
3750cfca06d7SDimitry Andric // Emit code to clear the bits in a record, which aren't a part of any user
3751cfca06d7SDimitry Andric // declared member, when the record is a function argument.
EmitCMSEClearRecord(llvm::Value * Src,llvm::ArrayType * ATy,QualType QTy)3752cfca06d7SDimitry Andric llvm::Value *CodeGenFunction::EmitCMSEClearRecord(llvm::Value *Src,
3753cfca06d7SDimitry Andric                                                   llvm::ArrayType *ATy,
3754cfca06d7SDimitry Andric                                                   QualType QTy) {
3755cfca06d7SDimitry Andric   const llvm::DataLayout &DataLayout = CGM.getDataLayout();
3756cfca06d7SDimitry Andric   int Size = DataLayout.getTypeStoreSize(ATy);
3757cfca06d7SDimitry Andric   SmallVector<uint64_t, 16> Bits(Size);
3758b60736ecSDimitry Andric   setUsedBits(CGM, QTy->castAs<RecordType>(), 0, Bits);
3759cfca06d7SDimitry Andric 
3760cfca06d7SDimitry Andric   // Clear each element of the LLVM array.
3761cfca06d7SDimitry Andric   int CharWidth = CGM.getContext().getCharWidth();
3762cfca06d7SDimitry Andric   int CharsPerElt =
3763cfca06d7SDimitry Andric       ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
3764cfca06d7SDimitry Andric   int MaskIndex = 0;
3765145449b1SDimitry Andric   llvm::Value *R = llvm::PoisonValue::get(ATy);
3766cfca06d7SDimitry Andric   for (int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
3767cfca06d7SDimitry Andric     uint64_t Mask = buildMultiCharMask(Bits, MaskIndex, CharsPerElt, CharWidth,
3768cfca06d7SDimitry Andric                                        DataLayout.isBigEndian());
3769cfca06d7SDimitry Andric     MaskIndex += CharsPerElt;
3770cfca06d7SDimitry Andric     llvm::Value *T0 = Builder.CreateExtractValue(Src, I);
3771cfca06d7SDimitry Andric     llvm::Value *T1 = Builder.CreateAnd(T0, Mask, "cmse.clear");
3772cfca06d7SDimitry Andric     R = Builder.CreateInsertValue(R, T1, I);
3773cfca06d7SDimitry Andric   }
3774cfca06d7SDimitry Andric 
3775cfca06d7SDimitry Andric   return R;
3776cfca06d7SDimitry Andric }
3777cfca06d7SDimitry Andric 
EmitFunctionEpilog(const CGFunctionInfo & FI,bool EmitRetDbgLoc,SourceLocation EndLoc)37786a037251SDimitry Andric void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
3779bfef3995SDimitry Andric                                          bool EmitRetDbgLoc,
3780bfef3995SDimitry Andric                                          SourceLocation EndLoc) {
37816252156dSDimitry Andric   if (FI.isNoReturn()) {
37826252156dSDimitry Andric     // Noreturn functions don't return.
37836252156dSDimitry Andric     EmitUnreachable(EndLoc);
37846252156dSDimitry Andric     return;
37856252156dSDimitry Andric   }
37866252156dSDimitry Andric 
378706d4ba38SDimitry Andric   if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>()) {
378806d4ba38SDimitry Andric     // Naked functions don't have epilogues.
378906d4ba38SDimitry Andric     Builder.CreateUnreachable();
379006d4ba38SDimitry Andric     return;
379106d4ba38SDimitry Andric   }
379206d4ba38SDimitry Andric 
3793ec2b103cSEd Schouten   // Functions with no result always return void.
379445b53394SDimitry Andric   if (!ReturnValue.isValid()) {
37954ba67500SRoman Divacky     Builder.CreateRetVoid();
37964ba67500SRoman Divacky     return;
37974ba67500SRoman Divacky   }
37984ba67500SRoman Divacky 
37993d1dcd9bSDimitry Andric   llvm::DebugLoc RetDbgLoc;
38009f4dbff6SDimitry Andric   llvm::Value *RV = nullptr;
3801ec2b103cSEd Schouten   QualType RetTy = FI.getReturnType();
3802ec2b103cSEd Schouten   const ABIArgInfo &RetAI = FI.getReturnInfo();
3803ec2b103cSEd Schouten 
3804ec2b103cSEd Schouten   switch (RetAI.getKind()) {
38059f4dbff6SDimitry Andric   case ABIArgInfo::InAlloca:
3806e3b55780SDimitry Andric     // Aggregates get evaluated directly into the destination.  Sometimes we
38079f4dbff6SDimitry Andric     // need to return the sret value in a register, though.
38089f4dbff6SDimitry Andric     assert(hasAggregateEvaluationKind(RetTy));
38099f4dbff6SDimitry Andric     if (RetAI.getInAllocaSRet()) {
38109f4dbff6SDimitry Andric       llvm::Function::arg_iterator EI = CurFn->arg_end();
38119f4dbff6SDimitry Andric       --EI;
381245b53394SDimitry Andric       llvm::Value *ArgStruct = &*EI;
38135e20cdd8SDimitry Andric       llvm::Value *SRet = Builder.CreateStructGEP(
3814145449b1SDimitry Andric           FI.getArgStruct(), ArgStruct, RetAI.getInAllocaFieldIndex());
3815344a3780SDimitry Andric       llvm::Type *Ty =
3816344a3780SDimitry Andric           cast<llvm::GetElementPtrInst>(SRet)->getResultElementType();
3817344a3780SDimitry Andric       RV = Builder.CreateAlignedLoad(Ty, SRet, getPointerAlign(), "sret");
38189f4dbff6SDimitry Andric     }
38199f4dbff6SDimitry Andric     break;
38209f4dbff6SDimitry Andric 
38213d1dcd9bSDimitry Andric   case ABIArgInfo::Indirect: {
38229f4dbff6SDimitry Andric     auto AI = CurFn->arg_begin();
38239f4dbff6SDimitry Andric     if (RetAI.isSRetAfterThis())
38249f4dbff6SDimitry Andric       ++AI;
3825809500fcSDimitry Andric     switch (getEvaluationKind(RetTy)) {
3826809500fcSDimitry Andric     case TEK_Complex: {
3827809500fcSDimitry Andric       ComplexPairTy RT =
382845b53394SDimitry Andric         EmitLoadOfComplex(MakeAddrLValue(ReturnValue, RetTy), EndLoc);
382945b53394SDimitry Andric       EmitStoreOfComplex(RT, MakeNaturalAlignAddrLValue(&*AI, RetTy),
3830809500fcSDimitry Andric                          /*isInit*/ true);
3831809500fcSDimitry Andric       break;
3832809500fcSDimitry Andric     }
3833809500fcSDimitry Andric     case TEK_Aggregate:
3834e3b55780SDimitry Andric       // Do nothing; aggregates get evaluated directly into the destination.
3835809500fcSDimitry Andric       break;
383677fc4c14SDimitry Andric     case TEK_Scalar: {
383777fc4c14SDimitry Andric       LValueBaseInfo BaseInfo;
383877fc4c14SDimitry Andric       TBAAAccessInfo TBAAInfo;
383977fc4c14SDimitry Andric       CharUnits Alignment =
384077fc4c14SDimitry Andric           CGM.getNaturalTypeAlignment(RetTy, &BaseInfo, &TBAAInfo);
384177fc4c14SDimitry Andric       Address ArgAddr(&*AI, ConvertType(RetTy), Alignment);
384277fc4c14SDimitry Andric       LValue ArgVal =
384377fc4c14SDimitry Andric           LValue::MakeAddr(ArgAddr, RetTy, getContext(), BaseInfo, TBAAInfo);
384477fc4c14SDimitry Andric       EmitStoreOfScalar(
3845ac9a064cSDimitry Andric           EmitLoadOfScalar(MakeAddrLValue(ReturnValue, RetTy), EndLoc), ArgVal,
3846ac9a064cSDimitry Andric           /*isInit*/ true);
3847809500fcSDimitry Andric       break;
3848ec2b103cSEd Schouten     }
384977fc4c14SDimitry Andric     }
3850ec2b103cSEd Schouten     break;
38513d1dcd9bSDimitry Andric   }
3852ec2b103cSEd Schouten 
385370b4596dSEd Schouten   case ABIArgInfo::Extend:
38543d1dcd9bSDimitry Andric   case ABIArgInfo::Direct:
38553d1dcd9bSDimitry Andric     if (RetAI.getCoerceToType() == ConvertType(RetTy) &&
38563d1dcd9bSDimitry Andric         RetAI.getDirectOffset() == 0) {
38574ba67500SRoman Divacky       // The internal return value temp always will have pointer-to-return-type
38584ba67500SRoman Divacky       // type, just do a load.
3859ec2b103cSEd Schouten 
3860dbe13110SDimitry Andric       // If there is a dominating store to ReturnValue, we can elide
3861dbe13110SDimitry Andric       // the load, zap the store, and usually zap the alloca.
38625e20cdd8SDimitry Andric       if (llvm::StoreInst *SI =
38635e20cdd8SDimitry Andric               findDominatingStoreToReturnValue(*this)) {
3864bfef3995SDimitry Andric         // Reuse the debug location from the store unless there is
3865bfef3995SDimitry Andric         // cleanup code to be emitted between the store and return
3866bfef3995SDimitry Andric         // instruction.
3867bfef3995SDimitry Andric         if (EmitRetDbgLoc && !AutoreleaseResult)
38683d1dcd9bSDimitry Andric           RetDbgLoc = SI->getDebugLoc();
38696a037251SDimitry Andric         // Get the stored value and nuke the now-dead store.
38704ba67500SRoman Divacky         RV = SI->getValueOperand();
38714ba67500SRoman Divacky         SI->eraseFromParent();
38724ba67500SRoman Divacky 
3873dbe13110SDimitry Andric       // Otherwise, we have to do a simple load.
3874dbe13110SDimitry Andric       } else {
3875dbe13110SDimitry Andric         RV = Builder.CreateLoad(ReturnValue);
38764ba67500SRoman Divacky       }
38773d1dcd9bSDimitry Andric     } else {
38783d1dcd9bSDimitry Andric       // If the value is offset in memory, apply the offset now.
387945b53394SDimitry Andric       Address V = emitAddressAtOffset(*this, ReturnValue, RetAI);
38803d1dcd9bSDimitry Andric 
388145b53394SDimitry Andric       RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this);
38823d1dcd9bSDimitry Andric     }
3883180abc3dSDimitry Andric 
3884180abc3dSDimitry Andric     // In ARC, end functions that return a retainable type with a call
3885180abc3dSDimitry Andric     // to objc_autoreleaseReturnValue.
3886180abc3dSDimitry Andric     if (AutoreleaseResult) {
38872b6b257fSDimitry Andric #ifndef NDEBUG
38882b6b257fSDimitry Andric       // Type::isObjCRetainabletype has to be called on a QualType that hasn't
38892b6b257fSDimitry Andric       // been stripped of the typedefs, so we cannot use RetTy here. Get the
38902b6b257fSDimitry Andric       // original return type of FunctionDecl, CurCodeDecl, and BlockDecl from
38912b6b257fSDimitry Andric       // CurCodeDecl or BlockInfo.
38922b6b257fSDimitry Andric       QualType RT;
38932b6b257fSDimitry Andric 
38942b6b257fSDimitry Andric       if (auto *FD = dyn_cast<FunctionDecl>(CurCodeDecl))
38952b6b257fSDimitry Andric         RT = FD->getReturnType();
38962b6b257fSDimitry Andric       else if (auto *MD = dyn_cast<ObjCMethodDecl>(CurCodeDecl))
38972b6b257fSDimitry Andric         RT = MD->getReturnType();
38982b6b257fSDimitry Andric       else if (isa<BlockDecl>(CurCodeDecl))
38992b6b257fSDimitry Andric         RT = BlockInfo->BlockExpression->getFunctionType()->getReturnType();
39002b6b257fSDimitry Andric       else
39012b6b257fSDimitry Andric         llvm_unreachable("Unexpected function/method type");
39022b6b257fSDimitry Andric 
3903dbe13110SDimitry Andric       assert(getLangOpts().ObjCAutoRefCount &&
3904180abc3dSDimitry Andric              !FI.isReturnsRetained() &&
39052b6b257fSDimitry Andric              RT->isObjCRetainableType());
39062b6b257fSDimitry Andric #endif
3907180abc3dSDimitry Andric       RV = emitAutoreleaseOfResult(*this, RV);
3908180abc3dSDimitry Andric     }
3909180abc3dSDimitry Andric 
3910ec2b103cSEd Schouten     break;
3911ec2b103cSEd Schouten 
39123d1dcd9bSDimitry Andric   case ABIArgInfo::Ignore:
3913ec2b103cSEd Schouten     break;
3914ec2b103cSEd Schouten 
39152b6b257fSDimitry Andric   case ABIArgInfo::CoerceAndExpand: {
39162b6b257fSDimitry Andric     auto coercionType = RetAI.getCoerceAndExpandType();
39172b6b257fSDimitry Andric 
39182b6b257fSDimitry Andric     // Load all of the coerced elements out into results.
39192b6b257fSDimitry Andric     llvm::SmallVector<llvm::Value*, 4> results;
39207fa27ce4SDimitry Andric     Address addr = ReturnValue.withElementType(coercionType);
39212b6b257fSDimitry Andric     for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
39222b6b257fSDimitry Andric       auto coercedEltType = coercionType->getElementType(i);
39232b6b257fSDimitry Andric       if (ABIArgInfo::isPaddingForCoerceAndExpand(coercedEltType))
39242b6b257fSDimitry Andric         continue;
39252b6b257fSDimitry Andric 
392622989816SDimitry Andric       auto eltAddr = Builder.CreateStructGEP(addr, i);
39272b6b257fSDimitry Andric       auto elt = Builder.CreateLoad(eltAddr);
39282b6b257fSDimitry Andric       results.push_back(elt);
39292b6b257fSDimitry Andric     }
39302b6b257fSDimitry Andric 
39312b6b257fSDimitry Andric     // If we have one result, it's the single direct result type.
39322b6b257fSDimitry Andric     if (results.size() == 1) {
39332b6b257fSDimitry Andric       RV = results[0];
39342b6b257fSDimitry Andric 
39352b6b257fSDimitry Andric     // Otherwise, we need to make a first-class aggregate.
39362b6b257fSDimitry Andric     } else {
39372b6b257fSDimitry Andric       // Construct a return type that lacks padding elements.
39382b6b257fSDimitry Andric       llvm::Type *returnType = RetAI.getUnpaddedCoerceAndExpandType();
39392b6b257fSDimitry Andric 
3940145449b1SDimitry Andric       RV = llvm::PoisonValue::get(returnType);
39412b6b257fSDimitry Andric       for (unsigned i = 0, e = results.size(); i != e; ++i) {
39422b6b257fSDimitry Andric         RV = Builder.CreateInsertValue(RV, results[i], i);
39432b6b257fSDimitry Andric       }
39442b6b257fSDimitry Andric     }
39452b6b257fSDimitry Andric     break;
39462b6b257fSDimitry Andric   }
3947ec2b103cSEd Schouten   case ABIArgInfo::Expand:
3948b60736ecSDimitry Andric   case ABIArgInfo::IndirectAliased:
394936981b17SDimitry Andric     llvm_unreachable("Invalid ABI kind for return argument");
3950ec2b103cSEd Schouten   }
3951ec2b103cSEd Schouten 
395206d4ba38SDimitry Andric   llvm::Instruction *Ret;
395306d4ba38SDimitry Andric   if (RV) {
3954cfca06d7SDimitry Andric     if (CurFuncDecl && CurFuncDecl->hasAttr<CmseNSEntryAttr>()) {
3955cfca06d7SDimitry Andric       // For certain return types, clear padding bits, as they may reveal
3956cfca06d7SDimitry Andric       // sensitive information.
3957cfca06d7SDimitry Andric       // Small struct/union types are passed as integers.
3958cfca06d7SDimitry Andric       auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
3959cfca06d7SDimitry Andric       if (ITy != nullptr && isa<RecordType>(RetTy.getCanonicalType()))
3960cfca06d7SDimitry Andric         RV = EmitCMSEClearRecord(RV, ITy, RetTy);
3961cfca06d7SDimitry Andric     }
3962ef915aabSDimitry Andric     EmitReturnValueCheck(RV);
396306d4ba38SDimitry Andric     Ret = Builder.CreateRet(RV);
396406d4ba38SDimitry Andric   } else {
396506d4ba38SDimitry Andric     Ret = Builder.CreateRetVoid();
396606d4ba38SDimitry Andric   }
396706d4ba38SDimitry Andric 
39685e20cdd8SDimitry Andric   if (RetDbgLoc)
39695e20cdd8SDimitry Andric     Ret->setDebugLoc(std::move(RetDbgLoc));
3970ec2b103cSEd Schouten }
3971ec2b103cSEd Schouten 
EmitReturnValueCheck(llvm::Value * RV)3972ef915aabSDimitry Andric void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
39737442d6faSDimitry Andric   // A current decl may not be available when emitting vtable thunks.
39747442d6faSDimitry Andric   if (!CurCodeDecl)
39757442d6faSDimitry Andric     return;
39767442d6faSDimitry Andric 
3977cfca06d7SDimitry Andric   // If the return block isn't reachable, neither is this check, so don't emit
3978cfca06d7SDimitry Andric   // it.
3979cfca06d7SDimitry Andric   if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty())
3980cfca06d7SDimitry Andric     return;
3981cfca06d7SDimitry Andric 
39827442d6faSDimitry Andric   ReturnsNonNullAttr *RetNNAttr = nullptr;
39837442d6faSDimitry Andric   if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
39847442d6faSDimitry Andric     RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>();
39857442d6faSDimitry Andric 
39867442d6faSDimitry Andric   if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
39877442d6faSDimitry Andric     return;
39887442d6faSDimitry Andric 
39897442d6faSDimitry Andric   // Prefer the returns_nonnull attribute if it's present.
39907442d6faSDimitry Andric   SourceLocation AttrLoc;
39917442d6faSDimitry Andric   SanitizerMask CheckKind;
39927442d6faSDimitry Andric   SanitizerHandler Handler;
39937442d6faSDimitry Andric   if (RetNNAttr) {
39947442d6faSDimitry Andric     assert(!requiresReturnValueNullabilityCheck() &&
39957442d6faSDimitry Andric            "Cannot check nullability and the nonnull attribute");
39967442d6faSDimitry Andric     AttrLoc = RetNNAttr->getLocation();
39977442d6faSDimitry Andric     CheckKind = SanitizerKind::ReturnsNonnullAttribute;
39987442d6faSDimitry Andric     Handler = SanitizerHandler::NonnullReturn;
39997442d6faSDimitry Andric   } else {
40007442d6faSDimitry Andric     if (auto *DD = dyn_cast<DeclaratorDecl>(CurCodeDecl))
40017442d6faSDimitry Andric       if (auto *TSI = DD->getTypeSourceInfo())
4002cfca06d7SDimitry Andric         if (auto FTL = TSI->getTypeLoc().getAsAdjusted<FunctionTypeLoc>())
40037442d6faSDimitry Andric           AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
40047442d6faSDimitry Andric     CheckKind = SanitizerKind::NullabilityReturn;
40057442d6faSDimitry Andric     Handler = SanitizerHandler::NullabilityReturn;
40067442d6faSDimitry Andric   }
40077442d6faSDimitry Andric 
40087442d6faSDimitry Andric   SanitizerScope SanScope(this);
40097442d6faSDimitry Andric 
4010ef915aabSDimitry Andric   // Make sure the "return" source location is valid. If we're checking a
4011ef915aabSDimitry Andric   // nullability annotation, make sure the preconditions for the check are met.
4012ef915aabSDimitry Andric   llvm::BasicBlock *Check = createBasicBlock("nullcheck");
4013ef915aabSDimitry Andric   llvm::BasicBlock *NoCheck = createBasicBlock("no.nullcheck");
4014ef915aabSDimitry Andric   llvm::Value *SLocPtr = Builder.CreateLoad(ReturnLocation, "return.sloc.load");
4015ef915aabSDimitry Andric   llvm::Value *CanNullCheck = Builder.CreateIsNotNull(SLocPtr);
40167442d6faSDimitry Andric   if (requiresReturnValueNullabilityCheck())
4017ef915aabSDimitry Andric     CanNullCheck =
4018ef915aabSDimitry Andric         Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
4019ef915aabSDimitry Andric   Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
4020ef915aabSDimitry Andric   EmitBlock(Check);
4021ef915aabSDimitry Andric 
4022ef915aabSDimitry Andric   // Now do the null check.
4023ef915aabSDimitry Andric   llvm::Value *Cond = Builder.CreateIsNotNull(RV);
4024ef915aabSDimitry Andric   llvm::Constant *StaticData[] = {EmitCheckSourceLocation(AttrLoc)};
4025ef915aabSDimitry Andric   llvm::Value *DynamicData[] = {SLocPtr};
4026ef915aabSDimitry Andric   EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, DynamicData);
4027ef915aabSDimitry Andric 
40287442d6faSDimitry Andric   EmitBlock(NoCheck);
4029ef915aabSDimitry Andric 
4030ef915aabSDimitry Andric #ifndef NDEBUG
4031ef915aabSDimitry Andric   // The return location should not be used after the check has been emitted.
4032ef915aabSDimitry Andric   ReturnLocation = Address::invalid();
4033ef915aabSDimitry Andric #endif
40347442d6faSDimitry Andric }
40357442d6faSDimitry Andric 
isInAllocaArgument(CGCXXABI & ABI,QualType type)40369f4dbff6SDimitry Andric static bool isInAllocaArgument(CGCXXABI &ABI, QualType type) {
40379f4dbff6SDimitry Andric   const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
40389f4dbff6SDimitry Andric   return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
40399f4dbff6SDimitry Andric }
40409f4dbff6SDimitry Andric 
createPlaceholderSlot(CodeGenFunction & CGF,QualType Ty)404145b53394SDimitry Andric static AggValueSlot createPlaceholderSlot(CodeGenFunction &CGF,
404245b53394SDimitry Andric                                           QualType Ty) {
40439f4dbff6SDimitry Andric   // FIXME: Generate IR in one pass, rather than going back and fixing up these
40449f4dbff6SDimitry Andric   // placeholders.
40459f4dbff6SDimitry Andric   llvm::Type *IRTy = CGF.ConvertTypeForMem(Ty);
40467fa27ce4SDimitry Andric   llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
40477fa27ce4SDimitry Andric   llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
404845b53394SDimitry Andric 
404945b53394SDimitry Andric   // FIXME: When we generate this IR in one pass, we shouldn't need
405045b53394SDimitry Andric   // this win32-specific alignment hack.
405145b53394SDimitry Andric   CharUnits Align = CharUnits::fromQuantity(4);
4052bab175ecSDimitry Andric   Placeholder = CGF.Builder.CreateAlignedLoad(IRPtrTy, Placeholder, Align);
405345b53394SDimitry Andric 
4054145449b1SDimitry Andric   return AggValueSlot::forAddr(Address(Placeholder, IRTy, Align),
40559f4dbff6SDimitry Andric                                Ty.getQualifiers(),
40569f4dbff6SDimitry Andric                                AggValueSlot::IsNotDestructed,
40579f4dbff6SDimitry Andric                                AggValueSlot::DoesNotNeedGCBarriers,
405848675466SDimitry Andric                                AggValueSlot::IsNotAliased,
405948675466SDimitry Andric                                AggValueSlot::DoesNotOverlap);
40609f4dbff6SDimitry Andric }
40619f4dbff6SDimitry Andric 
EmitDelegateCallArg(CallArgList & args,const VarDecl * param,SourceLocation loc)406201af97d3SDimitry Andric void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
4063bfef3995SDimitry Andric                                           const VarDecl *param,
4064bfef3995SDimitry Andric                                           SourceLocation loc) {
4065d7279c4cSRoman Divacky   // StartFunction converted the ABI-lowered parameter(s) into a
4066d7279c4cSRoman Divacky   // local alloca.  We need to turn that into an r-value suitable
4067d7279c4cSRoman Divacky   // for EmitCall.
406845b53394SDimitry Andric   Address local = GetAddrOfLocalVar(param);
4069d7279c4cSRoman Divacky 
407001af97d3SDimitry Andric   QualType type = param->getType();
4071d7279c4cSRoman Divacky 
4072bab175ecSDimitry Andric   // GetAddrOfLocalVar returns a pointer-to-pointer for references,
4073bab175ecSDimitry Andric   // but the argument needs to be the original pointer.
4074bab175ecSDimitry Andric   if (type->isReferenceType()) {
4075bab175ecSDimitry Andric     args.add(RValue::get(Builder.CreateLoad(local)), type);
4076bab175ecSDimitry Andric 
4077bab175ecSDimitry Andric   // In ARC, move out of consumed arguments so that the release cleanup
4078bab175ecSDimitry Andric   // entered by StartFunction doesn't cause an over-release.  This isn't
4079bab175ecSDimitry Andric   // optimal -O0 code generation, but it should get cleaned up when
4080bab175ecSDimitry Andric   // optimization is enabled.  This also assumes that delegate calls are
4081bab175ecSDimitry Andric   // performed exactly once for a set of arguments, but that should be safe.
4082bab175ecSDimitry Andric   } else if (getLangOpts().ObjCAutoRefCount &&
4083bab175ecSDimitry Andric              param->hasAttr<NSConsumedAttr>() &&
4084bab175ecSDimitry Andric              type->isObjCRetainableType()) {
4085bab175ecSDimitry Andric     llvm::Value *ptr = Builder.CreateLoad(local);
4086bab175ecSDimitry Andric     auto null =
4087bab175ecSDimitry Andric       llvm::ConstantPointerNull::get(cast<llvm::PointerType>(ptr->getType()));
4088bab175ecSDimitry Andric     Builder.CreateStore(null, local);
4089bab175ecSDimitry Andric     args.add(RValue::get(ptr), type);
4090bab175ecSDimitry Andric 
40912b6b257fSDimitry Andric   // For the most part, we just need to load the alloca, except that
40922b6b257fSDimitry Andric   // aggregate r-values are actually pointers to temporaries.
4093bab175ecSDimitry Andric   } else {
4094bfef3995SDimitry Andric     args.add(convertTempToRValue(local, type, loc), type);
409501af97d3SDimitry Andric   }
409648675466SDimitry Andric 
409748675466SDimitry Andric   // Deactivate the cleanup for the callee-destructed param that was pushed.
4098344a3780SDimitry Andric   if (type->isRecordType() && !CurFuncIsThunk &&
4099519fc96cSDimitry Andric       type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee() &&
4100519fc96cSDimitry Andric       param->needsDestruction(getContext())) {
410148675466SDimitry Andric     EHScopeStack::stable_iterator cleanup =
410248675466SDimitry Andric         CalleeDestructedParamCleanups.lookup(cast<ParmVarDecl>(param));
410348675466SDimitry Andric     assert(cleanup.isValid() &&
410448675466SDimitry Andric            "cleanup for callee-destructed param not recorded");
410548675466SDimitry Andric     // This unreachable is a temporary marker which will be removed later.
410648675466SDimitry Andric     llvm::Instruction *isActive = Builder.CreateUnreachable();
410748675466SDimitry Andric     args.addArgCleanupDeactivation(cleanup, isActive);
410848675466SDimitry Andric   }
4109bab175ecSDimitry Andric }
411001af97d3SDimitry Andric 
isProvablyNull(llvm::Value * addr)4111180abc3dSDimitry Andric static bool isProvablyNull(llvm::Value *addr) {
4112ac9a064cSDimitry Andric   return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
4113ac9a064cSDimitry Andric }
4114ac9a064cSDimitry Andric 
isProvablyNonNull(Address Addr,CodeGenFunction & CGF)4115ac9a064cSDimitry Andric static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
4116ac9a064cSDimitry Andric   return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
4117180abc3dSDimitry Andric }
4118180abc3dSDimitry Andric 
4119180abc3dSDimitry Andric /// Emit the actual writing-back of a writeback.
emitWriteback(CodeGenFunction & CGF,const CallArgList::Writeback & writeback)4120180abc3dSDimitry Andric static void emitWriteback(CodeGenFunction &CGF,
4121180abc3dSDimitry Andric                           const CallArgList::Writeback &writeback) {
4122809500fcSDimitry Andric   const LValue &srcLV = writeback.Source;
4123ac9a064cSDimitry Andric   Address srcAddr = srcLV.getAddress();
4124ac9a064cSDimitry Andric   assert(!isProvablyNull(srcAddr.getBasePointer()) &&
4125180abc3dSDimitry Andric          "shouldn't have writeback for provably null argument");
4126180abc3dSDimitry Andric 
41279f4dbff6SDimitry Andric   llvm::BasicBlock *contBB = nullptr;
4128180abc3dSDimitry Andric 
4129180abc3dSDimitry Andric   // If the argument wasn't provably non-null, we need to null check
4130180abc3dSDimitry Andric   // before doing the store.
4131ac9a064cSDimitry Andric   bool provablyNonNull = isProvablyNonNull(srcAddr, CGF);
4132ac9a064cSDimitry Andric 
4133180abc3dSDimitry Andric   if (!provablyNonNull) {
4134180abc3dSDimitry Andric     llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback");
4135180abc3dSDimitry Andric     contBB = CGF.createBasicBlock("icr.done");
4136180abc3dSDimitry Andric 
4137ac9a064cSDimitry Andric     llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull");
4138180abc3dSDimitry Andric     CGF.Builder.CreateCondBr(isNull, contBB, writebackBB);
4139180abc3dSDimitry Andric     CGF.EmitBlock(writebackBB);
4140180abc3dSDimitry Andric   }
4141180abc3dSDimitry Andric 
4142180abc3dSDimitry Andric   // Load the value to writeback.
4143180abc3dSDimitry Andric   llvm::Value *value = CGF.Builder.CreateLoad(writeback.Temporary);
4144180abc3dSDimitry Andric 
4145180abc3dSDimitry Andric   // Cast it back, in case we're writing an id to a Foo* or something.
414645b53394SDimitry Andric   value = CGF.Builder.CreateBitCast(value, srcAddr.getElementType(),
4147180abc3dSDimitry Andric                                     "icr.writeback-cast");
4148180abc3dSDimitry Andric 
4149180abc3dSDimitry Andric   // Perform the writeback.
4150809500fcSDimitry Andric 
4151809500fcSDimitry Andric   // If we have a "to use" value, it's something we need to emit a use
4152809500fcSDimitry Andric   // of.  This has to be carefully threaded in: if it's done after the
4153809500fcSDimitry Andric   // release it's potentially undefined behavior (and the optimizer
4154809500fcSDimitry Andric   // will ignore it), and if it happens before the retain then the
4155809500fcSDimitry Andric   // optimizer could move the release there.
4156809500fcSDimitry Andric   if (writeback.ToUse) {
4157809500fcSDimitry Andric     assert(srcLV.getObjCLifetime() == Qualifiers::OCL_Strong);
4158809500fcSDimitry Andric 
4159809500fcSDimitry Andric     // Retain the new value.  No need to block-copy here:  the block's
4160809500fcSDimitry Andric     // being passed up the stack.
4161809500fcSDimitry Andric     value = CGF.EmitARCRetainNonBlock(value);
4162809500fcSDimitry Andric 
4163809500fcSDimitry Andric     // Emit the intrinsic use here.
4164809500fcSDimitry Andric     CGF.EmitARCIntrinsicUse(writeback.ToUse);
4165809500fcSDimitry Andric 
4166809500fcSDimitry Andric     // Load the old value (primitively).
4167bfef3995SDimitry Andric     llvm::Value *oldValue = CGF.EmitLoadOfScalar(srcLV, SourceLocation());
4168809500fcSDimitry Andric 
4169809500fcSDimitry Andric     // Put the new value in place (primitively).
4170809500fcSDimitry Andric     CGF.EmitStoreOfScalar(value, srcLV, /*init*/ false);
4171809500fcSDimitry Andric 
4172809500fcSDimitry Andric     // Release the old value.
4173809500fcSDimitry Andric     CGF.EmitARCRelease(oldValue, srcLV.isARCPreciseLifetime());
4174809500fcSDimitry Andric 
4175809500fcSDimitry Andric   // Otherwise, we can just do a normal lvalue store.
4176809500fcSDimitry Andric   } else {
4177809500fcSDimitry Andric     CGF.EmitStoreThroughLValue(RValue::get(value), srcLV);
4178809500fcSDimitry Andric   }
4179180abc3dSDimitry Andric 
4180180abc3dSDimitry Andric   // Jump to the continuation block.
4181180abc3dSDimitry Andric   if (!provablyNonNull)
4182180abc3dSDimitry Andric     CGF.EmitBlock(contBB);
4183180abc3dSDimitry Andric }
4184180abc3dSDimitry Andric 
emitWritebacks(CodeGenFunction & CGF,const CallArgList & args)4185180abc3dSDimitry Andric static void emitWritebacks(CodeGenFunction &CGF,
4186180abc3dSDimitry Andric                            const CallArgList &args) {
41879f4dbff6SDimitry Andric   for (const auto &I : args.writebacks())
41889f4dbff6SDimitry Andric     emitWriteback(CGF, I);
4189180abc3dSDimitry Andric }
4190180abc3dSDimitry Andric 
deactivateArgCleanupsBeforeCall(CodeGenFunction & CGF,const CallArgList & CallArgs)4191bfef3995SDimitry Andric static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF,
4192bfef3995SDimitry Andric                                             const CallArgList &CallArgs) {
4193bfef3995SDimitry Andric   ArrayRef<CallArgList::CallArgCleanup> Cleanups =
4194bfef3995SDimitry Andric     CallArgs.getCleanupsToDeactivate();
4195bfef3995SDimitry Andric   // Iterate in reverse to increase the likelihood of popping the cleanup.
419645b53394SDimitry Andric   for (const auto &I : llvm::reverse(Cleanups)) {
419745b53394SDimitry Andric     CGF.DeactivateCleanupBlock(I.Cleanup, I.IsActiveIP);
419845b53394SDimitry Andric     I.IsActiveIP->eraseFromParent();
4199bfef3995SDimitry Andric   }
4200bfef3995SDimitry Andric }
4201bfef3995SDimitry Andric 
maybeGetUnaryAddrOfOperand(const Expr * E)4202809500fcSDimitry Andric static const Expr *maybeGetUnaryAddrOfOperand(const Expr *E) {
4203809500fcSDimitry Andric   if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E->IgnoreParens()))
4204809500fcSDimitry Andric     if (uop->getOpcode() == UO_AddrOf)
4205809500fcSDimitry Andric       return uop->getSubExpr();
42069f4dbff6SDimitry Andric   return nullptr;
4207809500fcSDimitry Andric }
4208809500fcSDimitry Andric 
4209180abc3dSDimitry Andric /// Emit an argument that's being passed call-by-writeback.  That is,
421045b53394SDimitry Andric /// we are passing the address of an __autoreleased temporary; it
421145b53394SDimitry Andric /// might be copy-initialized with the current value of the given
421245b53394SDimitry Andric /// address, but it will definitely be copied out of after the call.
emitWritebackArg(CodeGenFunction & CGF,CallArgList & args,const ObjCIndirectCopyRestoreExpr * CRE)4213180abc3dSDimitry Andric static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
4214180abc3dSDimitry Andric                              const ObjCIndirectCopyRestoreExpr *CRE) {
4215809500fcSDimitry Andric   LValue srcLV;
4216809500fcSDimitry Andric 
4217809500fcSDimitry Andric   // Make an optimistic effort to emit the address as an l-value.
42182e645aa5SDimitry Andric   // This can fail if the argument expression is more complicated.
4219809500fcSDimitry Andric   if (const Expr *lvExpr = maybeGetUnaryAddrOfOperand(CRE->getSubExpr())) {
4220809500fcSDimitry Andric     srcLV = CGF.EmitLValue(lvExpr);
4221809500fcSDimitry Andric 
4222809500fcSDimitry Andric   // Otherwise, just emit it as a scalar.
4223809500fcSDimitry Andric   } else {
422445b53394SDimitry Andric     Address srcAddr = CGF.EmitPointerWithAlignment(CRE->getSubExpr());
4225180abc3dSDimitry Andric 
4226809500fcSDimitry Andric     QualType srcAddrType =
4227809500fcSDimitry Andric       CRE->getSubExpr()->getType()->castAs<PointerType>()->getPointeeType();
422845b53394SDimitry Andric     srcLV = CGF.MakeAddrLValue(srcAddr, srcAddrType);
4229809500fcSDimitry Andric   }
4230ac9a064cSDimitry Andric   Address srcAddr = srcLV.getAddress();
4231809500fcSDimitry Andric 
4232180abc3dSDimitry Andric   // The dest and src types don't necessarily match in LLVM terms
4233180abc3dSDimitry Andric   // because of the crazy ObjC compatibility rules.
4234180abc3dSDimitry Andric 
423536981b17SDimitry Andric   llvm::PointerType *destType =
4236180abc3dSDimitry Andric       cast<llvm::PointerType>(CGF.ConvertType(CRE->getType()));
4237145449b1SDimitry Andric   llvm::Type *destElemType =
4238145449b1SDimitry Andric       CGF.ConvertTypeForMem(CRE->getType()->getPointeeType());
4239180abc3dSDimitry Andric 
4240180abc3dSDimitry Andric   // If the address is a constant null, just pass the appropriate null.
4241ac9a064cSDimitry Andric   if (isProvablyNull(srcAddr.getBasePointer())) {
4242180abc3dSDimitry Andric     args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
4243180abc3dSDimitry Andric              CRE->getType());
4244180abc3dSDimitry Andric     return;
4245180abc3dSDimitry Andric   }
4246180abc3dSDimitry Andric 
4247180abc3dSDimitry Andric   // Create the temporary.
4248145449b1SDimitry Andric   Address temp =
4249145449b1SDimitry Andric       CGF.CreateTempAlloca(destElemType, CGF.getPointerAlign(), "icr.temp");
4250809500fcSDimitry Andric   // Loading an l-value can introduce a cleanup if the l-value is __weak,
4251809500fcSDimitry Andric   // and that cleanup will be conditional if we can't prove that the l-value
4252809500fcSDimitry Andric   // isn't null, so we need to register a dominating point so that the cleanups
4253809500fcSDimitry Andric   // system will make valid IR.
4254809500fcSDimitry Andric   CodeGenFunction::ConditionalEvaluation condEval(CGF);
4255180abc3dSDimitry Andric 
4256180abc3dSDimitry Andric   // Zero-initialize it if we're not doing a copy-initialization.
4257180abc3dSDimitry Andric   bool shouldCopy = CRE->shouldCopy();
4258180abc3dSDimitry Andric   if (!shouldCopy) {
4259145449b1SDimitry Andric     llvm::Value *null =
4260145449b1SDimitry Andric         llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destElemType));
4261180abc3dSDimitry Andric     CGF.Builder.CreateStore(null, temp);
4262180abc3dSDimitry Andric   }
4263180abc3dSDimitry Andric 
42649f4dbff6SDimitry Andric   llvm::BasicBlock *contBB = nullptr;
42659f4dbff6SDimitry Andric   llvm::BasicBlock *originBB = nullptr;
4266180abc3dSDimitry Andric 
4267180abc3dSDimitry Andric   // If the address is *not* known to be non-null, we need to switch.
4268180abc3dSDimitry Andric   llvm::Value *finalArgument;
4269180abc3dSDimitry Andric 
4270ac9a064cSDimitry Andric   bool provablyNonNull = isProvablyNonNull(srcAddr, CGF);
4271180abc3dSDimitry Andric 
4272ac9a064cSDimitry Andric   if (provablyNonNull) {
4273ac9a064cSDimitry Andric     finalArgument = temp.emitRawPointer(CGF);
4274ac9a064cSDimitry Andric   } else {
4275ac9a064cSDimitry Andric     llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull");
4276ac9a064cSDimitry Andric 
4277ac9a064cSDimitry Andric     finalArgument = CGF.Builder.CreateSelect(
4278ac9a064cSDimitry Andric         isNull, llvm::ConstantPointerNull::get(destType),
4279ac9a064cSDimitry Andric         temp.emitRawPointer(CGF), "icr.argument");
4280180abc3dSDimitry Andric 
4281180abc3dSDimitry Andric     // If we need to copy, then the load has to be conditional, which
4282180abc3dSDimitry Andric     // means we need control flow.
4283180abc3dSDimitry Andric     if (shouldCopy) {
4284809500fcSDimitry Andric       originBB = CGF.Builder.GetInsertBlock();
4285180abc3dSDimitry Andric       contBB = CGF.createBasicBlock("icr.cont");
4286180abc3dSDimitry Andric       llvm::BasicBlock *copyBB = CGF.createBasicBlock("icr.copy");
4287180abc3dSDimitry Andric       CGF.Builder.CreateCondBr(isNull, contBB, copyBB);
4288180abc3dSDimitry Andric       CGF.EmitBlock(copyBB);
4289809500fcSDimitry Andric       condEval.begin(CGF);
4290180abc3dSDimitry Andric     }
4291180abc3dSDimitry Andric   }
4292180abc3dSDimitry Andric 
42939f4dbff6SDimitry Andric   llvm::Value *valueToUse = nullptr;
4294809500fcSDimitry Andric 
4295180abc3dSDimitry Andric   // Perform a copy if necessary.
4296180abc3dSDimitry Andric   if (shouldCopy) {
4297bfef3995SDimitry Andric     RValue srcRV = CGF.EmitLoadOfLValue(srcLV, SourceLocation());
4298180abc3dSDimitry Andric     assert(srcRV.isScalar());
4299180abc3dSDimitry Andric 
4300180abc3dSDimitry Andric     llvm::Value *src = srcRV.getScalarVal();
4301145449b1SDimitry Andric     src = CGF.Builder.CreateBitCast(src, destElemType, "icr.cast");
4302180abc3dSDimitry Andric 
4303180abc3dSDimitry Andric     // Use an ordinary store, not a store-to-lvalue.
4304180abc3dSDimitry Andric     CGF.Builder.CreateStore(src, temp);
4305809500fcSDimitry Andric 
4306809500fcSDimitry Andric     // If optimization is enabled, and the value was held in a
4307809500fcSDimitry Andric     // __strong variable, we need to tell the optimizer that this
4308809500fcSDimitry Andric     // value has to stay alive until we're doing the store back.
4309809500fcSDimitry Andric     // This is because the temporary is effectively unretained,
4310809500fcSDimitry Andric     // and so otherwise we can violate the high-level semantics.
4311809500fcSDimitry Andric     if (CGF.CGM.getCodeGenOpts().OptimizationLevel != 0 &&
4312809500fcSDimitry Andric         srcLV.getObjCLifetime() == Qualifiers::OCL_Strong) {
4313809500fcSDimitry Andric       valueToUse = src;
4314809500fcSDimitry Andric     }
4315180abc3dSDimitry Andric   }
4316180abc3dSDimitry Andric 
4317180abc3dSDimitry Andric   // Finish the control flow if we needed it.
4318809500fcSDimitry Andric   if (shouldCopy && !provablyNonNull) {
4319809500fcSDimitry Andric     llvm::BasicBlock *copyBB = CGF.Builder.GetInsertBlock();
4320180abc3dSDimitry Andric     CGF.EmitBlock(contBB);
4321180abc3dSDimitry Andric 
4322809500fcSDimitry Andric     // Make a phi for the value to intrinsically use.
4323809500fcSDimitry Andric     if (valueToUse) {
4324809500fcSDimitry Andric       llvm::PHINode *phiToUse = CGF.Builder.CreatePHI(valueToUse->getType(), 2,
4325809500fcSDimitry Andric                                                       "icr.to-use");
4326809500fcSDimitry Andric       phiToUse->addIncoming(valueToUse, copyBB);
4327809500fcSDimitry Andric       phiToUse->addIncoming(llvm::UndefValue::get(valueToUse->getType()),
4328809500fcSDimitry Andric                             originBB);
4329809500fcSDimitry Andric       valueToUse = phiToUse;
4330809500fcSDimitry Andric     }
4331809500fcSDimitry Andric 
4332809500fcSDimitry Andric     condEval.end(CGF);
4333809500fcSDimitry Andric   }
4334809500fcSDimitry Andric 
4335809500fcSDimitry Andric   args.addWriteback(srcLV, temp, valueToUse);
4336180abc3dSDimitry Andric   args.add(RValue::get(finalArgument), CRE->getType());
4337180abc3dSDimitry Andric }
4338180abc3dSDimitry Andric 
allocateArgumentMemory(CodeGenFunction & CGF)43399f4dbff6SDimitry Andric void CallArgList::allocateArgumentMemory(CodeGenFunction &CGF) {
4340bab175ecSDimitry Andric   assert(!StackBase);
43419f4dbff6SDimitry Andric 
43429f4dbff6SDimitry Andric   // Save the stack.
4343b1c73532SDimitry Andric   StackBase = CGF.Builder.CreateStackSave("inalloca.save");
43449f4dbff6SDimitry Andric }
43459f4dbff6SDimitry Andric 
freeArgumentMemory(CodeGenFunction & CGF) const43469f4dbff6SDimitry Andric void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const {
43479f4dbff6SDimitry Andric   if (StackBase) {
434845b53394SDimitry Andric     // Restore the stack after the call.
4349b1c73532SDimitry Andric     CGF.Builder.CreateStackRestore(StackBase);
43509f4dbff6SDimitry Andric   }
43519f4dbff6SDimitry Andric }
43529f4dbff6SDimitry Andric 
EmitNonNullArgCheck(RValue RV,QualType ArgType,SourceLocation ArgLoc,AbstractCallee AC,unsigned ParmNum)4353798321d8SDimitry Andric void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
4354798321d8SDimitry Andric                                           SourceLocation ArgLoc,
43557442d6faSDimitry Andric                                           AbstractCallee AC,
4356798321d8SDimitry Andric                                           unsigned ParmNum) {
43577442d6faSDimitry Andric   if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
43587442d6faSDimitry Andric                          SanOpts.has(SanitizerKind::NullabilityArg)))
435906d4ba38SDimitry Andric     return;
43607442d6faSDimitry Andric 
43617442d6faSDimitry Andric   // The param decl may be missing in a variadic function.
43627442d6faSDimitry Andric   auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) : nullptr;
436306d4ba38SDimitry Andric   unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
43647442d6faSDimitry Andric 
43657442d6faSDimitry Andric   // Prefer the nonnull attribute if it's present.
43667442d6faSDimitry Andric   const NonNullAttr *NNAttr = nullptr;
43677442d6faSDimitry Andric   if (SanOpts.has(SanitizerKind::NonnullAttribute))
43687442d6faSDimitry Andric     NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo);
43697442d6faSDimitry Andric 
43707442d6faSDimitry Andric   bool CanCheckNullability = false;
4371ac9a064cSDimitry Andric   if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
4372ac9a064cSDimitry Andric       !PVD->getType()->isRecordType()) {
4373e3b55780SDimitry Andric     auto Nullability = PVD->getType()->getNullability();
43747442d6faSDimitry Andric     CanCheckNullability = Nullability &&
43757442d6faSDimitry Andric                           *Nullability == NullabilityKind::NonNull &&
43767442d6faSDimitry Andric                           PVD->getTypeSourceInfo();
43777442d6faSDimitry Andric   }
43787442d6faSDimitry Andric 
43797442d6faSDimitry Andric   if (!NNAttr && !CanCheckNullability)
438006d4ba38SDimitry Andric     return;
43817442d6faSDimitry Andric 
43827442d6faSDimitry Andric   SourceLocation AttrLoc;
43837442d6faSDimitry Andric   SanitizerMask CheckKind;
43847442d6faSDimitry Andric   SanitizerHandler Handler;
43857442d6faSDimitry Andric   if (NNAttr) {
43867442d6faSDimitry Andric     AttrLoc = NNAttr->getLocation();
43877442d6faSDimitry Andric     CheckKind = SanitizerKind::NonnullAttribute;
43887442d6faSDimitry Andric     Handler = SanitizerHandler::NonnullArg;
43897442d6faSDimitry Andric   } else {
43907442d6faSDimitry Andric     AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
43917442d6faSDimitry Andric     CheckKind = SanitizerKind::NullabilityArg;
43927442d6faSDimitry Andric     Handler = SanitizerHandler::NullabilityArg;
43937442d6faSDimitry Andric   }
43947442d6faSDimitry Andric 
4395798321d8SDimitry Andric   SanitizerScope SanScope(this);
4396b60736ecSDimitry Andric   llvm::Value *Cond = EmitNonNullRValueCheck(RV, ArgType);
439706d4ba38SDimitry Andric   llvm::Constant *StaticData[] = {
43987442d6faSDimitry Andric       EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc),
4399798321d8SDimitry Andric       llvm::ConstantInt::get(Int32Ty, ArgNo + 1),
440006d4ba38SDimitry Andric   };
4401e3b55780SDimitry Andric   EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt);
440206d4ba38SDimitry Andric }
440306d4ba38SDimitry Andric 
EmitNonNullArgCheck(Address Addr,QualType ArgType,SourceLocation ArgLoc,AbstractCallee AC,unsigned ParmNum)4404ac9a064cSDimitry Andric void CodeGenFunction::EmitNonNullArgCheck(Address Addr, QualType ArgType,
4405ac9a064cSDimitry Andric                                           SourceLocation ArgLoc,
4406ac9a064cSDimitry Andric                                           AbstractCallee AC, unsigned ParmNum) {
4407ac9a064cSDimitry Andric   if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
4408ac9a064cSDimitry Andric                          SanOpts.has(SanitizerKind::NullabilityArg)))
4409ac9a064cSDimitry Andric     return;
4410ac9a064cSDimitry Andric 
4411ac9a064cSDimitry Andric   EmitNonNullArgCheck(RValue::get(Addr, *this), ArgType, ArgLoc, AC, ParmNum);
4412ac9a064cSDimitry Andric }
4413ac9a064cSDimitry Andric 
4414b60736ecSDimitry Andric // Check if the call is going to use the inalloca convention. This needs to
4415b60736ecSDimitry Andric // agree with CGFunctionInfo::usesInAlloca. The CGFunctionInfo is arranged
4416b60736ecSDimitry Andric // later, so we can't check it directly.
hasInAllocaArgs(CodeGenModule & CGM,CallingConv ExplicitCC,ArrayRef<QualType> ArgTypes)4417b60736ecSDimitry Andric static bool hasInAllocaArgs(CodeGenModule &CGM, CallingConv ExplicitCC,
4418b60736ecSDimitry Andric                             ArrayRef<QualType> ArgTypes) {
4419344a3780SDimitry Andric   // The Swift calling conventions don't go through the target-specific
4420344a3780SDimitry Andric   // argument classification, they never use inalloca.
4421b60736ecSDimitry Andric   // TODO: Consider limiting inalloca use to only calling conventions supported
4422b60736ecSDimitry Andric   // by MSVC.
4423344a3780SDimitry Andric   if (ExplicitCC == CC_Swift || ExplicitCC == CC_SwiftAsync)
4424b60736ecSDimitry Andric     return false;
4425b60736ecSDimitry Andric   if (!CGM.getTarget().getCXXABI().isMicrosoft())
4426b60736ecSDimitry Andric     return false;
4427b60736ecSDimitry Andric   return llvm::any_of(ArgTypes, [&](QualType Ty) {
4428b60736ecSDimitry Andric     return isInAllocaArgument(CGM.getCXXABI(), Ty);
4429b60736ecSDimitry Andric   });
4430b60736ecSDimitry Andric }
4431b60736ecSDimitry Andric 
4432b60736ecSDimitry Andric #ifndef NDEBUG
4433b60736ecSDimitry Andric // Determine whether the given argument is an Objective-C method
4434b60736ecSDimitry Andric // that may have type parameters in its signature.
isObjCMethodWithTypeParams(const ObjCMethodDecl * method)4435b60736ecSDimitry Andric static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method) {
4436b60736ecSDimitry Andric   const DeclContext *dc = method->getDeclContext();
4437b60736ecSDimitry Andric   if (const ObjCInterfaceDecl *classDecl = dyn_cast<ObjCInterfaceDecl>(dc)) {
4438b60736ecSDimitry Andric     return classDecl->getTypeParamListAsWritten();
4439b60736ecSDimitry Andric   }
4440b60736ecSDimitry Andric 
4441b60736ecSDimitry Andric   if (const ObjCCategoryDecl *catDecl = dyn_cast<ObjCCategoryDecl>(dc)) {
4442b60736ecSDimitry Andric     return catDecl->getTypeParamList();
4443b60736ecSDimitry Andric   }
4444b60736ecSDimitry Andric 
4445b60736ecSDimitry Andric   return false;
4446b60736ecSDimitry Andric }
4447b60736ecSDimitry Andric #endif
4448b60736ecSDimitry Andric 
4449b60736ecSDimitry Andric /// EmitCallArgs - Emit call arguments for a function.
EmitCallArgs(CallArgList & Args,PrototypeWrapper Prototype,llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,AbstractCallee AC,unsigned ParamsToSkip,EvaluationOrder Order)445045b53394SDimitry Andric void CodeGenFunction::EmitCallArgs(
4451b60736ecSDimitry Andric     CallArgList &Args, PrototypeWrapper Prototype,
445245b53394SDimitry Andric     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
44537442d6faSDimitry Andric     AbstractCallee AC, unsigned ParamsToSkip, EvaluationOrder Order) {
4454b60736ecSDimitry Andric   SmallVector<QualType, 16> ArgTypes;
4455b60736ecSDimitry Andric 
4456b60736ecSDimitry Andric   assert((ParamsToSkip == 0 || Prototype.P) &&
4457b60736ecSDimitry Andric          "Can't skip parameters if type info is not provided");
4458b60736ecSDimitry Andric 
4459b60736ecSDimitry Andric   // This variable only captures *explicitly* written conventions, not those
4460b60736ecSDimitry Andric   // applied by default via command line flags or target defaults, such as
4461b60736ecSDimitry Andric   // thiscall, aapcs, stdcall via -mrtd, etc. Computing that correctly would
4462b60736ecSDimitry Andric   // require knowing if this is a C++ instance method or being able to see
4463b60736ecSDimitry Andric   // unprototyped FunctionTypes.
4464b60736ecSDimitry Andric   CallingConv ExplicitCC = CC_C;
4465b60736ecSDimitry Andric 
4466b60736ecSDimitry Andric   // First, if a prototype was provided, use those argument types.
4467b60736ecSDimitry Andric   bool IsVariadic = false;
4468b60736ecSDimitry Andric   if (Prototype.P) {
4469b60736ecSDimitry Andric     const auto *MD = Prototype.P.dyn_cast<const ObjCMethodDecl *>();
4470b60736ecSDimitry Andric     if (MD) {
4471b60736ecSDimitry Andric       IsVariadic = MD->isVariadic();
4472b60736ecSDimitry Andric       ExplicitCC = getCallingConventionForDecl(
4473b60736ecSDimitry Andric           MD, CGM.getTarget().getTriple().isOSWindows());
4474b60736ecSDimitry Andric       ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
4475b60736ecSDimitry Andric                       MD->param_type_end());
4476b60736ecSDimitry Andric     } else {
4477b60736ecSDimitry Andric       const auto *FPT = Prototype.P.get<const FunctionProtoType *>();
4478b60736ecSDimitry Andric       IsVariadic = FPT->isVariadic();
4479b60736ecSDimitry Andric       ExplicitCC = FPT->getExtInfo().getCC();
4480b60736ecSDimitry Andric       ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
4481b60736ecSDimitry Andric                       FPT->param_type_end());
4482b60736ecSDimitry Andric     }
4483b60736ecSDimitry Andric 
4484b60736ecSDimitry Andric #ifndef NDEBUG
4485b60736ecSDimitry Andric     // Check that the prototyped types match the argument expression types.
4486b60736ecSDimitry Andric     bool isGenericMethod = MD && isObjCMethodWithTypeParams(MD);
4487b60736ecSDimitry Andric     CallExpr::const_arg_iterator Arg = ArgRange.begin();
4488b60736ecSDimitry Andric     for (QualType Ty : ArgTypes) {
4489b60736ecSDimitry Andric       assert(Arg != ArgRange.end() && "Running over edge of argument list!");
4490b60736ecSDimitry Andric       assert(
4491b60736ecSDimitry Andric           (isGenericMethod || Ty->isVariablyModifiedType() ||
4492b60736ecSDimitry Andric            Ty.getNonReferenceType()->isObjCRetainableType() ||
4493b60736ecSDimitry Andric            getContext()
4494b60736ecSDimitry Andric                    .getCanonicalType(Ty.getNonReferenceType())
4495b60736ecSDimitry Andric                    .getTypePtr() ==
4496b60736ecSDimitry Andric                getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
4497b60736ecSDimitry Andric           "type mismatch in call argument!");
4498b60736ecSDimitry Andric       ++Arg;
4499b60736ecSDimitry Andric     }
4500b60736ecSDimitry Andric 
4501b60736ecSDimitry Andric     // Either we've emitted all the call args, or we have a call to variadic
4502b60736ecSDimitry Andric     // function.
4503b60736ecSDimitry Andric     assert((Arg == ArgRange.end() || IsVariadic) &&
4504b60736ecSDimitry Andric            "Extra arguments in non-variadic function!");
4505b60736ecSDimitry Andric #endif
4506b60736ecSDimitry Andric   }
4507b60736ecSDimitry Andric 
4508b60736ecSDimitry Andric   // If we still have any arguments, emit them using the type of the argument.
450977fc4c14SDimitry Andric   for (auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
4510b60736ecSDimitry Andric     ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
451145b53394SDimitry Andric   assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
451245b53394SDimitry Andric 
4513b60736ecSDimitry Andric   // We must evaluate arguments from right to left in the MS C++ ABI,
4514bab175ecSDimitry Andric   // because arguments are destroyed left to right in the callee. As a special
4515bab175ecSDimitry Andric   // case, there are certain language constructs that require left-to-right
4516bab175ecSDimitry Andric   // evaluation, and in those cases we consider the evaluation order requirement
4517bab175ecSDimitry Andric   // to trump the "destruction order is reverse construction order" guarantee.
4518bab175ecSDimitry Andric   bool LeftToRight =
4519bab175ecSDimitry Andric       CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()
4520bab175ecSDimitry Andric           ? Order == EvaluationOrder::ForceLeftToRight
4521bab175ecSDimitry Andric           : Order != EvaluationOrder::ForceRightToLeft;
4522bab175ecSDimitry Andric 
45237442d6faSDimitry Andric   auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg,
45247442d6faSDimitry Andric                                          RValue EmittedArg) {
45257442d6faSDimitry Andric     if (!AC.hasFunctionDecl() || I >= AC.getNumParams())
45267442d6faSDimitry Andric       return;
45277442d6faSDimitry Andric     auto *PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>();
45287442d6faSDimitry Andric     if (PS == nullptr)
45297442d6faSDimitry Andric       return;
45307442d6faSDimitry Andric 
45317442d6faSDimitry Andric     const auto &Context = getContext();
45327442d6faSDimitry Andric     auto SizeTy = Context.getSizeType();
45337442d6faSDimitry Andric     auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
45347442d6faSDimitry Andric     assert(EmittedArg.getScalarVal() && "We emitted nothing for the arg?");
45357442d6faSDimitry Andric     llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T,
453622989816SDimitry Andric                                                      EmittedArg.getScalarVal(),
453722989816SDimitry Andric                                                      PS->isDynamic());
45387442d6faSDimitry Andric     Args.add(RValue::get(V), SizeTy);
45397442d6faSDimitry Andric     // If we're emitting args in reverse, be sure to do so with
45407442d6faSDimitry Andric     // pass_object_size, as well.
45417442d6faSDimitry Andric     if (!LeftToRight)
45427442d6faSDimitry Andric       std::swap(Args.back(), *(&Args.back() - 1));
45437442d6faSDimitry Andric   };
45447442d6faSDimitry Andric 
45459f4dbff6SDimitry Andric   // Insert a stack save if we're going to need any inalloca args.
4546b60736ecSDimitry Andric   if (hasInAllocaArgs(CGM, ExplicitCC, ArgTypes)) {
4547b60736ecSDimitry Andric     assert(getTarget().getTriple().getArch() == llvm::Triple::x86 &&
4548b60736ecSDimitry Andric            "inalloca only supported on x86");
45499f4dbff6SDimitry Andric     Args.allocateArgumentMemory(*this);
45509f4dbff6SDimitry Andric   }
45519f4dbff6SDimitry Andric 
4552bab175ecSDimitry Andric   // Evaluate each argument in the appropriate order.
4553bab175ecSDimitry Andric   size_t CallArgsStart = Args.size();
4554bab175ecSDimitry Andric   for (unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
4555bab175ecSDimitry Andric     unsigned Idx = LeftToRight ? I : E - I - 1;
4556bab175ecSDimitry Andric     CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
45577442d6faSDimitry Andric     unsigned InitialArgSize = Args.size();
4558cf1b4019SDimitry Andric     // If *Arg is an ObjCIndirectCopyRestoreExpr, check that either the types of
4559cf1b4019SDimitry Andric     // the argument and parameter match or the objc method is parameterized.
4560cf1b4019SDimitry Andric     assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
4561cf1b4019SDimitry Andric             getContext().hasSameUnqualifiedType((*Arg)->getType(),
4562cf1b4019SDimitry Andric                                                 ArgTypes[Idx]) ||
4563cf1b4019SDimitry Andric             (isa<ObjCMethodDecl>(AC.getDecl()) &&
4564cf1b4019SDimitry Andric              isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(AC.getDecl())))) &&
4565cf1b4019SDimitry Andric            "Argument and parameter types don't match");
4566bab175ecSDimitry Andric     EmitCallArg(Args, *Arg, ArgTypes[Idx]);
45677442d6faSDimitry Andric     // In particular, we depend on it being the last arg in Args, and the
45687442d6faSDimitry Andric     // objectsize bits depend on there only being one arg if !LeftToRight.
45697442d6faSDimitry Andric     assert(InitialArgSize + 1 == Args.size() &&
45707442d6faSDimitry Andric            "The code below depends on only adding one arg per EmitCallArg");
45717442d6faSDimitry Andric     (void)InitialArgSize;
457248675466SDimitry Andric     // Since pointer argument are never emitted as LValue, it is safe to emit
457348675466SDimitry Andric     // non-null argument check for r-value only.
457448675466SDimitry Andric     if (!Args.back().hasLValue()) {
457548675466SDimitry Andric       RValue RVArg = Args.back().getKnownRValue();
45767442d6faSDimitry Andric       EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,
45777442d6faSDimitry Andric                           ParamsToSkip + Idx);
45787442d6faSDimitry Andric       // @llvm.objectsize should never have side-effects and shouldn't need
45797442d6faSDimitry Andric       // destruction/cleanups, so we can safely "emit" it after its arg,
45807442d6faSDimitry Andric       // regardless of right-to-leftness
45817442d6faSDimitry Andric       MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
4582bab175ecSDimitry Andric     }
458348675466SDimitry Andric   }
4584bab175ecSDimitry Andric 
4585bab175ecSDimitry Andric   if (!LeftToRight) {
45869f4dbff6SDimitry Andric     // Un-reverse the arguments we just evaluated so they match up with the LLVM
45879f4dbff6SDimitry Andric     // IR function.
45889f4dbff6SDimitry Andric     std::reverse(Args.begin() + CallArgsStart, Args.end());
45899f4dbff6SDimitry Andric   }
45909f4dbff6SDimitry Andric }
45919f4dbff6SDimitry Andric 
45929f4dbff6SDimitry Andric namespace {
45939f4dbff6SDimitry Andric 
459445b53394SDimitry Andric struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
DestroyUnpassedArg__anon748148590f11::DestroyUnpassedArg459545b53394SDimitry Andric   DestroyUnpassedArg(Address Addr, QualType Ty)
45969f4dbff6SDimitry Andric       : Addr(Addr), Ty(Ty) {}
45979f4dbff6SDimitry Andric 
459845b53394SDimitry Andric   Address Addr;
45999f4dbff6SDimitry Andric   QualType Ty;
46009f4dbff6SDimitry Andric 
Emit__anon748148590f11::DestroyUnpassedArg46019f4dbff6SDimitry Andric   void Emit(CodeGenFunction &CGF, Flags flags) override {
460248675466SDimitry Andric     QualType::DestructionKind DtorKind = Ty.isDestructedType();
460348675466SDimitry Andric     if (DtorKind == QualType::DK_cxx_destructor) {
46049f4dbff6SDimitry Andric       const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
46059f4dbff6SDimitry Andric       assert(!Dtor->isTrivial());
46069f4dbff6SDimitry Andric       CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*for vbase*/ false,
460722989816SDimitry Andric                                 /*Delegating=*/false, Addr, Ty);
460848675466SDimitry Andric     } else {
460948675466SDimitry Andric       CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Ty));
461048675466SDimitry Andric     }
46119f4dbff6SDimitry Andric   }
46129f4dbff6SDimitry Andric };
46139f4dbff6SDimitry Andric 
46145e20cdd8SDimitry Andric struct DisableDebugLocationUpdates {
46155e20cdd8SDimitry Andric   CodeGenFunction &CGF;
46165e20cdd8SDimitry Andric   bool disabledDebugInfo;
DisableDebugLocationUpdates__anon748148590f11::DisableDebugLocationUpdates46175e20cdd8SDimitry Andric   DisableDebugLocationUpdates(CodeGenFunction &CGF, const Expr *E) : CGF(CGF) {
46185e20cdd8SDimitry Andric     if ((disabledDebugInfo = isa<CXXDefaultArgExpr>(E) && CGF.getDebugInfo()))
46195e20cdd8SDimitry Andric       CGF.disableDebugInfo();
46205e20cdd8SDimitry Andric   }
~DisableDebugLocationUpdates__anon748148590f11::DisableDebugLocationUpdates46215e20cdd8SDimitry Andric   ~DisableDebugLocationUpdates() {
46225e20cdd8SDimitry Andric     if (disabledDebugInfo)
46235e20cdd8SDimitry Andric       CGF.enableDebugInfo();
46245e20cdd8SDimitry Andric   }
46255e20cdd8SDimitry Andric };
46265e20cdd8SDimitry Andric 
462745b53394SDimitry Andric } // end anonymous namespace
462845b53394SDimitry Andric 
getRValue(CodeGenFunction & CGF) const462948675466SDimitry Andric RValue CallArg::getRValue(CodeGenFunction &CGF) const {
463048675466SDimitry Andric   if (!HasLV)
463148675466SDimitry Andric     return RV;
463248675466SDimitry Andric   LValue Copy = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty), Ty);
463348675466SDimitry Andric   CGF.EmitAggregateCopy(Copy, LV, Ty, AggValueSlot::DoesNotOverlap,
463448675466SDimitry Andric                         LV.isVolatile());
463548675466SDimitry Andric   IsUsed = true;
4636ac9a064cSDimitry Andric   return RValue::getAggregate(Copy.getAddress());
463748675466SDimitry Andric }
463848675466SDimitry Andric 
copyInto(CodeGenFunction & CGF,Address Addr) const463948675466SDimitry Andric void CallArg::copyInto(CodeGenFunction &CGF, Address Addr) const {
464048675466SDimitry Andric   LValue Dst = CGF.MakeAddrLValue(Addr, Ty);
464148675466SDimitry Andric   if (!HasLV && RV.isScalar())
464222989816SDimitry Andric     CGF.EmitStoreOfScalar(RV.getScalarVal(), Dst, /*isInit=*/true);
464348675466SDimitry Andric   else if (!HasLV && RV.isComplex())
464448675466SDimitry Andric     CGF.EmitStoreOfComplex(RV.getComplexVal(), Dst, /*init=*/true);
464548675466SDimitry Andric   else {
4646ac9a064cSDimitry Andric     auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress();
464748675466SDimitry Andric     LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty);
464848675466SDimitry Andric     // We assume that call args are never copied into subobjects.
464948675466SDimitry Andric     CGF.EmitAggregateCopy(Dst, SrcLV, Ty, AggValueSlot::DoesNotOverlap,
465048675466SDimitry Andric                           HasLV ? LV.isVolatileQualified()
465148675466SDimitry Andric                                 : RV.isVolatileQualified());
465248675466SDimitry Andric   }
465348675466SDimitry Andric   IsUsed = true;
465448675466SDimitry Andric }
465548675466SDimitry Andric 
EmitCallArg(CallArgList & args,const Expr * E,QualType type)465601af97d3SDimitry Andric void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
465701af97d3SDimitry Andric                                   QualType type) {
46585e20cdd8SDimitry Andric   DisableDebugLocationUpdates Dis(*this, E);
4659180abc3dSDimitry Andric   if (const ObjCIndirectCopyRestoreExpr *CRE
4660180abc3dSDimitry Andric         = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
466113cc256eSDimitry Andric     assert(getLangOpts().ObjCAutoRefCount);
4662180abc3dSDimitry Andric     return emitWritebackArg(*this, args, CRE);
4663180abc3dSDimitry Andric   }
4664180abc3dSDimitry Andric 
466536981b17SDimitry Andric   assert(type->isReferenceType() == E->isGLValue() &&
466636981b17SDimitry Andric          "reference binding to unmaterialized r-value!");
466736981b17SDimitry Andric 
466836981b17SDimitry Andric   if (E->isGLValue()) {
466936981b17SDimitry Andric     assert(E->getObjectKind() == OK_Ordinary);
4670bfef3995SDimitry Andric     return args.add(EmitReferenceBindingToExpr(E), type);
467136981b17SDimitry Andric   }
467201af97d3SDimitry Andric 
4673bfef3995SDimitry Andric   bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
4674bfef3995SDimitry Andric 
4675bfef3995SDimitry Andric   // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee.
4676bfef3995SDimitry Andric   // However, we still have to push an EH-only cleanup in case we unwind before
4677bfef3995SDimitry Andric   // we make it to the call.
4678344a3780SDimitry Andric   if (type->isRecordType() &&
4679519fc96cSDimitry Andric       type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
46809f4dbff6SDimitry Andric     // If we're using inalloca, use the argument memory.  Otherwise, use a
46819f4dbff6SDimitry Andric     // temporary.
468277fc4c14SDimitry Andric     AggValueSlot Slot = args.isUsingInAlloca()
468377fc4c14SDimitry Andric         ? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
46849f4dbff6SDimitry Andric 
4685ac9a064cSDimitry Andric     bool DestroyedInCallee = true, NeedsCleanup = true;
468648675466SDimitry Andric     if (const auto *RD = type->getAsCXXRecordDecl())
468748675466SDimitry Andric       DestroyedInCallee = RD->hasNonTrivialDestructor();
468848675466SDimitry Andric     else
4689ac9a064cSDimitry Andric       NeedsCleanup = type.isDestructedType();
469048675466SDimitry Andric 
46919f4dbff6SDimitry Andric     if (DestroyedInCallee)
4692bfef3995SDimitry Andric       Slot.setExternallyDestructed();
46939f4dbff6SDimitry Andric 
4694bfef3995SDimitry Andric     EmitAggExpr(E, Slot);
4695bfef3995SDimitry Andric     RValue RV = Slot.asRValue();
4696bfef3995SDimitry Andric     args.add(RV, type);
4697bfef3995SDimitry Andric 
4698ac9a064cSDimitry Andric     if (DestroyedInCallee && NeedsCleanup) {
46999f4dbff6SDimitry Andric       // Create a no-op GEP between the placeholder and the cleanup so we can
47009f4dbff6SDimitry Andric       // RAUW it successfully.  It also serves as a marker of the first
47019f4dbff6SDimitry Andric       // instruction where the cleanup is active.
4702ac9a064cSDimitry Andric       pushFullExprCleanup<DestroyUnpassedArg>(NormalAndEHCleanup,
4703ac9a064cSDimitry Andric                                               Slot.getAddress(), type);
4704bfef3995SDimitry Andric       // This unreachable is a temporary marker which will be removed later.
4705ac9a064cSDimitry Andric       llvm::Instruction *IsActive =
4706ac9a064cSDimitry Andric           Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
4707145449b1SDimitry Andric       args.addArgCleanupDeactivation(EHStack.stable_begin(), IsActive);
4708bfef3995SDimitry Andric     }
47099f4dbff6SDimitry Andric     return;
4710bfef3995SDimitry Andric   }
4711bfef3995SDimitry Andric 
4712bfef3995SDimitry Andric   if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) &&
4713ac9a064cSDimitry Andric       cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue &&
4714ac9a064cSDimitry Andric       !type->isArrayParameterType()) {
471529cafa66SDimitry Andric     LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr());
471629cafa66SDimitry Andric     assert(L.isSimple());
471748675466SDimitry Andric     args.addUncopiedAggregate(L, type);
471829cafa66SDimitry Andric     return;
471929cafa66SDimitry Andric   }
472029cafa66SDimitry Andric 
472101af97d3SDimitry Andric   args.add(EmitAnyExprToTemp(E), type);
4722ec2b103cSEd Schouten }
4723ec2b103cSEd Schouten 
getVarArgType(const Expr * Arg)472406d4ba38SDimitry Andric QualType CodeGenFunction::getVarArgType(const Expr *Arg) {
472506d4ba38SDimitry Andric   // System headers on Windows define NULL to 0 instead of 0LL on Win64. MSVC
472606d4ba38SDimitry Andric   // implicitly widens null pointer constants that are arguments to varargs
472706d4ba38SDimitry Andric   // functions to pointer-sized ints.
472806d4ba38SDimitry Andric   if (!getTarget().getTriple().isOSWindows())
472906d4ba38SDimitry Andric     return Arg->getType();
473006d4ba38SDimitry Andric 
473106d4ba38SDimitry Andric   if (Arg->getType()->isIntegerType() &&
473206d4ba38SDimitry Andric       getContext().getTypeSize(Arg->getType()) <
4733e3b55780SDimitry Andric           getContext().getTargetInfo().getPointerWidth(LangAS::Default) &&
473406d4ba38SDimitry Andric       Arg->isNullPointerConstant(getContext(),
473506d4ba38SDimitry Andric                                  Expr::NPC_ValueDependentIsNotNull)) {
473606d4ba38SDimitry Andric     return getContext().getIntPtrType();
473706d4ba38SDimitry Andric   }
473806d4ba38SDimitry Andric 
473906d4ba38SDimitry Andric   return Arg->getType();
474006d4ba38SDimitry Andric }
474106d4ba38SDimitry Andric 
4742dbe13110SDimitry Andric // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
4743dbe13110SDimitry Andric // optimizer it can aggressively ignore unwind edges.
4744dbe13110SDimitry Andric void
AddObjCARCExceptionMetadata(llvm::Instruction * Inst)4745dbe13110SDimitry Andric CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
4746dbe13110SDimitry Andric   if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
4747dbe13110SDimitry Andric       !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
4748dbe13110SDimitry Andric     Inst->setMetadata("clang.arc.no_objc_arc_exceptions",
4749dbe13110SDimitry Andric                       CGM.getNoObjCARCExceptionsMetadata());
4750dbe13110SDimitry Andric }
4751dbe13110SDimitry Andric 
4752809500fcSDimitry Andric /// Emits a call to the given no-arguments nounwind runtime function.
4753809500fcSDimitry Andric llvm::CallInst *
EmitNounwindRuntimeCall(llvm::FunctionCallee callee,const llvm::Twine & name)475422989816SDimitry Andric CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4755809500fcSDimitry Andric                                          const llvm::Twine &name) {
4756ac9a064cSDimitry Andric   return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
4757809500fcSDimitry Andric }
4758809500fcSDimitry Andric 
4759809500fcSDimitry Andric /// Emits a call to the given nounwind runtime function.
4760809500fcSDimitry Andric llvm::CallInst *
EmitNounwindRuntimeCall(llvm::FunctionCallee callee,ArrayRef<Address> args,const llvm::Twine & name)476122989816SDimitry Andric CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4762ac9a064cSDimitry Andric                                          ArrayRef<Address> args,
4763ac9a064cSDimitry Andric                                          const llvm::Twine &name) {
4764ac9a064cSDimitry Andric   SmallVector<llvm::Value *, 3> values;
4765ac9a064cSDimitry Andric   for (auto arg : args)
4766ac9a064cSDimitry Andric     values.push_back(arg.emitRawPointer(*this));
4767ac9a064cSDimitry Andric   return EmitNounwindRuntimeCall(callee, values, name);
4768ac9a064cSDimitry Andric }
4769ac9a064cSDimitry Andric 
4770ac9a064cSDimitry Andric llvm::CallInst *
EmitNounwindRuntimeCall(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args,const llvm::Twine & name)4771ac9a064cSDimitry Andric CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
4772809500fcSDimitry Andric                                          ArrayRef<llvm::Value *> args,
4773809500fcSDimitry Andric                                          const llvm::Twine &name) {
4774809500fcSDimitry Andric   llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
4775809500fcSDimitry Andric   call->setDoesNotThrow();
4776809500fcSDimitry Andric   return call;
4777809500fcSDimitry Andric }
4778809500fcSDimitry Andric 
4779809500fcSDimitry Andric /// Emits a simple call (never an invoke) to the given no-arguments
4780809500fcSDimitry Andric /// runtime function.
EmitRuntimeCall(llvm::FunctionCallee callee,const llvm::Twine & name)478122989816SDimitry Andric llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
4782809500fcSDimitry Andric                                                  const llvm::Twine &name) {
4783e3b55780SDimitry Andric   return EmitRuntimeCall(callee, std::nullopt, name);
4784809500fcSDimitry Andric }
4785809500fcSDimitry Andric 
478645b53394SDimitry Andric // Calls which may throw must have operand bundles indicating which funclet
478745b53394SDimitry Andric // they are nested within.
478848675466SDimitry Andric SmallVector<llvm::OperandBundleDef, 1>
getBundlesForFunclet(llvm::Value * Callee)478948675466SDimitry Andric CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) {
47902b6b257fSDimitry Andric   // There is no need for a funclet operand bundle if we aren't inside a
47912b6b257fSDimitry Andric   // funclet.
479245b53394SDimitry Andric   if (!CurrentFuncletPad)
479308e8dd7bSDimitry Andric     return (SmallVector<llvm::OperandBundleDef, 1>());
479445b53394SDimitry Andric 
479508e8dd7bSDimitry Andric   // Skip intrinsics which cannot throw (as long as they don't lower into
479608e8dd7bSDimitry Andric   // regular function calls in the course of IR transformations).
479708e8dd7bSDimitry Andric   if (auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts())) {
479808e8dd7bSDimitry Andric     if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
479908e8dd7bSDimitry Andric       auto IID = CalleeFn->getIntrinsicID();
480008e8dd7bSDimitry Andric       if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
480108e8dd7bSDimitry Andric         return (SmallVector<llvm::OperandBundleDef, 1>());
480208e8dd7bSDimitry Andric     }
480308e8dd7bSDimitry Andric   }
480445b53394SDimitry Andric 
480508e8dd7bSDimitry Andric   SmallVector<llvm::OperandBundleDef, 1> BundleList;
480645b53394SDimitry Andric   BundleList.emplace_back("funclet", CurrentFuncletPad);
480748675466SDimitry Andric   return BundleList;
480845b53394SDimitry Andric }
480945b53394SDimitry Andric 
48102b6b257fSDimitry Andric /// Emits a simple call (never an invoke) to the given runtime function.
EmitRuntimeCall(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args,const llvm::Twine & name)481122989816SDimitry Andric llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
48122b6b257fSDimitry Andric                                                  ArrayRef<llvm::Value *> args,
48132b6b257fSDimitry Andric                                                  const llvm::Twine &name) {
481422989816SDimitry Andric   llvm::CallInst *call = Builder.CreateCall(
481522989816SDimitry Andric       callee, args, getBundlesForFunclet(callee.getCallee()), name);
48162b6b257fSDimitry Andric   call->setCallingConv(getRuntimeCC());
4817ac9a064cSDimitry Andric 
4818ac9a064cSDimitry Andric   if (CGM.shouldEmitConvergenceTokens() && call->isConvergent())
4819ac9a064cSDimitry Andric     return addControlledConvergenceToken(call);
48202b6b257fSDimitry Andric   return call;
48212b6b257fSDimitry Andric }
48222b6b257fSDimitry Andric 
4823809500fcSDimitry Andric /// Emits a call or invoke to the given noreturn runtime function.
EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args)482422989816SDimitry Andric void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(
482522989816SDimitry Andric     llvm::FunctionCallee callee, ArrayRef<llvm::Value *> args) {
482648675466SDimitry Andric   SmallVector<llvm::OperandBundleDef, 1> BundleList =
482722989816SDimitry Andric       getBundlesForFunclet(callee.getCallee());
482845b53394SDimitry Andric 
4829809500fcSDimitry Andric   if (getInvokeDest()) {
4830809500fcSDimitry Andric     llvm::InvokeInst *invoke =
4831809500fcSDimitry Andric       Builder.CreateInvoke(callee,
4832809500fcSDimitry Andric                            getUnreachableBlock(),
4833809500fcSDimitry Andric                            getInvokeDest(),
483445b53394SDimitry Andric                            args,
483545b53394SDimitry Andric                            BundleList);
4836809500fcSDimitry Andric     invoke->setDoesNotReturn();
4837809500fcSDimitry Andric     invoke->setCallingConv(getRuntimeCC());
4838809500fcSDimitry Andric   } else {
483945b53394SDimitry Andric     llvm::CallInst *call = Builder.CreateCall(callee, args, BundleList);
4840809500fcSDimitry Andric     call->setDoesNotReturn();
4841809500fcSDimitry Andric     call->setCallingConv(getRuntimeCC());
4842809500fcSDimitry Andric     Builder.CreateUnreachable();
4843809500fcSDimitry Andric   }
4844809500fcSDimitry Andric }
4845809500fcSDimitry Andric 
48462b6b257fSDimitry Andric /// Emits a call or invoke instruction to the given nullary runtime function.
484722989816SDimitry Andric llvm::CallBase *
EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,const Twine & name)484822989816SDimitry Andric CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4849809500fcSDimitry Andric                                          const Twine &name) {
4850e3b55780SDimitry Andric   return EmitRuntimeCallOrInvoke(callee, std::nullopt, name);
4851809500fcSDimitry Andric }
4852809500fcSDimitry Andric 
4853809500fcSDimitry Andric /// Emits a call or invoke instruction to the given runtime function.
485422989816SDimitry Andric llvm::CallBase *
EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args,const Twine & name)485522989816SDimitry Andric CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
4856809500fcSDimitry Andric                                          ArrayRef<llvm::Value *> args,
4857809500fcSDimitry Andric                                          const Twine &name) {
485822989816SDimitry Andric   llvm::CallBase *call = EmitCallOrInvoke(callee, args, name);
485922989816SDimitry Andric   call->setCallingConv(getRuntimeCC());
486022989816SDimitry Andric   return call;
4861809500fcSDimitry Andric }
4862809500fcSDimitry Andric 
48634ba67500SRoman Divacky /// Emits a call or invoke instruction to the given function, depending
48644ba67500SRoman Divacky /// on the current state of the EH stack.
EmitCallOrInvoke(llvm::FunctionCallee Callee,ArrayRef<llvm::Value * > Args,const Twine & Name)486522989816SDimitry Andric llvm::CallBase *CodeGenFunction::EmitCallOrInvoke(llvm::FunctionCallee Callee,
486636981b17SDimitry Andric                                                   ArrayRef<llvm::Value *> Args,
486736981b17SDimitry Andric                                                   const Twine &Name) {
48684ba67500SRoman Divacky   llvm::BasicBlock *InvokeDest = getInvokeDest();
486948675466SDimitry Andric   SmallVector<llvm::OperandBundleDef, 1> BundleList =
487022989816SDimitry Andric       getBundlesForFunclet(Callee.getCallee());
48714ba67500SRoman Divacky 
487222989816SDimitry Andric   llvm::CallBase *Inst;
4873dbe13110SDimitry Andric   if (!InvokeDest)
48742b6b257fSDimitry Andric     Inst = Builder.CreateCall(Callee, Args, BundleList, Name);
4875dbe13110SDimitry Andric   else {
48764ba67500SRoman Divacky     llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
48772b6b257fSDimitry Andric     Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
48782b6b257fSDimitry Andric                                 Name);
48794ba67500SRoman Divacky     EmitBlock(ContBB);
4880dbe13110SDimitry Andric   }
4881dbe13110SDimitry Andric 
4882dbe13110SDimitry Andric   // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
4883dbe13110SDimitry Andric   // optimizer it can aggressively ignore unwind edges.
4884dbe13110SDimitry Andric   if (CGM.getLangOpts().ObjCAutoRefCount)
4885dbe13110SDimitry Andric     AddObjCARCExceptionMetadata(Inst);
4886dbe13110SDimitry Andric 
488722989816SDimitry Andric   return Inst;
48884ba67500SRoman Divacky }
48894ba67500SRoman Divacky 
deferPlaceholderReplacement(llvm::Instruction * Old,llvm::Value * New)48909f4dbff6SDimitry Andric void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
48919f4dbff6SDimitry Andric                                                   llvm::Value *New) {
4892344a3780SDimitry Andric   DeferredReplacements.push_back(
4893344a3780SDimitry Andric       std::make_pair(llvm::WeakTrackingVH(Old), New));
48949f4dbff6SDimitry Andric }
4895180abc3dSDimitry Andric 
4896cfca06d7SDimitry Andric namespace {
4897cfca06d7SDimitry Andric 
4898cfca06d7SDimitry Andric /// Specify given \p NewAlign as the alignment of return value attribute. If
4899cfca06d7SDimitry Andric /// such attribute already exists, re-set it to the maximal one of two options.
4900e3b55780SDimitry Andric [[nodiscard]] llvm::AttributeList
maybeRaiseRetAlignmentAttribute(llvm::LLVMContext & Ctx,const llvm::AttributeList & Attrs,llvm::Align NewAlign)4901cfca06d7SDimitry Andric maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
4902cfca06d7SDimitry Andric                                 const llvm::AttributeList &Attrs,
4903cfca06d7SDimitry Andric                                 llvm::Align NewAlign) {
4904cfca06d7SDimitry Andric   llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
4905cfca06d7SDimitry Andric   if (CurAlign >= NewAlign)
4906cfca06d7SDimitry Andric     return Attrs;
4907cfca06d7SDimitry Andric   llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
4908c0981da4SDimitry Andric   return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
4909c0981da4SDimitry Andric       .addRetAttribute(Ctx, AlignAttr);
4910cfca06d7SDimitry Andric }
4911cfca06d7SDimitry Andric 
4912cfca06d7SDimitry Andric template <typename AlignedAttrTy> class AbstractAssumeAlignedAttrEmitter {
4913cfca06d7SDimitry Andric protected:
4914cfca06d7SDimitry Andric   CodeGenFunction &CGF;
4915cfca06d7SDimitry Andric 
4916cfca06d7SDimitry Andric   /// We do nothing if this is, or becomes, nullptr.
4917cfca06d7SDimitry Andric   const AlignedAttrTy *AA = nullptr;
4918cfca06d7SDimitry Andric 
4919cfca06d7SDimitry Andric   llvm::Value *Alignment = nullptr;      // May or may not be a constant.
4920cfca06d7SDimitry Andric   llvm::ConstantInt *OffsetCI = nullptr; // Constant, hopefully zero.
4921cfca06d7SDimitry Andric 
AbstractAssumeAlignedAttrEmitter(CodeGenFunction & CGF_,const Decl * FuncDecl)4922cfca06d7SDimitry Andric   AbstractAssumeAlignedAttrEmitter(CodeGenFunction &CGF_, const Decl *FuncDecl)
4923cfca06d7SDimitry Andric       : CGF(CGF_) {
4924cfca06d7SDimitry Andric     if (!FuncDecl)
4925cfca06d7SDimitry Andric       return;
4926cfca06d7SDimitry Andric     AA = FuncDecl->getAttr<AlignedAttrTy>();
4927cfca06d7SDimitry Andric   }
4928cfca06d7SDimitry Andric 
4929cfca06d7SDimitry Andric public:
4930cfca06d7SDimitry Andric   /// If we can, materialize the alignment as an attribute on return value.
4931e3b55780SDimitry Andric   [[nodiscard]] llvm::AttributeList
TryEmitAsCallSiteAttribute(const llvm::AttributeList & Attrs)4932cfca06d7SDimitry Andric   TryEmitAsCallSiteAttribute(const llvm::AttributeList &Attrs) {
4933cfca06d7SDimitry Andric     if (!AA || OffsetCI || CGF.SanOpts.has(SanitizerKind::Alignment))
4934cfca06d7SDimitry Andric       return Attrs;
4935cfca06d7SDimitry Andric     const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
4936cfca06d7SDimitry Andric     if (!AlignmentCI)
4937cfca06d7SDimitry Andric       return Attrs;
4938cfca06d7SDimitry Andric     // We may legitimately have non-power-of-2 alignment here.
4939cfca06d7SDimitry Andric     // If so, this is UB land, emit it via `@llvm.assume` instead.
4940cfca06d7SDimitry Andric     if (!AlignmentCI->getValue().isPowerOf2())
4941cfca06d7SDimitry Andric       return Attrs;
4942cfca06d7SDimitry Andric     llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
4943cfca06d7SDimitry Andric         CGF.getLLVMContext(), Attrs,
4944cfca06d7SDimitry Andric         llvm::Align(
4945cfca06d7SDimitry Andric             AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
4946cfca06d7SDimitry Andric     AA = nullptr; // We're done. Disallow doing anything else.
4947cfca06d7SDimitry Andric     return NewAttrs;
4948cfca06d7SDimitry Andric   }
4949cfca06d7SDimitry Andric 
4950cfca06d7SDimitry Andric   /// Emit alignment assumption.
4951cfca06d7SDimitry Andric   /// This is a general fallback that we take if either there is an offset,
4952cfca06d7SDimitry Andric   /// or the alignment is variable or we are sanitizing for alignment.
EmitAsAnAssumption(SourceLocation Loc,QualType RetTy,RValue & Ret)4953cfca06d7SDimitry Andric   void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
4954cfca06d7SDimitry Andric     if (!AA)
4955cfca06d7SDimitry Andric       return;
4956cfca06d7SDimitry Andric     CGF.emitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc,
4957cfca06d7SDimitry Andric                                 AA->getLocation(), Alignment, OffsetCI);
4958cfca06d7SDimitry Andric     AA = nullptr; // We're done. Disallow doing anything else.
4959cfca06d7SDimitry Andric   }
4960cfca06d7SDimitry Andric };
4961cfca06d7SDimitry Andric 
4962cfca06d7SDimitry Andric /// Helper data structure to emit `AssumeAlignedAttr`.
4963cfca06d7SDimitry Andric class AssumeAlignedAttrEmitter final
4964cfca06d7SDimitry Andric     : public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
4965cfca06d7SDimitry Andric public:
AssumeAlignedAttrEmitter(CodeGenFunction & CGF_,const Decl * FuncDecl)4966cfca06d7SDimitry Andric   AssumeAlignedAttrEmitter(CodeGenFunction &CGF_, const Decl *FuncDecl)
4967cfca06d7SDimitry Andric       : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
4968cfca06d7SDimitry Andric     if (!AA)
4969cfca06d7SDimitry Andric       return;
4970cfca06d7SDimitry Andric     // It is guaranteed that the alignment/offset are constants.
4971cfca06d7SDimitry Andric     Alignment = cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AA->getAlignment()));
4972cfca06d7SDimitry Andric     if (Expr *Offset = AA->getOffset()) {
4973cfca06d7SDimitry Andric       OffsetCI = cast<llvm::ConstantInt>(CGF.EmitScalarExpr(Offset));
4974cfca06d7SDimitry Andric       if (OffsetCI->isNullValue()) // Canonicalize zero offset to no offset.
4975cfca06d7SDimitry Andric         OffsetCI = nullptr;
4976cfca06d7SDimitry Andric     }
4977cfca06d7SDimitry Andric   }
4978cfca06d7SDimitry Andric };
4979cfca06d7SDimitry Andric 
4980cfca06d7SDimitry Andric /// Helper data structure to emit `AllocAlignAttr`.
4981cfca06d7SDimitry Andric class AllocAlignAttrEmitter final
4982cfca06d7SDimitry Andric     : public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
4983cfca06d7SDimitry Andric public:
AllocAlignAttrEmitter(CodeGenFunction & CGF_,const Decl * FuncDecl,const CallArgList & CallArgs)4984cfca06d7SDimitry Andric   AllocAlignAttrEmitter(CodeGenFunction &CGF_, const Decl *FuncDecl,
4985cfca06d7SDimitry Andric                         const CallArgList &CallArgs)
4986cfca06d7SDimitry Andric       : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
4987cfca06d7SDimitry Andric     if (!AA)
4988cfca06d7SDimitry Andric       return;
4989cfca06d7SDimitry Andric     // Alignment may or may not be a constant, and that is okay.
4990cfca06d7SDimitry Andric     Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
4991cfca06d7SDimitry Andric                     .getRValue(CGF)
4992cfca06d7SDimitry Andric                     .getScalarVal();
4993cfca06d7SDimitry Andric   }
4994cfca06d7SDimitry Andric };
4995cfca06d7SDimitry Andric 
4996cfca06d7SDimitry Andric } // namespace
4997cfca06d7SDimitry Andric 
getMaxVectorWidth(const llvm::Type * Ty)4998145449b1SDimitry Andric static unsigned getMaxVectorWidth(const llvm::Type *Ty) {
4999145449b1SDimitry Andric   if (auto *VT = dyn_cast<llvm::VectorType>(Ty))
5000e3b55780SDimitry Andric     return VT->getPrimitiveSizeInBits().getKnownMinValue();
5001145449b1SDimitry Andric   if (auto *AT = dyn_cast<llvm::ArrayType>(Ty))
5002145449b1SDimitry Andric     return getMaxVectorWidth(AT->getElementType());
5003145449b1SDimitry Andric 
5004145449b1SDimitry Andric   unsigned MaxVectorWidth = 0;
5005145449b1SDimitry Andric   if (auto *ST = dyn_cast<llvm::StructType>(Ty))
5006145449b1SDimitry Andric     for (auto *I : ST->elements())
5007145449b1SDimitry Andric       MaxVectorWidth = std::max(MaxVectorWidth, getMaxVectorWidth(I));
5008145449b1SDimitry Andric   return MaxVectorWidth;
5009145449b1SDimitry Andric }
5010145449b1SDimitry Andric 
EmitCall(const CGFunctionInfo & CallInfo,const CGCallee & Callee,ReturnValueSlot ReturnValue,const CallArgList & CallArgs,llvm::CallBase ** callOrInvoke,bool IsMustTail,SourceLocation Loc,bool IsVirtualFunctionPointerThunk)5011ec2b103cSEd Schouten RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5012bab175ecSDimitry Andric                                  const CGCallee &Callee,
5013abe15e55SRoman Divacky                                  ReturnValueSlot ReturnValue,
5014ec2b103cSEd Schouten                                  const CallArgList &CallArgs,
5015344a3780SDimitry Andric                                  llvm::CallBase **callOrInvoke, bool IsMustTail,
5016ac9a064cSDimitry Andric                                  SourceLocation Loc,
5017ac9a064cSDimitry Andric                                  bool IsVirtualFunctionPointerThunk) {
5018ec2b103cSEd Schouten   // FIXME: We no longer need the types from CallArgs; lift up and simplify.
5019ec2b103cSEd Schouten 
502048675466SDimitry Andric   assert(Callee.isOrdinary() || Callee.isVirtual());
5021bab175ecSDimitry Andric 
5022ec2b103cSEd Schouten   // Handle struct-return functions by passing a pointer to the
5023ec2b103cSEd Schouten   // location that we would like to return into.
5024ec2b103cSEd Schouten   QualType RetTy = CallInfo.getReturnType();
5025ec2b103cSEd Schouten   const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
50267ef7bab7SEd Schouten 
502722989816SDimitry Andric   llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo);
502822989816SDimitry Andric 
502922989816SDimitry Andric   const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
5030cfca06d7SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
503122989816SDimitry Andric     // We can only guarantee that a function is called from the correct
503222989816SDimitry Andric     // context/function based on the appropriate target attributes,
503322989816SDimitry Andric     // so only check in the case where we have both always_inline and target
503422989816SDimitry Andric     // since otherwise we could be making a conditional call after a check for
503522989816SDimitry Andric     // the proper cpu features (and it won't cause code generation issues due to
503622989816SDimitry Andric     // function based code generation).
503722989816SDimitry Andric     if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
50387fa27ce4SDimitry Andric         (TargetDecl->hasAttr<TargetAttr>() ||
50397fa27ce4SDimitry Andric          (CurFuncDecl && CurFuncDecl->hasAttr<TargetAttr>())))
504022989816SDimitry Andric       checkTargetFeatures(Loc, FD);
5041ac9a064cSDimitry Andric   }
504222989816SDimitry Andric 
5043cfca06d7SDimitry Andric   // Some architectures (such as x86-64) have the ABI changed based on
5044cfca06d7SDimitry Andric   // attribute-target/features. Give them a chance to diagnose.
5045cfca06d7SDimitry Andric   CGM.getTargetCodeGenInfo().checkFunctionCallABI(
5046ac9a064cSDimitry Andric       CGM, Loc, dyn_cast_or_null<FunctionDecl>(CurCodeDecl),
5047ac9a064cSDimitry Andric       dyn_cast_or_null<FunctionDecl>(TargetDecl), CallArgs, RetTy);
5048cfca06d7SDimitry Andric 
5049bab175ecSDimitry Andric   // 1. Set up the arguments.
50507ef7bab7SEd Schouten 
50519f4dbff6SDimitry Andric   // If we're using inalloca, insert the allocation after the stack save.
50529f4dbff6SDimitry Andric   // FIXME: Do this earlier rather than hacking it in here!
5053ac9a064cSDimitry Andric   RawAddress ArgMemory = RawAddress::invalid();
50549f4dbff6SDimitry Andric   if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) {
50557442d6faSDimitry Andric     const llvm::DataLayout &DL = CGM.getDataLayout();
50569f4dbff6SDimitry Andric     llvm::Instruction *IP = CallArgs.getStackBase();
50579f4dbff6SDimitry Andric     llvm::AllocaInst *AI;
50589f4dbff6SDimitry Andric     if (IP) {
50599f4dbff6SDimitry Andric       IP = IP->getNextNode();
50607442d6faSDimitry Andric       AI = new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
50617442d6faSDimitry Andric                                 "argmem", IP);
50629f4dbff6SDimitry Andric     } else {
50639f4dbff6SDimitry Andric       AI = CreateTempAlloca(ArgStruct, "argmem");
50649f4dbff6SDimitry Andric     }
506545b53394SDimitry Andric     auto Align = CallInfo.getArgStructAlignment();
5066519fc96cSDimitry Andric     AI->setAlignment(Align.getAsAlign());
50679f4dbff6SDimitry Andric     AI->setUsedWithInAlloca(true);
50689f4dbff6SDimitry Andric     assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
5069ac9a064cSDimitry Andric     ArgMemory = RawAddress(AI, ArgStruct, Align);
50709f4dbff6SDimitry Andric   }
50719f4dbff6SDimitry Andric 
507206d4ba38SDimitry Andric   ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo);
507306d4ba38SDimitry Andric   SmallVector<llvm::Value *, 16> IRCallArgs(IRFunctionArgs.totalIRArgs());
507406d4ba38SDimitry Andric 
50757ef7bab7SEd Schouten   // If the call returns a temporary with struct return, create a temporary
5076abe15e55SRoman Divacky   // alloca to hold the result, unless one is given to us.
507745b53394SDimitry Andric   Address SRetPtr = Address::invalid();
5078ac9a064cSDimitry Andric   RawAddress SRetAlloca = RawAddress::invalid();
507948675466SDimitry Andric   llvm::Value *UnusedReturnSizePtr = nullptr;
50802b6b257fSDimitry Andric   if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
5081ac9a064cSDimitry Andric     if (IsVirtualFunctionPointerThunk && RetAI.isIndirect()) {
5082ac9a064cSDimitry Andric       SRetPtr = makeNaturalAddressForPointer(CurFn->arg_begin() +
5083ac9a064cSDimitry Andric                                                  IRFunctionArgs.getSRetArgNo(),
5084ac9a064cSDimitry Andric                                              RetTy, CharUnits::fromQuantity(1));
5085ac9a064cSDimitry Andric     } else if (!ReturnValue.isNull()) {
5086ac9a064cSDimitry Andric       SRetPtr = ReturnValue.getAddress();
508745b53394SDimitry Andric     } else {
508848675466SDimitry Andric       SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
5089798321d8SDimitry Andric       if (HaveInsertPoint() && ReturnValue.isUnused()) {
5090344a3780SDimitry Andric         llvm::TypeSize size =
5091798321d8SDimitry Andric             CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
509248675466SDimitry Andric         UnusedReturnSizePtr = EmitLifetimeStart(size, SRetAlloca.getPointer());
5093798321d8SDimitry Andric       }
5094798321d8SDimitry Andric     }
509506d4ba38SDimitry Andric     if (IRFunctionArgs.hasSRetArg()) {
5096ac9a064cSDimitry Andric       IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
5097ac9a064cSDimitry Andric           getAsNaturalPointerTo(SRetPtr, RetTy);
50982b6b257fSDimitry Andric     } else if (RetAI.isInAlloca()) {
509922989816SDimitry Andric       Address Addr =
510022989816SDimitry Andric           Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex());
5101ac9a064cSDimitry Andric       Builder.CreateStore(getAsNaturalPointerTo(SRetPtr, RetTy), Addr);
51029f4dbff6SDimitry Andric     }
5103abe15e55SRoman Divacky   }
5104ec2b103cSEd Schouten 
5105ac9a064cSDimitry Andric   RawAddress swiftErrorTemp = RawAddress::invalid();
51062b6b257fSDimitry Andric   Address swiftErrorArg = Address::invalid();
51072b6b257fSDimitry Andric 
5108519fc96cSDimitry Andric   // When passing arguments using temporary allocas, we need to add the
5109519fc96cSDimitry Andric   // appropriate lifetime markers. This vector keeps track of all the lifetime
5110519fc96cSDimitry Andric   // markers that need to be ended right after the call.
5111519fc96cSDimitry Andric   SmallVector<CallLifetimeEnd, 2> CallLifetimeEndAfterCall;
5112519fc96cSDimitry Andric 
5113bab175ecSDimitry Andric   // Translate all of the arguments as necessary to match the IR lowering.
5114ec2b103cSEd Schouten   assert(CallInfo.arg_size() == CallArgs.size() &&
5115ec2b103cSEd Schouten          "Mismatch between function signature & arguments.");
511606d4ba38SDimitry Andric   unsigned ArgNo = 0;
5117ec2b103cSEd Schouten   CGFunctionInfo::const_arg_iterator info_it = CallInfo.arg_begin();
5118ec2b103cSEd Schouten   for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
511906d4ba38SDimitry Andric        I != E; ++I, ++info_it, ++ArgNo) {
5120ec2b103cSEd Schouten     const ABIArgInfo &ArgInfo = info_it->info;
5121ec2b103cSEd Schouten 
512213cc256eSDimitry Andric     // Insert a padding argument to ensure proper alignment.
512306d4ba38SDimitry Andric     if (IRFunctionArgs.hasPaddingArg(ArgNo))
512406d4ba38SDimitry Andric       IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
512506d4ba38SDimitry Andric           llvm::UndefValue::get(ArgInfo.getPaddingType());
512606d4ba38SDimitry Andric 
512706d4ba38SDimitry Andric     unsigned FirstIRArg, NumIRArgs;
512806d4ba38SDimitry Andric     std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
512913cc256eSDimitry Andric 
5130e3b55780SDimitry Andric     bool ArgHasMaybeUndefAttr =
5131e3b55780SDimitry Andric         IsArgumentMaybeUndef(TargetDecl, CallInfo.getNumRequiredArgs(), ArgNo);
5132e3b55780SDimitry Andric 
5133ec2b103cSEd Schouten     switch (ArgInfo.getKind()) {
51349f4dbff6SDimitry Andric     case ABIArgInfo::InAlloca: {
513506d4ba38SDimitry Andric       assert(NumIRArgs == 0);
51369f4dbff6SDimitry Andric       assert(getTarget().getTriple().getArch() == llvm::Triple::x86);
513748675466SDimitry Andric       if (I->isAggregate()) {
5138ac9a064cSDimitry Andric         RawAddress Addr = I->hasLValue()
5139ac9a064cSDimitry Andric                               ? I->getKnownLValue().getAddress()
514048675466SDimitry Andric                               : I->getKnownRValue().getAggregateAddress();
51419f4dbff6SDimitry Andric         llvm::Instruction *Placeholder =
514248675466SDimitry Andric             cast<llvm::Instruction>(Addr.getPointer());
5143cfca06d7SDimitry Andric 
5144cfca06d7SDimitry Andric         if (!ArgInfo.getInAllocaIndirect()) {
5145cfca06d7SDimitry Andric           // Replace the placeholder with the appropriate argument slot GEP.
51469f4dbff6SDimitry Andric           CGBuilderTy::InsertPoint IP = Builder.saveIP();
51479f4dbff6SDimitry Andric           Builder.SetInsertPoint(Placeholder);
5148cfca06d7SDimitry Andric           Addr = Builder.CreateStructGEP(ArgMemory,
5149cfca06d7SDimitry Andric                                          ArgInfo.getInAllocaFieldIndex());
51509f4dbff6SDimitry Andric           Builder.restoreIP(IP);
5151cfca06d7SDimitry Andric         } else {
5152cfca06d7SDimitry Andric           // For indirect things such as overaligned structs, replace the
5153cfca06d7SDimitry Andric           // placeholder with a regular aggregate temporary alloca. Store the
5154cfca06d7SDimitry Andric           // address of this alloca into the struct.
5155cfca06d7SDimitry Andric           Addr = CreateMemTemp(info_it->type, "inalloca.indirect.tmp");
5156cfca06d7SDimitry Andric           Address ArgSlot = Builder.CreateStructGEP(
5157cfca06d7SDimitry Andric               ArgMemory, ArgInfo.getInAllocaFieldIndex());
5158cfca06d7SDimitry Andric           Builder.CreateStore(Addr.getPointer(), ArgSlot);
5159cfca06d7SDimitry Andric         }
516045b53394SDimitry Andric         deferPlaceholderReplacement(Placeholder, Addr.getPointer());
5161cfca06d7SDimitry Andric       } else if (ArgInfo.getInAllocaIndirect()) {
5162cfca06d7SDimitry Andric         // Make a temporary alloca and store the address of it into the argument
5163cfca06d7SDimitry Andric         // struct.
5164ac9a064cSDimitry Andric         RawAddress Addr = CreateMemTempWithoutCast(
5165cfca06d7SDimitry Andric             I->Ty, getContext().getTypeAlignInChars(I->Ty),
5166cfca06d7SDimitry Andric             "indirect-arg-temp");
5167cfca06d7SDimitry Andric         I->copyInto(*this, Addr);
5168cfca06d7SDimitry Andric         Address ArgSlot =
5169cfca06d7SDimitry Andric             Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
5170cfca06d7SDimitry Andric         Builder.CreateStore(Addr.getPointer(), ArgSlot);
51719f4dbff6SDimitry Andric       } else {
51729f4dbff6SDimitry Andric         // Store the RValue into the argument struct.
517322989816SDimitry Andric         Address Addr =
517422989816SDimitry Andric             Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
51757fa27ce4SDimitry Andric         Addr = Addr.withElementType(ConvertTypeForMem(I->Ty));
517648675466SDimitry Andric         I->copyInto(*this, Addr);
51779f4dbff6SDimitry Andric       }
517806d4ba38SDimitry Andric       break;
51799f4dbff6SDimitry Andric     }
51809f4dbff6SDimitry Andric 
5181b60736ecSDimitry Andric     case ABIArgInfo::Indirect:
5182b60736ecSDimitry Andric     case ABIArgInfo::IndirectAliased: {
518306d4ba38SDimitry Andric       assert(NumIRArgs == 1);
5184ac9a064cSDimitry Andric       if (I->isAggregate()) {
5185180abc3dSDimitry Andric         // We want to avoid creating an unnecessary temporary+copy here;
5186809500fcSDimitry Andric         // however, we need one in three cases:
5187180abc3dSDimitry Andric         // 1. If the argument is not byval, and we are required to copy the
5188180abc3dSDimitry Andric         //    source.  (This case doesn't occur on any common architecture.)
5189180abc3dSDimitry Andric         // 2. If the argument is byval, RV is not sufficiently aligned, and
5190180abc3dSDimitry Andric         //    we cannot force it to be sufficiently aligned.
519148675466SDimitry Andric         // 3. If the argument is byval, but RV is not located in default
519248675466SDimitry Andric         //    or alloca address space.
519348675466SDimitry Andric         Address Addr = I->hasLValue()
5194ac9a064cSDimitry Andric                            ? I->getKnownLValue().getAddress()
519548675466SDimitry Andric                            : I->getKnownRValue().getAggregateAddress();
519645b53394SDimitry Andric         CharUnits Align = ArgInfo.getIndirectAlign();
519713cc256eSDimitry Andric         const llvm::DataLayout *TD = &CGM.getDataLayout();
519848675466SDimitry Andric 
519948675466SDimitry Andric         assert((FirstIRArg >= IRFuncTy->getNumParams() ||
520048675466SDimitry Andric                 IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
520148675466SDimitry Andric                     TD->getAllocaAddrSpace()) &&
520248675466SDimitry Andric                "indirect argument must be in alloca address space");
520348675466SDimitry Andric 
520448675466SDimitry Andric         bool NeedCopy = false;
520548675466SDimitry Andric         if (Addr.getAlignment() < Align &&
5206ac9a064cSDimitry Andric             llvm::getOrEnforceKnownAlignment(Addr.emitRawPointer(*this),
5207ac9a064cSDimitry Andric                                              Align.getAsAlign(),
5208ac9a064cSDimitry Andric                                              *TD) < Align.getAsAlign()) {
520948675466SDimitry Andric           NeedCopy = true;
521048675466SDimitry Andric         } else if (I->hasLValue()) {
521148675466SDimitry Andric           auto LV = I->getKnownLValue();
521248675466SDimitry Andric           auto AS = LV.getAddressSpace();
5213676fbe81SDimitry Andric 
5214b1c73532SDimitry Andric           bool isByValOrRef =
5215b1c73532SDimitry Andric               ArgInfo.isIndirectAliased() || ArgInfo.getIndirectByVal();
5216b1c73532SDimitry Andric 
5217b1c73532SDimitry Andric           if (!isByValOrRef ||
5218706b4fc4SDimitry Andric               (LV.getAlignment() < getContext().getTypeAlignInChars(I->Ty))) {
5219676fbe81SDimitry Andric             NeedCopy = true;
5220676fbe81SDimitry Andric           }
5221676fbe81SDimitry Andric           if (!getLangOpts().OpenCL) {
5222b1c73532SDimitry Andric             if ((isByValOrRef &&
5223676fbe81SDimitry Andric                 (AS != LangAS::Default &&
5224676fbe81SDimitry Andric                  AS != CGM.getASTAllocaAddressSpace()))) {
522548675466SDimitry Andric               NeedCopy = true;
522648675466SDimitry Andric             }
522748675466SDimitry Andric           }
5228676fbe81SDimitry Andric           // For OpenCL even if RV is located in default or alloca address space
5229676fbe81SDimitry Andric           // we don't want to perform address space cast for it.
5230b1c73532SDimitry Andric           else if ((isByValOrRef &&
5231676fbe81SDimitry Andric                     Addr.getType()->getAddressSpace() != IRFuncTy->
5232676fbe81SDimitry Andric                       getParamType(FirstIRArg)->getPointerAddressSpace())) {
5233676fbe81SDimitry Andric             NeedCopy = true;
5234676fbe81SDimitry Andric           }
5235676fbe81SDimitry Andric         }
5236676fbe81SDimitry Andric 
5237ac9a064cSDimitry Andric         if (!NeedCopy) {
5238ac9a064cSDimitry Andric           // Skip the extra memcpy call.
5239ac9a064cSDimitry Andric           llvm::Value *V = getAsNaturalPointerTo(Addr, I->Ty);
5240ac9a064cSDimitry Andric           auto *T = llvm::PointerType::get(
5241ac9a064cSDimitry Andric               CGM.getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace());
5242ac9a064cSDimitry Andric 
5243ac9a064cSDimitry Andric           llvm::Value *Val = getTargetHooks().performAddrSpaceCast(
5244ac9a064cSDimitry Andric               *this, V, LangAS::Default, CGM.getASTAllocaAddressSpace(), T,
5245ac9a064cSDimitry Andric               true);
5246e3b55780SDimitry Andric           if (ArgHasMaybeUndefAttr)
5247ac9a064cSDimitry Andric             Val = Builder.CreateFreeze(Val);
5248ac9a064cSDimitry Andric           IRCallArgs[FirstIRArg] = Val;
5249ac9a064cSDimitry Andric           break;
5250ac9a064cSDimitry Andric         }
5251ac9a064cSDimitry Andric       }
5252ac9a064cSDimitry Andric 
5253ac9a064cSDimitry Andric       // For non-aggregate args and aggregate args meeting conditions above
5254ac9a064cSDimitry Andric       // we need to create an aligned temporary, and copy to it.
5255ac9a064cSDimitry Andric       RawAddress AI = CreateMemTempWithoutCast(
5256ac9a064cSDimitry Andric           I->Ty, ArgInfo.getIndirectAlign(), "byval-temp");
5257ac9a064cSDimitry Andric       llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty);
5258ac9a064cSDimitry Andric       if (ArgHasMaybeUndefAttr)
5259ac9a064cSDimitry Andric         Val = Builder.CreateFreeze(Val);
5260e3b55780SDimitry Andric       IRCallArgs[FirstIRArg] = Val;
5261519fc96cSDimitry Andric 
5262519fc96cSDimitry Andric       // Emit lifetime markers for the temporary alloca.
5263344a3780SDimitry Andric       llvm::TypeSize ByvalTempElementSize =
5264519fc96cSDimitry Andric           CGM.getDataLayout().getTypeAllocSize(AI.getElementType());
5265519fc96cSDimitry Andric       llvm::Value *LifetimeSize =
5266519fc96cSDimitry Andric           EmitLifetimeStart(ByvalTempElementSize, AI.getPointer());
5267519fc96cSDimitry Andric 
5268519fc96cSDimitry Andric       // Add cleanup code to emit the end lifetime marker after the call.
5269519fc96cSDimitry Andric       if (LifetimeSize) // In case we disabled lifetime markers.
5270519fc96cSDimitry Andric         CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize);
5271519fc96cSDimitry Andric 
5272519fc96cSDimitry Andric       // Generate the copy.
527348675466SDimitry Andric       I->copyInto(*this, AI);
5274ec2b103cSEd Schouten       break;
5275ec2b103cSEd Schouten     }
5276ec2b103cSEd Schouten 
5277ec2b103cSEd Schouten     case ABIArgInfo::Ignore:
527806d4ba38SDimitry Andric       assert(NumIRArgs == 0);
5279ec2b103cSEd Schouten       break;
5280ec2b103cSEd Schouten 
52813d1dcd9bSDimitry Andric     case ABIArgInfo::Extend:
52823d1dcd9bSDimitry Andric     case ABIArgInfo::Direct: {
52833d1dcd9bSDimitry Andric       if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) &&
52843d1dcd9bSDimitry Andric           ArgInfo.getCoerceToType() == ConvertType(info_it->type) &&
52853d1dcd9bSDimitry Andric           ArgInfo.getDirectOffset() == 0) {
528606d4ba38SDimitry Andric         assert(NumIRArgs == 1);
5287180abc3dSDimitry Andric         llvm::Value *V;
528848675466SDimitry Andric         if (!I->isAggregate())
528948675466SDimitry Andric           V = I->getKnownRValue().getScalarVal();
52903d1dcd9bSDimitry Andric         else
529148675466SDimitry Andric           V = Builder.CreateLoad(
5292ac9a064cSDimitry Andric               I->hasLValue() ? I->getKnownLValue().getAddress()
529348675466SDimitry Andric                              : I->getKnownRValue().getAggregateAddress());
5294180abc3dSDimitry Andric 
52952b6b257fSDimitry Andric         // Implement swifterror by copying into a new swifterror argument.
52962b6b257fSDimitry Andric         // We'll write back in the normal path out of the call.
52972b6b257fSDimitry Andric         if (CallInfo.getExtParameterInfo(ArgNo).getABI()
52982b6b257fSDimitry Andric               == ParameterABI::SwiftErrorResult) {
52992b6b257fSDimitry Andric           assert(!swiftErrorTemp.isValid() && "multiple swifterror args");
53002b6b257fSDimitry Andric 
53012b6b257fSDimitry Andric           QualType pointeeTy = I->Ty->getPointeeType();
5302ac9a064cSDimitry Andric           swiftErrorArg = makeNaturalAddressForPointer(
5303ac9a064cSDimitry Andric               V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy));
53042b6b257fSDimitry Andric 
53052b6b257fSDimitry Andric           swiftErrorTemp =
53062b6b257fSDimitry Andric             CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
53072b6b257fSDimitry Andric           V = swiftErrorTemp.getPointer();
53082b6b257fSDimitry Andric           cast<llvm::AllocaInst>(V)->setSwiftError(true);
53092b6b257fSDimitry Andric 
53102b6b257fSDimitry Andric           llvm::Value *errorValue = Builder.CreateLoad(swiftErrorArg);
53112b6b257fSDimitry Andric           Builder.CreateStore(errorValue, swiftErrorTemp);
53122b6b257fSDimitry Andric         }
53132b6b257fSDimitry Andric 
531406d4ba38SDimitry Andric         // We might have to widen integers, but we should never truncate.
531506d4ba38SDimitry Andric         if (ArgInfo.getCoerceToType() != V->getType() &&
531606d4ba38SDimitry Andric             V->getType()->isIntegerTy())
531706d4ba38SDimitry Andric           V = Builder.CreateZExt(V, ArgInfo.getCoerceToType());
531806d4ba38SDimitry Andric 
5319180abc3dSDimitry Andric         // If the argument doesn't match, perform a bitcast to coerce it.  This
5320180abc3dSDimitry Andric         // can happen due to trivial type mismatches.
532106d4ba38SDimitry Andric         if (FirstIRArg < IRFuncTy->getNumParams() &&
532206d4ba38SDimitry Andric             V->getType() != IRFuncTy->getParamType(FirstIRArg))
532306d4ba38SDimitry Andric           V = Builder.CreateBitCast(V, IRFuncTy->getParamType(FirstIRArg));
53242b6b257fSDimitry Andric 
5325e3b55780SDimitry Andric         if (ArgHasMaybeUndefAttr)
5326e3b55780SDimitry Andric           V = Builder.CreateFreeze(V);
532706d4ba38SDimitry Andric         IRCallArgs[FirstIRArg] = V;
53283d1dcd9bSDimitry Andric         break;
53293d1dcd9bSDimitry Andric       }
53303d1dcd9bSDimitry Andric 
5331ac9a064cSDimitry Andric       llvm::StructType *STy =
5332ac9a064cSDimitry Andric           dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType());
5333ac9a064cSDimitry Andric       if (STy && ArgInfo.isDirect() && !ArgInfo.getCanBeFlattened()) {
5334ac9a064cSDimitry Andric         llvm::Type *SrcTy = ConvertTypeForMem(I->Ty);
5335ac9a064cSDimitry Andric         [[maybe_unused]] llvm::TypeSize SrcTypeSize =
5336ac9a064cSDimitry Andric             CGM.getDataLayout().getTypeAllocSize(SrcTy);
5337ac9a064cSDimitry Andric         [[maybe_unused]] llvm::TypeSize DstTypeSize =
5338ac9a064cSDimitry Andric             CGM.getDataLayout().getTypeAllocSize(STy);
5339ac9a064cSDimitry Andric         if (STy->containsHomogeneousScalableVectorTypes()) {
5340ac9a064cSDimitry Andric           assert(SrcTypeSize == DstTypeSize &&
5341ac9a064cSDimitry Andric                  "Only allow non-fractional movement of structure with "
5342ac9a064cSDimitry Andric                  "homogeneous scalable vector type");
5343ac9a064cSDimitry Andric 
5344ac9a064cSDimitry Andric           IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
5345ac9a064cSDimitry Andric           break;
5346ac9a064cSDimitry Andric         }
5347ac9a064cSDimitry Andric       }
5348ac9a064cSDimitry Andric 
5349ec2b103cSEd Schouten       // FIXME: Avoid the conversion through memory if possible.
535045b53394SDimitry Andric       Address Src = Address::invalid();
535148675466SDimitry Andric       if (!I->isAggregate()) {
535245b53394SDimitry Andric         Src = CreateMemTemp(I->Ty, "coerce");
535348675466SDimitry Andric         I->copyInto(*this, Src);
535451ece4aaSDimitry Andric       } else {
5355ac9a064cSDimitry Andric         Src = I->hasLValue() ? I->getKnownLValue().getAddress()
535648675466SDimitry Andric                              : I->getKnownRValue().getAggregateAddress();
535751ece4aaSDimitry Andric       }
53584ba67500SRoman Divacky 
53593d1dcd9bSDimitry Andric       // If the value is offset in memory, apply the offset now.
536045b53394SDimitry Andric       Src = emitAddressAtOffset(*this, Src, ArgInfo);
53613d1dcd9bSDimitry Andric 
536206d4ba38SDimitry Andric       // Fast-isel and the optimizer generally like scalar values better than
536306d4ba38SDimitry Andric       // FCAs, so we flatten them if this is safe to do for this argument.
536406d4ba38SDimitry Andric       if (STy && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) {
5365cfca06d7SDimitry Andric         llvm::Type *SrcTy = Src.getElementType();
5366b1c73532SDimitry Andric         llvm::TypeSize SrcTypeSize =
5367b1c73532SDimitry Andric             CGM.getDataLayout().getTypeAllocSize(SrcTy);
5368b1c73532SDimitry Andric         llvm::TypeSize DstTypeSize = CGM.getDataLayout().getTypeAllocSize(STy);
5369b1c73532SDimitry Andric         if (SrcTypeSize.isScalable()) {
5370b1c73532SDimitry Andric           assert(STy->containsHomogeneousScalableVectorTypes() &&
5371b1c73532SDimitry Andric                  "ABI only supports structure with homogeneous scalable vector "
5372b1c73532SDimitry Andric                  "type");
5373b1c73532SDimitry Andric           assert(SrcTypeSize == DstTypeSize &&
5374b1c73532SDimitry Andric                  "Only allow non-fractional movement of structure with "
5375b1c73532SDimitry Andric                  "homogeneous scalable vector type");
5376b1c73532SDimitry Andric           assert(NumIRArgs == STy->getNumElements());
5377b1c73532SDimitry Andric 
5378b1c73532SDimitry Andric           llvm::Value *StoredStructValue =
5379b1c73532SDimitry Andric               Builder.CreateLoad(Src, Src.getName() + ".tuple");
5380b1c73532SDimitry Andric           for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5381b1c73532SDimitry Andric             llvm::Value *Extract = Builder.CreateExtractValue(
5382b1c73532SDimitry Andric                 StoredStructValue, i, Src.getName() + ".extract" + Twine(i));
5383b1c73532SDimitry Andric             IRCallArgs[FirstIRArg + i] = Extract;
5384b1c73532SDimitry Andric           }
5385b1c73532SDimitry Andric         } else {
5386b1c73532SDimitry Andric           uint64_t SrcSize = SrcTypeSize.getFixedValue();
5387b1c73532SDimitry Andric           uint64_t DstSize = DstTypeSize.getFixedValue();
538813cc256eSDimitry Andric 
538913cc256eSDimitry Andric           // If the source type is smaller than the destination type of the
539013cc256eSDimitry Andric           // coerce-to logic, copy the source value into a temp alloca the size
539113cc256eSDimitry Andric           // of the destination type to allow loading all of it. The bits past
539213cc256eSDimitry Andric           // the source value are left undef.
539313cc256eSDimitry Andric           if (SrcSize < DstSize) {
5394b1c73532SDimitry Andric             Address TempAlloca = CreateTempAlloca(STy, Src.getAlignment(),
539545b53394SDimitry Andric                                                   Src.getName() + ".coerce");
539645b53394SDimitry Andric             Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
539745b53394SDimitry Andric             Src = TempAlloca;
539813cc256eSDimitry Andric           } else {
53997fa27ce4SDimitry Andric             Src = Src.withElementType(STy);
540013cc256eSDimitry Andric           }
540113cc256eSDimitry Andric 
540206d4ba38SDimitry Andric           assert(NumIRArgs == STy->getNumElements());
54034ba67500SRoman Divacky           for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
540422989816SDimitry Andric             Address EltPtr = Builder.CreateStructGEP(Src, i);
540545b53394SDimitry Andric             llvm::Value *LI = Builder.CreateLoad(EltPtr);
5406e3b55780SDimitry Andric             if (ArgHasMaybeUndefAttr)
5407e3b55780SDimitry Andric               LI = Builder.CreateFreeze(LI);
540806d4ba38SDimitry Andric             IRCallArgs[FirstIRArg + i] = LI;
54094ba67500SRoman Divacky           }
5410b1c73532SDimitry Andric         }
54114ba67500SRoman Divacky       } else {
54124ba67500SRoman Divacky         // In the simple case, just pass the coerced loaded value.
541306d4ba38SDimitry Andric         assert(NumIRArgs == 1);
5414cfca06d7SDimitry Andric         llvm::Value *Load =
541545b53394SDimitry Andric             CreateCoercedLoad(Src, ArgInfo.getCoerceToType(), *this);
5416cfca06d7SDimitry Andric 
5417cfca06d7SDimitry Andric         if (CallInfo.isCmseNSCall()) {
5418cfca06d7SDimitry Andric           // For certain parameter types, clear padding bits, as they may reveal
5419cfca06d7SDimitry Andric           // sensitive information.
5420cfca06d7SDimitry Andric           // Small struct/union types are passed as integer arrays.
5421cfca06d7SDimitry Andric           auto *ATy = dyn_cast<llvm::ArrayType>(Load->getType());
5422cfca06d7SDimitry Andric           if (ATy != nullptr && isa<RecordType>(I->Ty.getCanonicalType()))
5423cfca06d7SDimitry Andric             Load = EmitCMSEClearRecord(Load, ATy, I->Ty);
5424cfca06d7SDimitry Andric         }
5425e3b55780SDimitry Andric 
5426e3b55780SDimitry Andric         if (ArgHasMaybeUndefAttr)
5427e3b55780SDimitry Andric           Load = Builder.CreateFreeze(Load);
5428cfca06d7SDimitry Andric         IRCallArgs[FirstIRArg] = Load;
54294ba67500SRoman Divacky       }
54304ba67500SRoman Divacky 
5431ec2b103cSEd Schouten       break;
5432ec2b103cSEd Schouten     }
5433ec2b103cSEd Schouten 
54342b6b257fSDimitry Andric     case ABIArgInfo::CoerceAndExpand: {
54352b6b257fSDimitry Andric       auto coercionType = ArgInfo.getCoerceAndExpandType();
54362b6b257fSDimitry Andric       auto layout = CGM.getDataLayout().getStructLayout(coercionType);
54372b6b257fSDimitry Andric 
54382b6b257fSDimitry Andric       llvm::Value *tempSize = nullptr;
54392b6b257fSDimitry Andric       Address addr = Address::invalid();
5440ac9a064cSDimitry Andric       RawAddress AllocaAddr = RawAddress::invalid();
544148675466SDimitry Andric       if (I->isAggregate()) {
5442ac9a064cSDimitry Andric         addr = I->hasLValue() ? I->getKnownLValue().getAddress()
544348675466SDimitry Andric                               : I->getKnownRValue().getAggregateAddress();
544448675466SDimitry Andric 
54452b6b257fSDimitry Andric       } else {
544648675466SDimitry Andric         RValue RV = I->getKnownRValue();
54472b6b257fSDimitry Andric         assert(RV.isScalar()); // complex should always just be direct
54482b6b257fSDimitry Andric 
54492b6b257fSDimitry Andric         llvm::Type *scalarType = RV.getScalarVal()->getType();
54502b6b257fSDimitry Andric         auto scalarSize = CGM.getDataLayout().getTypeAllocSize(scalarType);
5451e3b55780SDimitry Andric         auto scalarAlign = CGM.getDataLayout().getPrefTypeAlign(scalarType);
54522b6b257fSDimitry Andric 
54532b6b257fSDimitry Andric         // Materialize to a temporary.
5454e3b55780SDimitry Andric         addr = CreateTempAlloca(
5455e3b55780SDimitry Andric             RV.getScalarVal()->getType(),
5456e3b55780SDimitry Andric             CharUnits::fromQuantity(std::max(layout->getAlignment(), scalarAlign)),
545748675466SDimitry Andric             "tmp",
545848675466SDimitry Andric             /*ArraySize=*/nullptr, &AllocaAddr);
545948675466SDimitry Andric         tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer());
54602b6b257fSDimitry Andric 
54612b6b257fSDimitry Andric         Builder.CreateStore(RV.getScalarVal(), addr);
54622b6b257fSDimitry Andric       }
54632b6b257fSDimitry Andric 
54647fa27ce4SDimitry Andric       addr = addr.withElementType(coercionType);
54652b6b257fSDimitry Andric 
54662b6b257fSDimitry Andric       unsigned IRArgPos = FirstIRArg;
54672b6b257fSDimitry Andric       for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
54682b6b257fSDimitry Andric         llvm::Type *eltType = coercionType->getElementType(i);
54692b6b257fSDimitry Andric         if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue;
547022989816SDimitry Andric         Address eltAddr = Builder.CreateStructGEP(addr, i);
54712b6b257fSDimitry Andric         llvm::Value *elt = Builder.CreateLoad(eltAddr);
5472e3b55780SDimitry Andric         if (ArgHasMaybeUndefAttr)
5473e3b55780SDimitry Andric           elt = Builder.CreateFreeze(elt);
54742b6b257fSDimitry Andric         IRCallArgs[IRArgPos++] = elt;
54752b6b257fSDimitry Andric       }
54762b6b257fSDimitry Andric       assert(IRArgPos == FirstIRArg + NumIRArgs);
54772b6b257fSDimitry Andric 
54782b6b257fSDimitry Andric       if (tempSize) {
547948675466SDimitry Andric         EmitLifetimeEnd(tempSize, AllocaAddr.getPointer());
54802b6b257fSDimitry Andric       }
54812b6b257fSDimitry Andric 
54822b6b257fSDimitry Andric       break;
54832b6b257fSDimitry Andric     }
54842b6b257fSDimitry Andric 
5485b60736ecSDimitry Andric     case ABIArgInfo::Expand: {
548606d4ba38SDimitry Andric       unsigned IRArgPos = FirstIRArg;
548748675466SDimitry Andric       ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
548806d4ba38SDimitry Andric       assert(IRArgPos == FirstIRArg + NumIRArgs);
5489ec2b103cSEd Schouten       break;
5490ec2b103cSEd Schouten     }
5491ec2b103cSEd Schouten     }
5492b60736ecSDimitry Andric   }
5493ec2b103cSEd Schouten 
549448675466SDimitry Andric   const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*this);
549548675466SDimitry Andric   llvm::Value *CalleePtr = ConcreteCallee.getFunctionPointer();
5496bab175ecSDimitry Andric 
5497bab175ecSDimitry Andric   // If we're using inalloca, set up that argument.
549845b53394SDimitry Andric   if (ArgMemory.isValid()) {
549945b53394SDimitry Andric     llvm::Value *Arg = ArgMemory.getPointer();
550006d4ba38SDimitry Andric     assert(IRFunctionArgs.hasInallocaArg());
550106d4ba38SDimitry Andric     IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
55029f4dbff6SDimitry Andric   }
55039f4dbff6SDimitry Andric 
5504bab175ecSDimitry Andric   // 2. Prepare the function pointer.
5505bab175ecSDimitry Andric 
5506bab175ecSDimitry Andric   // If the callee is a bitcast of a non-variadic function to have a
5507bab175ecSDimitry Andric   // variadic function pointer type, check to see if we can remove the
5508bab175ecSDimitry Andric   // bitcast.  This comes up with unprototyped functions.
5509bab175ecSDimitry Andric   //
5510bab175ecSDimitry Andric   // This makes the IR nicer, but more importantly it ensures that we
5511bab175ecSDimitry Andric   // can inline the function at -O0 if it is marked always_inline.
551222989816SDimitry Andric   auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
551322989816SDimitry Andric                                    llvm::Value *Ptr) -> llvm::Function * {
5514bab175ecSDimitry Andric     if (!CalleeFT->isVarArg())
551522989816SDimitry Andric       return nullptr;
5516bab175ecSDimitry Andric 
551722989816SDimitry Andric     // Get underlying value if it's a bitcast
551822989816SDimitry Andric     if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
551922989816SDimitry Andric       if (CE->getOpcode() == llvm::Instruction::BitCast)
552022989816SDimitry Andric         Ptr = CE->getOperand(0);
552122989816SDimitry Andric     }
5522bab175ecSDimitry Andric 
552322989816SDimitry Andric     llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
5524bab175ecSDimitry Andric     if (!OrigFn)
552522989816SDimitry Andric       return nullptr;
5526bab175ecSDimitry Andric 
5527bab175ecSDimitry Andric     llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
5528bab175ecSDimitry Andric 
5529bab175ecSDimitry Andric     // If the original type is variadic, or if any of the component types
5530bab175ecSDimitry Andric     // disagree, we cannot remove the cast.
5531bab175ecSDimitry Andric     if (OrigFT->isVarArg() ||
5532bab175ecSDimitry Andric         OrigFT->getNumParams() != CalleeFT->getNumParams() ||
5533bab175ecSDimitry Andric         OrigFT->getReturnType() != CalleeFT->getReturnType())
553422989816SDimitry Andric       return nullptr;
5535bab175ecSDimitry Andric 
5536bab175ecSDimitry Andric     for (unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
5537bab175ecSDimitry Andric       if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
553822989816SDimitry Andric         return nullptr;
5539bab175ecSDimitry Andric 
5540bab175ecSDimitry Andric     return OrigFn;
5541bab175ecSDimitry Andric   };
554222989816SDimitry Andric 
554322989816SDimitry Andric   if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
554422989816SDimitry Andric     CalleePtr = OrigFn;
554522989816SDimitry Andric     IRFuncTy = OrigFn->getFunctionType();
554622989816SDimitry Andric   }
5547bab175ecSDimitry Andric 
5548bab175ecSDimitry Andric   // 3. Perform the actual call.
5549bab175ecSDimitry Andric 
5550bab175ecSDimitry Andric   // Deactivate any cleanups that we're supposed to do immediately before
5551bab175ecSDimitry Andric   // the call.
5552bfef3995SDimitry Andric   if (!CallArgs.getCleanupsToDeactivate().empty())
5553bfef3995SDimitry Andric     deactivateArgCleanupsBeforeCall(*this, CallArgs);
5554bfef3995SDimitry Andric 
5555bab175ecSDimitry Andric   // Assert that the arguments we computed match up.  The IR verifier
5556bab175ecSDimitry Andric   // will catch this, but this is a common enough source of problems
5557bab175ecSDimitry Andric   // during IRGen changes that it's way better for debugging to catch
5558bab175ecSDimitry Andric   // it ourselves here.
5559bab175ecSDimitry Andric #ifndef NDEBUG
556006d4ba38SDimitry Andric   assert(IRCallArgs.size() == IRFuncTy->getNumParams() || IRFuncTy->isVarArg());
556106d4ba38SDimitry Andric   for (unsigned i = 0; i < IRCallArgs.size(); ++i) {
556206d4ba38SDimitry Andric     // Inalloca argument can have different type.
556306d4ba38SDimitry Andric     if (IRFunctionArgs.hasInallocaArg() &&
556406d4ba38SDimitry Andric         i == IRFunctionArgs.getInallocaArgNo())
556506d4ba38SDimitry Andric       continue;
556606d4ba38SDimitry Andric     if (i < IRFuncTy->getNumParams())
556706d4ba38SDimitry Andric       assert(IRCallArgs[i]->getType() == IRFuncTy->getParamType(i));
556806d4ba38SDimitry Andric   }
5569bab175ecSDimitry Andric #endif
557006d4ba38SDimitry Andric 
5571676fbe81SDimitry Andric   // Update the largest vector width if any arguments have vector types.
5572145449b1SDimitry Andric   for (unsigned i = 0; i < IRCallArgs.size(); ++i)
5573145449b1SDimitry Andric     LargestVectorWidth = std::max(LargestVectorWidth,
5574145449b1SDimitry Andric                                   getMaxVectorWidth(IRCallArgs[i]->getType()));
5575676fbe81SDimitry Andric 
5576bab175ecSDimitry Andric   // Compute the calling convention and attributes.
55774c8b2481SRoman Divacky   unsigned CallingConv;
5578583e75ccSDimitry Andric   llvm::AttributeList Attrs;
5579bab175ecSDimitry Andric   CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
5580583e75ccSDimitry Andric                              Callee.getAbstractInfo(), Attrs, CallingConv,
5581344a3780SDimitry Andric                              /*AttrOnCallSite=*/true,
5582344a3780SDimitry Andric                              /*IsThunk=*/false);
5583ec2b103cSEd Schouten 
5584ac9a064cSDimitry Andric   if (CallingConv == llvm::CallingConv::X86_VectorCall &&
5585ac9a064cSDimitry Andric       getTarget().getTriple().isWindowsArm64EC()) {
5586ac9a064cSDimitry Andric     CGM.Error(Loc, "__vectorcall calling convention is not currently "
5587ac9a064cSDimitry Andric                    "supported");
5588ac9a064cSDimitry Andric   }
5589ac9a064cSDimitry Andric 
5590b1c73532SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
5591b60736ecSDimitry Andric     if (FD->hasAttr<StrictFPAttr>())
5592706b4fc4SDimitry Andric       // All calls within a strictfp function are marked strictfp
5593c0981da4SDimitry Andric       Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP);
5594706b4fc4SDimitry Andric 
5595b1c73532SDimitry Andric     // If -ffast-math is enabled and the function is guarded by an
5596b1c73532SDimitry Andric     // '__attribute__((optnone)) adjust the memory attribute so the BE emits the
5597b1c73532SDimitry Andric     // library call instead of the intrinsic.
5598b1c73532SDimitry Andric     if (FD->hasAttr<OptimizeNoneAttr>() && getLangOpts().FastMath)
5599b1c73532SDimitry Andric       CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
5600b1c73532SDimitry Andric                                 Attrs);
5601b1c73532SDimitry Andric   }
5602cfca06d7SDimitry Andric   // Add call-site nomerge attribute if exists.
5603cfca06d7SDimitry Andric   if (InNoMergeAttributedStmt)
5604c0981da4SDimitry Andric     Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoMerge);
5605cfca06d7SDimitry Andric 
5606145449b1SDimitry Andric   // Add call-site noinline attribute if exists.
5607145449b1SDimitry Andric   if (InNoInlineAttributedStmt)
5608145449b1SDimitry Andric     Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
5609145449b1SDimitry Andric 
5610145449b1SDimitry Andric   // Add call-site always_inline attribute if exists.
5611145449b1SDimitry Andric   if (InAlwaysInlineAttributedStmt)
5612145449b1SDimitry Andric     Attrs =
5613145449b1SDimitry Andric         Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline);
5614145449b1SDimitry Andric 
5615bab175ecSDimitry Andric   // Apply some call-site-specific attributes.
5616bab175ecSDimitry Andric   // TODO: work this into building the attribute set.
5617bab175ecSDimitry Andric 
5618bab175ecSDimitry Andric   // Apply always_inline to all calls within flatten functions.
5619bab175ecSDimitry Andric   // FIXME: should this really take priority over __try, below?
5620bab175ecSDimitry Andric   if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
5621145449b1SDimitry Andric       !InNoInlineAttributedStmt &&
562222989816SDimitry Andric       !(TargetDecl && TargetDecl->hasAttr<NoInlineAttr>())) {
5623bab175ecSDimitry Andric     Attrs =
5624c0981da4SDimitry Andric         Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline);
5625bab175ecSDimitry Andric   }
5626bab175ecSDimitry Andric 
5627bab175ecSDimitry Andric   // Disable inlining inside SEH __try blocks.
5628bab175ecSDimitry Andric   if (isSEHTryScope()) {
5629c0981da4SDimitry Andric     Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
5630bab175ecSDimitry Andric   }
5631bab175ecSDimitry Andric 
5632bab175ecSDimitry Andric   // Decide whether to use a call or an invoke.
563345b53394SDimitry Andric   bool CannotThrow;
563445b53394SDimitry Andric   if (currentFunctionUsesSEHTry()) {
5635bab175ecSDimitry Andric     // SEH cares about asynchronous exceptions, so everything can "throw."
563645b53394SDimitry Andric     CannotThrow = false;
563745b53394SDimitry Andric   } else if (isCleanupPadScope() &&
563845b53394SDimitry Andric              EHPersonality::get(*this).isMSVCXXPersonality()) {
563945b53394SDimitry Andric     // The MSVC++ personality will implicitly terminate the program if an
5640bab175ecSDimitry Andric     // exception is thrown during a cleanup outside of a try/catch.
5641bab175ecSDimitry Andric     // We don't need to model anything in IR to get this behavior.
564245b53394SDimitry Andric     CannotThrow = true;
564345b53394SDimitry Andric   } else {
5644bab175ecSDimitry Andric     // Otherwise, nounwind call sites will never throw.
5645c0981da4SDimitry Andric     CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
5646b60736ecSDimitry Andric 
5647b60736ecSDimitry Andric     if (auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
5648b60736ecSDimitry Andric       if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
5649b60736ecSDimitry Andric         CannotThrow = true;
565045b53394SDimitry Andric   }
565148675466SDimitry Andric 
565248675466SDimitry Andric   // If we made a temporary, be sure to clean up after ourselves. Note that we
565348675466SDimitry Andric   // can't depend on being inside of an ExprWithCleanups, so we need to manually
565448675466SDimitry Andric   // pop this cleanup later on. Being eager about this is OK, since this
565548675466SDimitry Andric   // temporary is 'invisible' outside of the callee.
565648675466SDimitry Andric   if (UnusedReturnSizePtr)
565748675466SDimitry Andric     pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetAlloca,
565848675466SDimitry Andric                                          UnusedReturnSizePtr);
565948675466SDimitry Andric 
566045b53394SDimitry Andric   llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
566145b53394SDimitry Andric 
566248675466SDimitry Andric   SmallVector<llvm::OperandBundleDef, 1> BundleList =
566348675466SDimitry Andric       getBundlesForFunclet(CalleePtr);
56644ba67500SRoman Divacky 
5665e3b55780SDimitry Andric   if (SanOpts.has(SanitizerKind::KCFI) &&
5666e3b55780SDimitry Andric       !isa_and_nonnull<FunctionDecl>(TargetDecl))
5667e3b55780SDimitry Andric     EmitKCFIOperandBundle(ConcreteCallee, BundleList);
5668e3b55780SDimitry Andric 
5669ac9a064cSDimitry Andric   // Add the pointer-authentication bundle.
5670ac9a064cSDimitry Andric   EmitPointerAuthOperandBundle(ConcreteCallee.getPointerAuthInfo(), BundleList);
5671ac9a064cSDimitry Andric 
5672706b4fc4SDimitry Andric   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl))
5673b60736ecSDimitry Andric     if (FD->hasAttr<StrictFPAttr>())
5674706b4fc4SDimitry Andric       // All calls within a strictfp function are marked strictfp
5675c0981da4SDimitry Andric       Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP);
5676706b4fc4SDimitry Andric 
5677cfca06d7SDimitry Andric   AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*this, TargetDecl);
5678cfca06d7SDimitry Andric   Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5679cfca06d7SDimitry Andric 
5680cfca06d7SDimitry Andric   AllocAlignAttrEmitter AllocAlignAttrEmitter(*this, TargetDecl, CallArgs);
5681cfca06d7SDimitry Andric   Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
5682cfca06d7SDimitry Andric 
5683bab175ecSDimitry Andric   // Emit the actual call/invoke instruction.
568422989816SDimitry Andric   llvm::CallBase *CI;
56854ba67500SRoman Divacky   if (!InvokeDest) {
568622989816SDimitry Andric     CI = Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
5687ec2b103cSEd Schouten   } else {
5688ec2b103cSEd Schouten     llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
568922989816SDimitry Andric     CI = Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
569045b53394SDimitry Andric                               BundleList);
5691ec2b103cSEd Schouten     EmitBlock(Cont);
5692ec2b103cSEd Schouten   }
5693b1c73532SDimitry Andric   if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
5694312c0ed1SDimitry Andric       CI->getCalledFunction()->getName().starts_with("_Z4sqrt")) {
5695b1c73532SDimitry Andric     SetSqrtFPAccuracy(CI);
5696b1c73532SDimitry Andric   }
56974ba67500SRoman Divacky   if (callOrInvoke)
5698bab175ecSDimitry Andric     *callOrInvoke = CI;
5699ec2b103cSEd Schouten 
5700706b4fc4SDimitry Andric   // If this is within a function that has the guard(nocf) attribute and is an
5701706b4fc4SDimitry Andric   // indirect call, add the "guard_nocf" attribute to this call to indicate that
5702706b4fc4SDimitry Andric   // Control Flow Guard checks should not be added, even if the call is inlined.
5703706b4fc4SDimitry Andric   if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
5704706b4fc4SDimitry Andric     if (const auto *A = FD->getAttr<CFGuardAttr>()) {
5705706b4fc4SDimitry Andric       if (A->getGuard() == CFGuardAttr::GuardArg::nocf && !CI->getCalledFunction())
5706c0981da4SDimitry Andric         Attrs = Attrs.addFnAttribute(getLLVMContext(), "guard_nocf");
5707706b4fc4SDimitry Andric     }
5708706b4fc4SDimitry Andric   }
5709706b4fc4SDimitry Andric 
5710bab175ecSDimitry Andric   // Apply the attributes and calling convention.
571122989816SDimitry Andric   CI->setAttributes(Attrs);
571222989816SDimitry Andric   CI->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
5713ec2b103cSEd Schouten 
5714bab175ecSDimitry Andric   // Apply various metadata.
5715bab175ecSDimitry Andric 
5716bab175ecSDimitry Andric   if (!CI->getType()->isVoidTy())
5717bab175ecSDimitry Andric     CI->setName("call");
5718bab175ecSDimitry Andric 
5719ac9a064cSDimitry Andric   if (CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
5720ac9a064cSDimitry Andric     CI = addControlledConvergenceToken(CI);
5721ac9a064cSDimitry Andric 
5722676fbe81SDimitry Andric   // Update largest vector width from the return type.
5723cfca06d7SDimitry Andric   LargestVectorWidth =
5724145449b1SDimitry Andric       std::max(LargestVectorWidth, getMaxVectorWidth(CI->getType()));
5725676fbe81SDimitry Andric 
57262b6b257fSDimitry Andric   // Insert instrumentation or attach profile metadata at indirect call sites.
57272b6b257fSDimitry Andric   // For more details, see the comment before the definition of
57282b6b257fSDimitry Andric   // IPVK_IndirectCallTarget in InstrProfData.inc.
572922989816SDimitry Andric   if (!CI->getCalledFunction())
57302b6b257fSDimitry Andric     PGO.valueProfile(Builder, llvm::IPVK_IndirectCallTarget,
5731bab175ecSDimitry Andric                      CI, CalleePtr);
57322b6b257fSDimitry Andric 
5733dbe13110SDimitry Andric   // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
5734dbe13110SDimitry Andric   // optimizer it can aggressively ignore unwind edges.
5735dbe13110SDimitry Andric   if (CGM.getLangOpts().ObjCAutoRefCount)
5736bab175ecSDimitry Andric     AddObjCARCExceptionMetadata(CI);
5737bab175ecSDimitry Andric 
5738344a3780SDimitry Andric   // Set tail call kind if necessary.
5739bab175ecSDimitry Andric   if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
5740bab175ecSDimitry Andric     if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
5741bab175ecSDimitry Andric       Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
5742ac9a064cSDimitry Andric     else if (IsMustTail) {
5743ac9a064cSDimitry Andric       if (getTarget().getTriple().isPPC()) {
5744ac9a064cSDimitry Andric         if (getTarget().getTriple().isOSAIX())
5745ac9a064cSDimitry Andric           CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
5746ac9a064cSDimitry Andric         else if (!getTarget().hasFeature("pcrelative-memops")) {
5747ac9a064cSDimitry Andric           if (getTarget().hasFeature("longcall"))
5748ac9a064cSDimitry Andric             CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
5749ac9a064cSDimitry Andric           else if (Call->isIndirectCall())
5750ac9a064cSDimitry Andric             CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
5751ac9a064cSDimitry Andric           else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
5752ac9a064cSDimitry Andric             if (!cast<FunctionDecl>(TargetDecl)->isDefined())
5753ac9a064cSDimitry Andric               // The undefined callee may be a forward declaration. Without
5754ac9a064cSDimitry Andric               // knowning all symbols in the module, we won't know the symbol is
5755ac9a064cSDimitry Andric               // defined or not. Collect all these symbols for later diagnosing.
5756ac9a064cSDimitry Andric               CGM.addUndefinedGlobalForTailCall(
5757ac9a064cSDimitry Andric                   {cast<FunctionDecl>(TargetDecl), Loc});
5758ac9a064cSDimitry Andric             else {
5759ac9a064cSDimitry Andric               llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(
5760ac9a064cSDimitry Andric                   GlobalDecl(cast<FunctionDecl>(TargetDecl)));
5761ac9a064cSDimitry Andric               if (llvm::GlobalValue::isWeakForLinker(Linkage) ||
5762ac9a064cSDimitry Andric                   llvm::GlobalValue::isDiscardableIfUnused(Linkage))
5763ac9a064cSDimitry Andric                 CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
5764ac9a064cSDimitry Andric                     << 2;
5765ac9a064cSDimitry Andric             }
5766ac9a064cSDimitry Andric           }
5767ac9a064cSDimitry Andric         }
5768ac9a064cSDimitry Andric       }
5769344a3780SDimitry Andric       Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
5770bab175ecSDimitry Andric     }
5771ac9a064cSDimitry Andric   }
5772bab175ecSDimitry Andric 
577322989816SDimitry Andric   // Add metadata for calls to MSAllocator functions
577422989816SDimitry Andric   if (getDebugInfo() && TargetDecl &&
577522989816SDimitry Andric       TargetDecl->hasAttr<MSAllocatorAttr>())
5776cfca06d7SDimitry Andric     getDebugInfo()->addHeapAllocSiteMetadata(CI, RetTy->getPointeeType(), Loc);
577722989816SDimitry Andric 
5778c0981da4SDimitry Andric   // Add metadata if calling an __attribute__((error(""))) or warning fn.
5779c0981da4SDimitry Andric   if (TargetDecl && TargetDecl->hasAttr<ErrorAttr>()) {
5780c0981da4SDimitry Andric     llvm::ConstantInt *Line =
5781ac9a064cSDimitry Andric         llvm::ConstantInt::get(Int64Ty, Loc.getRawEncoding());
5782c0981da4SDimitry Andric     llvm::ConstantAsMetadata *MD = llvm::ConstantAsMetadata::get(Line);
5783c0981da4SDimitry Andric     llvm::MDTuple *MDT = llvm::MDNode::get(getLLVMContext(), {MD});
5784c0981da4SDimitry Andric     CI->setMetadata("srcloc", MDT);
5785c0981da4SDimitry Andric   }
5786c0981da4SDimitry Andric 
5787bab175ecSDimitry Andric   // 4. Finish the call.
5788dbe13110SDimitry Andric 
5789ec2b103cSEd Schouten   // If the call doesn't return, finish the basic block and clear the
5790bab175ecSDimitry Andric   // insertion point; this allows the rest of IRGen to discard
5791ec2b103cSEd Schouten   // unreachable code.
579222989816SDimitry Andric   if (CI->doesNotReturn()) {
579348675466SDimitry Andric     if (UnusedReturnSizePtr)
579448675466SDimitry Andric       PopCleanupBlock();
5795798321d8SDimitry Andric 
57966252156dSDimitry Andric     // Strip away the noreturn attribute to better diagnose unreachable UB.
57976252156dSDimitry Andric     if (SanOpts.has(SanitizerKind::Unreachable)) {
579822989816SDimitry Andric       // Also remove from function since CallBase::hasFnAttr additionally checks
579922989816SDimitry Andric       // attributes of the called function.
580022989816SDimitry Andric       if (auto *F = CI->getCalledFunction())
58016252156dSDimitry Andric         F->removeFnAttr(llvm::Attribute::NoReturn);
5802c0981da4SDimitry Andric       CI->removeFnAttr(llvm::Attribute::NoReturn);
580322989816SDimitry Andric 
580422989816SDimitry Andric       // Avoid incompatibility with ASan which relies on the `noreturn`
580522989816SDimitry Andric       // attribute to insert handler calls.
580622989816SDimitry Andric       if (SanOpts.hasOneOf(SanitizerKind::Address |
580722989816SDimitry Andric                            SanitizerKind::KernelAddress)) {
580822989816SDimitry Andric         SanitizerScope SanScope(this);
580922989816SDimitry Andric         llvm::IRBuilder<>::InsertPointGuard IPGuard(Builder);
581022989816SDimitry Andric         Builder.SetInsertPoint(CI);
581122989816SDimitry Andric         auto *FnType = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
581222989816SDimitry Andric         llvm::FunctionCallee Fn =
581322989816SDimitry Andric             CGM.CreateRuntimeFunction(FnType, "__asan_handle_no_return");
581422989816SDimitry Andric         EmitNounwindRuntimeCall(Fn);
581522989816SDimitry Andric       }
58166252156dSDimitry Andric     }
58176252156dSDimitry Andric 
58186252156dSDimitry Andric     EmitUnreachable(Loc);
5819ec2b103cSEd Schouten     Builder.ClearInsertionPoint();
5820ec2b103cSEd Schouten 
5821ec2b103cSEd Schouten     // FIXME: For now, emit a dummy basic block because expr emitters in
5822ec2b103cSEd Schouten     // generally are not ready to handle emitting expressions at unreachable
5823ec2b103cSEd Schouten     // points.
5824ec2b103cSEd Schouten     EnsureInsertPoint();
5825ec2b103cSEd Schouten 
5826ec2b103cSEd Schouten     // Return a reasonable RValue.
5827ec2b103cSEd Schouten     return GetUndefRValue(RetTy);
5828ec2b103cSEd Schouten   }
5829ec2b103cSEd Schouten 
5830344a3780SDimitry Andric   // If this is a musttail call, return immediately. We do not branch to the
5831344a3780SDimitry Andric   // epilogue in this case.
5832344a3780SDimitry Andric   if (IsMustTail) {
5833344a3780SDimitry Andric     for (auto it = EHStack.find(CurrentCleanupScopeDepth); it != EHStack.end();
5834344a3780SDimitry Andric          ++it) {
5835344a3780SDimitry Andric       EHCleanupScope *Cleanup = dyn_cast<EHCleanupScope>(&*it);
5836344a3780SDimitry Andric       if (!(Cleanup && Cleanup->getCleanup()->isRedundantBeforeReturn()))
5837344a3780SDimitry Andric         CGM.ErrorUnsupported(MustTailCall, "tail call skipping over cleanups");
5838344a3780SDimitry Andric     }
5839344a3780SDimitry Andric     if (CI->getType()->isVoidTy())
5840344a3780SDimitry Andric       Builder.CreateRetVoid();
5841344a3780SDimitry Andric     else
5842344a3780SDimitry Andric       Builder.CreateRet(CI);
5843344a3780SDimitry Andric     Builder.ClearInsertionPoint();
5844344a3780SDimitry Andric     EnsureInsertPoint();
5845344a3780SDimitry Andric     return GetUndefRValue(RetTy);
5846344a3780SDimitry Andric   }
5847344a3780SDimitry Andric 
58482b6b257fSDimitry Andric   // Perform the swifterror writeback.
58492b6b257fSDimitry Andric   if (swiftErrorTemp.isValid()) {
58502b6b257fSDimitry Andric     llvm::Value *errorResult = Builder.CreateLoad(swiftErrorTemp);
58512b6b257fSDimitry Andric     Builder.CreateStore(errorResult, swiftErrorArg);
58522b6b257fSDimitry Andric   }
58532b6b257fSDimitry Andric 
5854bab175ecSDimitry Andric   // Emit any call-associated writebacks immediately.  Arguably this
5855bab175ecSDimitry Andric   // should happen after any return-value munging.
5856180abc3dSDimitry Andric   if (CallArgs.hasWritebacks())
5857180abc3dSDimitry Andric     emitWritebacks(*this, CallArgs);
5858180abc3dSDimitry Andric 
58599f4dbff6SDimitry Andric   // The stack cleanup for inalloca arguments has to run out of the normal
58609f4dbff6SDimitry Andric   // lexical order, so deactivate it and run it manually here.
58619f4dbff6SDimitry Andric   CallArgs.freeArgumentMemory(*this);
58629f4dbff6SDimitry Andric 
5863bab175ecSDimitry Andric   // Extract the return value.
5864ac9a064cSDimitry Andric   RValue Ret;
5865ac9a064cSDimitry Andric 
5866ac9a064cSDimitry Andric   // If the current function is a virtual function pointer thunk, avoid copying
5867ac9a064cSDimitry Andric   // the return value of the musttail call to a temporary.
5868ac9a064cSDimitry Andric   if (IsVirtualFunctionPointerThunk) {
5869ac9a064cSDimitry Andric     Ret = RValue::get(CI);
5870ac9a064cSDimitry Andric   } else {
5871ac9a064cSDimitry Andric     Ret = [&] {
5872ec2b103cSEd Schouten       switch (RetAI.getKind()) {
58732b6b257fSDimitry Andric       case ABIArgInfo::CoerceAndExpand: {
58742b6b257fSDimitry Andric         auto coercionType = RetAI.getCoerceAndExpandType();
58752b6b257fSDimitry Andric 
58767fa27ce4SDimitry Andric         Address addr = SRetPtr.withElementType(coercionType);
58772b6b257fSDimitry Andric 
58782b6b257fSDimitry Andric         assert(CI->getType() == RetAI.getUnpaddedCoerceAndExpandType());
58792b6b257fSDimitry Andric         bool requiresExtract = isa<llvm::StructType>(CI->getType());
58802b6b257fSDimitry Andric 
58812b6b257fSDimitry Andric         unsigned unpaddedIndex = 0;
58822b6b257fSDimitry Andric         for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
58832b6b257fSDimitry Andric           llvm::Type *eltType = coercionType->getElementType(i);
5884ac9a064cSDimitry Andric           if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType))
5885ac9a064cSDimitry Andric             continue;
588622989816SDimitry Andric           Address eltAddr = Builder.CreateStructGEP(addr, i);
58872b6b257fSDimitry Andric           llvm::Value *elt = CI;
58882b6b257fSDimitry Andric           if (requiresExtract)
58892b6b257fSDimitry Andric             elt = Builder.CreateExtractValue(elt, unpaddedIndex++);
58902b6b257fSDimitry Andric           else
58912b6b257fSDimitry Andric             assert(unpaddedIndex == 0);
58922b6b257fSDimitry Andric           Builder.CreateStore(elt, eltAddr);
58932b6b257fSDimitry Andric         }
5894e3b55780SDimitry Andric         [[fallthrough]];
58952b6b257fSDimitry Andric       }
58962b6b257fSDimitry Andric 
58979f4dbff6SDimitry Andric       case ABIArgInfo::InAlloca:
5898798321d8SDimitry Andric       case ABIArgInfo::Indirect: {
5899798321d8SDimitry Andric         RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation());
590048675466SDimitry Andric         if (UnusedReturnSizePtr)
590148675466SDimitry Andric           PopCleanupBlock();
5902798321d8SDimitry Andric         return ret;
5903798321d8SDimitry Andric       }
59043d1dcd9bSDimitry Andric 
59053d1dcd9bSDimitry Andric       case ABIArgInfo::Ignore:
59063d1dcd9bSDimitry Andric         // If we are ignoring an argument that had a result, make sure to
59073d1dcd9bSDimitry Andric         // construct the appropriate return value for our caller.
59083d1dcd9bSDimitry Andric         return GetUndefRValue(RetTy);
5909ec2b103cSEd Schouten 
591070b4596dSEd Schouten       case ABIArgInfo::Extend:
59113d1dcd9bSDimitry Andric       case ABIArgInfo::Direct: {
5912180abc3dSDimitry Andric         llvm::Type *RetIRTy = ConvertType(RetTy);
5913ac9a064cSDimitry Andric         if (RetAI.getCoerceToType() == RetIRTy &&
5914ac9a064cSDimitry Andric             RetAI.getDirectOffset() == 0) {
5915809500fcSDimitry Andric           switch (getEvaluationKind(RetTy)) {
5916809500fcSDimitry Andric           case TEK_Complex: {
5917ec2b103cSEd Schouten             llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
5918ec2b103cSEd Schouten             llvm::Value *Imag = Builder.CreateExtractValue(CI, 1);
5919ec2b103cSEd Schouten             return RValue::getComplex(std::make_pair(Real, Imag));
5920ec2b103cSEd Schouten           }
59211de139fdSDimitry Andric           case TEK_Aggregate:
59221de139fdSDimitry Andric             break;
5923809500fcSDimitry Andric           case TEK_Scalar: {
5924ac9a064cSDimitry Andric             // If the argument doesn't match, perform a bitcast to coerce it.
5925ac9a064cSDimitry Andric             // This can happen due to trivial type mismatches.
5926180abc3dSDimitry Andric             llvm::Value *V = CI;
5927180abc3dSDimitry Andric             if (V->getType() != RetIRTy)
5928180abc3dSDimitry Andric               V = Builder.CreateBitCast(V, RetIRTy);
5929180abc3dSDimitry Andric             return RValue::get(V);
59303d1dcd9bSDimitry Andric           }
5931809500fcSDimitry Andric           }
5932809500fcSDimitry Andric         }
5933ec2b103cSEd Schouten 
59347fa27ce4SDimitry Andric         // If coercing a fixed vector from a scalable vector for ABI
59357fa27ce4SDimitry Andric         // compatibility, and the types match, use the llvm.vector.extract
59367fa27ce4SDimitry Andric         // intrinsic to perform the conversion.
5937ac9a064cSDimitry Andric         if (auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
59387fa27ce4SDimitry Andric           llvm::Value *V = CI;
5939ac9a064cSDimitry Andric           if (auto *ScalableSrcTy =
5940ac9a064cSDimitry Andric                   dyn_cast<llvm::ScalableVectorType>(V->getType())) {
5941ac9a064cSDimitry Andric             if (FixedDstTy->getElementType() ==
5942ac9a064cSDimitry Andric                 ScalableSrcTy->getElementType()) {
59437fa27ce4SDimitry Andric               llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int64Ty);
5944ac9a064cSDimitry Andric               V = Builder.CreateExtractVector(FixedDstTy, V, Zero,
5945ac9a064cSDimitry Andric                                               "cast.fixed");
59467fa27ce4SDimitry Andric               return RValue::get(V);
59477fa27ce4SDimitry Andric             }
59487fa27ce4SDimitry Andric           }
59497fa27ce4SDimitry Andric         }
59507fa27ce4SDimitry Andric 
595145b53394SDimitry Andric         Address DestPtr = ReturnValue.getValue();
5952abe15e55SRoman Divacky         bool DestIsVolatile = ReturnValue.isVolatile();
59531de139fdSDimitry Andric         uint64_t DestSize =
59541de139fdSDimitry Andric             getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity();
5955abe15e55SRoman Divacky 
595645b53394SDimitry Andric         if (!DestPtr.isValid()) {
5957ecb7e5c8SRoman Divacky           DestPtr = CreateMemTemp(RetTy, "coerce");
5958abe15e55SRoman Divacky           DestIsVolatile = false;
59591de139fdSDimitry Andric           DestSize = getContext().getTypeSizeInChars(RetTy).getQuantity();
5960abe15e55SRoman Divacky         }
5961abe15e55SRoman Divacky 
5962b1c73532SDimitry Andric         // An empty record can overlap other data (if declared with
5963b1c73532SDimitry Andric         // no_unique_address); omit the store for such types - as there is no
5964b1c73532SDimitry Andric         // actual data to store.
5965b1c73532SDimitry Andric         if (!isEmptyRecord(getContext(), RetTy, true)) {
59663d1dcd9bSDimitry Andric           // If the value is offset in memory, apply the offset now.
596745b53394SDimitry Andric           Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI);
59681de139fdSDimitry Andric           CreateCoercedStore(
59691de139fdSDimitry Andric               CI, StorePtr,
59701de139fdSDimitry Andric               llvm::TypeSize::getFixed(DestSize - RetAI.getDirectOffset()),
59711de139fdSDimitry Andric               DestIsVolatile);
5972b1c73532SDimitry Andric         }
59733d1dcd9bSDimitry Andric 
5974bfef3995SDimitry Andric         return convertTempToRValue(DestPtr, RetTy, SourceLocation());
5975ec2b103cSEd Schouten       }
5976ec2b103cSEd Schouten 
5977ec2b103cSEd Schouten       case ABIArgInfo::Expand:
5978b60736ecSDimitry Andric       case ABIArgInfo::IndirectAliased:
597936981b17SDimitry Andric         llvm_unreachable("Invalid ABI kind for return argument");
5980ec2b103cSEd Schouten       }
5981ec2b103cSEd Schouten 
598236981b17SDimitry Andric       llvm_unreachable("Unhandled ABIArgInfo::Kind");
598306d4ba38SDimitry Andric     }();
5984ac9a064cSDimitry Andric   }
598506d4ba38SDimitry Andric 
5986bab175ecSDimitry Andric   // Emit the assume_aligned check on the return value.
598706d4ba38SDimitry Andric   if (Ret.isScalar() && TargetDecl) {
5988cfca06d7SDimitry Andric     AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
5989cfca06d7SDimitry Andric     AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
599006d4ba38SDimitry Andric   }
599106d4ba38SDimitry Andric 
5992519fc96cSDimitry Andric   // Explicitly call CallLifetimeEnd::Emit just to re-use the code even though
5993519fc96cSDimitry Andric   // we can't use the full cleanup mechanism.
5994519fc96cSDimitry Andric   for (CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall)
5995519fc96cSDimitry Andric     LifetimeEnd.Emit(*this, /*Flags=*/{});
5996519fc96cSDimitry Andric 
5997cfca06d7SDimitry Andric   if (!ReturnValue.isExternallyDestructed() &&
5998cfca06d7SDimitry Andric       RetTy.isDestructedType() == QualType::DK_nontrivial_c_struct)
5999cfca06d7SDimitry Andric     pushDestroy(QualType::DK_nontrivial_c_struct, Ret.getAggregateAddress(),
6000cfca06d7SDimitry Andric                 RetTy);
6001cfca06d7SDimitry Andric 
600206d4ba38SDimitry Andric   return Ret;
6003ec2b103cSEd Schouten }
6004ec2b103cSEd Schouten 
prepareConcreteCallee(CodeGenFunction & CGF) const600548675466SDimitry Andric CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
600648675466SDimitry Andric   if (isVirtual()) {
600748675466SDimitry Andric     const CallExpr *CE = getVirtualCallExpr();
600848675466SDimitry Andric     return CGF.CGM.getCXXABI().getVirtualFunctionPointer(
600922989816SDimitry Andric         CGF, getVirtualMethodDecl(), getThisAddress(), getVirtualFunctionType(),
6010676fbe81SDimitry Andric         CE ? CE->getBeginLoc() : SourceLocation());
601148675466SDimitry Andric   }
601248675466SDimitry Andric 
601348675466SDimitry Andric   return *this;
601448675466SDimitry Andric }
601548675466SDimitry Andric 
6016ec2b103cSEd Schouten /* VarArg handling */
6017ec2b103cSEd Schouten 
EmitVAArg(VAArgExpr * VE,Address & VAListAddr,AggValueSlot Slot)6018ac9a064cSDimitry Andric RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
6019ac9a064cSDimitry Andric                                   AggValueSlot Slot) {
6020ac9a064cSDimitry Andric   VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr())
602145b53394SDimitry Andric                                     : EmitVAListRef(VE->getSubExpr());
602245b53394SDimitry Andric   QualType Ty = VE->getType();
602345b53394SDimitry Andric   if (VE->isMicrosoftABI())
6024e6b73279SDimitry Andric     return CGM.getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty, Slot);
6025e6b73279SDimitry Andric   return CGM.getABIInfo().EmitVAArg(*this, VAListAddr, Ty, Slot);
6026ec2b103cSEd Schouten }
6027