10b57cec5SDimitry Andric //===--- CGCall.cpp - Encapsulate calling convention details --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // These classes wrap the information about a call or function
100b57cec5SDimitry Andric // definition used to handle ABI compliancy.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #include "CGCall.h"
150b57cec5SDimitry Andric #include "ABIInfo.h"
168a4dda33SDimitry Andric #include "ABIInfoImpl.h"
170b57cec5SDimitry Andric #include "CGBlocks.h"
180b57cec5SDimitry Andric #include "CGCXXABI.h"
190b57cec5SDimitry Andric #include "CGCleanup.h"
205ffd83dbSDimitry Andric #include "CGRecordLayout.h"
210b57cec5SDimitry Andric #include "CodeGenFunction.h"
220b57cec5SDimitry Andric #include "CodeGenModule.h"
230b57cec5SDimitry Andric #include "TargetInfo.h"
24480093f4SDimitry Andric #include "clang/AST/Attr.h"
250b57cec5SDimitry Andric #include "clang/AST/Decl.h"
260b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
270b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
280b57cec5SDimitry Andric #include "clang/Basic/CodeGenOptions.h"
290b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h"
300b57cec5SDimitry Andric #include "clang/CodeGen/CGFunctionInfo.h"
310b57cec5SDimitry Andric #include "clang/CodeGen/SwiftCallingConv.h"
320b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
330b57cec5SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
34e8d8bef9SDimitry Andric #include "llvm/IR/Assumptions.h"
3506c3fb27SDimitry Andric #include "llvm/IR/AttributeMask.h"
360b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
370b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h"
380b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
390b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h"
400b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
410b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
426a5eebc1SDimitry Andric #include "llvm/IR/Type.h"
43480093f4SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
44bdd1243dSDimitry Andric #include <optional>
450b57cec5SDimitry Andric using namespace clang;
460b57cec5SDimitry Andric using namespace CodeGen;
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric /***/
490b57cec5SDimitry Andric
ClangCallConvToLLVMCallConv(CallingConv CC)500b57cec5SDimitry Andric unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
510b57cec5SDimitry Andric switch (CC) {
520b57cec5SDimitry Andric default: return llvm::CallingConv::C;
530b57cec5SDimitry Andric case CC_X86StdCall: return llvm::CallingConv::X86_StdCall;
540b57cec5SDimitry Andric case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
550b57cec5SDimitry Andric case CC_X86RegCall: return llvm::CallingConv::X86_RegCall;
560b57cec5SDimitry Andric case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
570b57cec5SDimitry Andric case CC_Win64: return llvm::CallingConv::Win64;
580b57cec5SDimitry Andric case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV;
590b57cec5SDimitry Andric case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS;
600b57cec5SDimitry Andric case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP;
610b57cec5SDimitry Andric case CC_IntelOclBicc: return llvm::CallingConv::Intel_OCL_BI;
620b57cec5SDimitry Andric // TODO: Add support for __pascal to LLVM.
630b57cec5SDimitry Andric case CC_X86Pascal: return llvm::CallingConv::C;
640b57cec5SDimitry Andric // TODO: Add support for __vectorcall to LLVM.
650b57cec5SDimitry Andric case CC_X86VectorCall: return llvm::CallingConv::X86_VectorCall;
660b57cec5SDimitry Andric case CC_AArch64VectorCall: return llvm::CallingConv::AArch64_VectorCall;
6781ad6265SDimitry Andric case CC_AArch64SVEPCS: return llvm::CallingConv::AArch64_SVE_VectorCall;
6881ad6265SDimitry Andric case CC_AMDGPUKernelCall: return llvm::CallingConv::AMDGPU_KERNEL;
690b57cec5SDimitry Andric case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC;
700b57cec5SDimitry Andric case CC_OpenCLKernel: return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv();
710b57cec5SDimitry Andric case CC_PreserveMost: return llvm::CallingConv::PreserveMost;
720b57cec5SDimitry Andric case CC_PreserveAll: return llvm::CallingConv::PreserveAll;
730b57cec5SDimitry Andric case CC_Swift: return llvm::CallingConv::Swift;
74fe6060f1SDimitry Andric case CC_SwiftAsync: return llvm::CallingConv::SwiftTail;
755f757f3fSDimitry Andric case CC_M68kRTD: return llvm::CallingConv::M68k_RTD;
760fca6ea1SDimitry Andric case CC_PreserveNone: return llvm::CallingConv::PreserveNone;
770fca6ea1SDimitry Andric // clang-format off
780fca6ea1SDimitry Andric case CC_RISCVVectorCall: return llvm::CallingConv::RISCV_VectorCall;
790fca6ea1SDimitry Andric // clang-format on
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric
830b57cec5SDimitry Andric /// Derives the 'this' type for codegen purposes, i.e. ignoring method CVR
840b57cec5SDimitry Andric /// qualification. Either or both of RD and MD may be null. A null RD indicates
850b57cec5SDimitry Andric /// that there is no meaningful 'this' type, and a null MD can occur when
860b57cec5SDimitry Andric /// calling a method pointer.
DeriveThisType(const CXXRecordDecl * RD,const CXXMethodDecl * MD)870b57cec5SDimitry Andric CanQualType CodeGenTypes::DeriveThisType(const CXXRecordDecl *RD,
880b57cec5SDimitry Andric const CXXMethodDecl *MD) {
890b57cec5SDimitry Andric QualType RecTy;
900b57cec5SDimitry Andric if (RD)
910b57cec5SDimitry Andric RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal();
920b57cec5SDimitry Andric else
930b57cec5SDimitry Andric RecTy = Context.VoidTy;
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric if (MD)
960b57cec5SDimitry Andric RecTy = Context.getAddrSpaceQualType(RecTy, MD->getMethodQualifiers().getAddressSpace());
970b57cec5SDimitry Andric return Context.getPointerType(CanQualType::CreateUnsafe(RecTy));
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric /// Returns the canonical formal type of the given C++ method.
GetFormalType(const CXXMethodDecl * MD)1010b57cec5SDimitry Andric static CanQual<FunctionProtoType> GetFormalType(const CXXMethodDecl *MD) {
1020b57cec5SDimitry Andric return MD->getType()->getCanonicalTypeUnqualified()
1030b57cec5SDimitry Andric .getAs<FunctionProtoType>();
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric /// Returns the "extra-canonicalized" return type, which discards
1070b57cec5SDimitry Andric /// qualifiers on the return type. Codegen doesn't care about them,
1080b57cec5SDimitry Andric /// and it makes ABI code a little easier to be able to assume that
1090b57cec5SDimitry Andric /// all parameter and return types are top-level unqualified.
GetReturnType(QualType RetTy)1100b57cec5SDimitry Andric static CanQualType GetReturnType(QualType RetTy) {
1110b57cec5SDimitry Andric return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType();
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric
1140b57cec5SDimitry Andric /// Arrange the argument and result information for a value of the given
1150b57cec5SDimitry Andric /// unprototyped freestanding function type.
1160b57cec5SDimitry Andric const CGFunctionInfo &
arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP)1170b57cec5SDimitry Andric CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> FTNP) {
1180b57cec5SDimitry Andric // When translating an unprototyped function type, always use a
1190b57cec5SDimitry Andric // variadic type.
1200b57cec5SDimitry Andric return arrangeLLVMFunctionInfo(FTNP->getReturnType().getUnqualifiedType(),
1218a4dda33SDimitry Andric FnInfoOpts::None, std::nullopt,
1220b57cec5SDimitry Andric FTNP->getExtInfo(), {}, RequiredArgs(0));
1230b57cec5SDimitry Andric }
1240b57cec5SDimitry Andric
addExtParameterInfosForCall(llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> & paramInfos,const FunctionProtoType * proto,unsigned prefixArgs,unsigned totalArgs)1250b57cec5SDimitry Andric static void addExtParameterInfosForCall(
1260b57cec5SDimitry Andric llvm::SmallVectorImpl<FunctionProtoType::ExtParameterInfo> ¶mInfos,
1270b57cec5SDimitry Andric const FunctionProtoType *proto,
1280b57cec5SDimitry Andric unsigned prefixArgs,
1290b57cec5SDimitry Andric unsigned totalArgs) {
1300b57cec5SDimitry Andric assert(proto->hasExtParameterInfos());
1310b57cec5SDimitry Andric assert(paramInfos.size() <= prefixArgs);
1320b57cec5SDimitry Andric assert(proto->getNumParams() + prefixArgs <= totalArgs);
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric paramInfos.reserve(totalArgs);
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric // Add default infos for any prefix args that don't already have infos.
1370b57cec5SDimitry Andric paramInfos.resize(prefixArgs);
1380b57cec5SDimitry Andric
1390b57cec5SDimitry Andric // Add infos for the prototype.
1400b57cec5SDimitry Andric for (const auto &ParamInfo : proto->getExtParameterInfos()) {
1410b57cec5SDimitry Andric paramInfos.push_back(ParamInfo);
1420b57cec5SDimitry Andric // pass_object_size params have no parameter info.
1430b57cec5SDimitry Andric if (ParamInfo.hasPassObjectSize())
1440b57cec5SDimitry Andric paramInfos.emplace_back();
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric
1470b57cec5SDimitry Andric assert(paramInfos.size() <= totalArgs &&
1480b57cec5SDimitry Andric "Did we forget to insert pass_object_size args?");
1490b57cec5SDimitry Andric // Add default infos for the variadic and/or suffix arguments.
1500b57cec5SDimitry Andric paramInfos.resize(totalArgs);
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric
1530b57cec5SDimitry Andric /// Adds the formal parameters in FPT to the given prefix. If any parameter in
1540b57cec5SDimitry 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)1550b57cec5SDimitry Andric static void appendParameterTypes(const CodeGenTypes &CGT,
1560b57cec5SDimitry Andric SmallVectorImpl<CanQualType> &prefix,
1570b57cec5SDimitry Andric SmallVectorImpl<FunctionProtoType::ExtParameterInfo> ¶mInfos,
1580b57cec5SDimitry Andric CanQual<FunctionProtoType> FPT) {
1590b57cec5SDimitry Andric // Fast path: don't touch param info if we don't need to.
1600b57cec5SDimitry Andric if (!FPT->hasExtParameterInfos()) {
1610b57cec5SDimitry Andric assert(paramInfos.empty() &&
1620b57cec5SDimitry Andric "We have paramInfos, but the prototype doesn't?");
1630b57cec5SDimitry Andric prefix.append(FPT->param_type_begin(), FPT->param_type_end());
1640b57cec5SDimitry Andric return;
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric
1670b57cec5SDimitry Andric unsigned PrefixSize = prefix.size();
1680b57cec5SDimitry Andric // In the vast majority of cases, we'll have precisely FPT->getNumParams()
1690b57cec5SDimitry Andric // parameters; the only thing that can change this is the presence of
1700b57cec5SDimitry Andric // pass_object_size. So, we preallocate for the common case.
1710b57cec5SDimitry Andric prefix.reserve(prefix.size() + FPT->getNumParams());
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric auto ExtInfos = FPT->getExtParameterInfos();
1740b57cec5SDimitry Andric assert(ExtInfos.size() == FPT->getNumParams());
1750b57cec5SDimitry Andric for (unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
1760b57cec5SDimitry Andric prefix.push_back(FPT->getParamType(I));
1770b57cec5SDimitry Andric if (ExtInfos[I].hasPassObjectSize())
1780b57cec5SDimitry Andric prefix.push_back(CGT.getContext().getSizeType());
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric addExtParameterInfosForCall(paramInfos, FPT.getTypePtr(), PrefixSize,
1820b57cec5SDimitry Andric prefix.size());
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric /// Arrange the LLVM function layout for a value of the given function
1860b57cec5SDimitry Andric /// type, on top of any implicit parameters already stored.
1870b57cec5SDimitry Andric static const CGFunctionInfo &
arrangeLLVMFunctionInfo(CodeGenTypes & CGT,bool instanceMethod,SmallVectorImpl<CanQualType> & prefix,CanQual<FunctionProtoType> FTP)1880b57cec5SDimitry Andric arrangeLLVMFunctionInfo(CodeGenTypes &CGT, bool instanceMethod,
1890b57cec5SDimitry Andric SmallVectorImpl<CanQualType> &prefix,
1900b57cec5SDimitry Andric CanQual<FunctionProtoType> FTP) {
1910b57cec5SDimitry Andric SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
1920b57cec5SDimitry Andric RequiredArgs Required = RequiredArgs::forPrototypePlus(FTP, prefix.size());
1930b57cec5SDimitry Andric // FIXME: Kill copy.
1940b57cec5SDimitry Andric appendParameterTypes(CGT, prefix, paramInfos, FTP);
1950b57cec5SDimitry Andric CanQualType resultType = FTP->getReturnType().getUnqualifiedType();
1960b57cec5SDimitry Andric
1978a4dda33SDimitry Andric FnInfoOpts opts =
1988a4dda33SDimitry Andric instanceMethod ? FnInfoOpts::IsInstanceMethod : FnInfoOpts::None;
1998a4dda33SDimitry Andric return CGT.arrangeLLVMFunctionInfo(resultType, opts, prefix,
2008a4dda33SDimitry Andric FTP->getExtInfo(), paramInfos, Required);
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric
2030b57cec5SDimitry Andric /// Arrange the argument and result information for a value of the
2040b57cec5SDimitry Andric /// given freestanding function type.
2050b57cec5SDimitry Andric const CGFunctionInfo &
arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP)2060b57cec5SDimitry Andric CodeGenTypes::arrangeFreeFunctionType(CanQual<FunctionProtoType> FTP) {
2070b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
2080b57cec5SDimitry Andric return ::arrangeLLVMFunctionInfo(*this, /*instanceMethod=*/false, argTypes,
2090b57cec5SDimitry Andric FTP);
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric
getCallingConventionForDecl(const ObjCMethodDecl * D,bool IsWindows)212e8d8bef9SDimitry Andric static CallingConv getCallingConventionForDecl(const ObjCMethodDecl *D,
213e8d8bef9SDimitry Andric bool IsWindows) {
2140b57cec5SDimitry Andric // Set the appropriate calling convention for the Function.
2150b57cec5SDimitry Andric if (D->hasAttr<StdCallAttr>())
2160b57cec5SDimitry Andric return CC_X86StdCall;
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric if (D->hasAttr<FastCallAttr>())
2190b57cec5SDimitry Andric return CC_X86FastCall;
2200b57cec5SDimitry Andric
2210b57cec5SDimitry Andric if (D->hasAttr<RegCallAttr>())
2220b57cec5SDimitry Andric return CC_X86RegCall;
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric if (D->hasAttr<ThisCallAttr>())
2250b57cec5SDimitry Andric return CC_X86ThisCall;
2260b57cec5SDimitry Andric
2270b57cec5SDimitry Andric if (D->hasAttr<VectorCallAttr>())
2280b57cec5SDimitry Andric return CC_X86VectorCall;
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric if (D->hasAttr<PascalAttr>())
2310b57cec5SDimitry Andric return CC_X86Pascal;
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric if (PcsAttr *PCS = D->getAttr<PcsAttr>())
2340b57cec5SDimitry Andric return (PCS->getPCS() == PcsAttr::AAPCS ? CC_AAPCS : CC_AAPCS_VFP);
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric if (D->hasAttr<AArch64VectorPcsAttr>())
2370b57cec5SDimitry Andric return CC_AArch64VectorCall;
2380b57cec5SDimitry Andric
23981ad6265SDimitry Andric if (D->hasAttr<AArch64SVEPcsAttr>())
24081ad6265SDimitry Andric return CC_AArch64SVEPCS;
24181ad6265SDimitry Andric
24281ad6265SDimitry Andric if (D->hasAttr<AMDGPUKernelCallAttr>())
24381ad6265SDimitry Andric return CC_AMDGPUKernelCall;
24481ad6265SDimitry Andric
2450b57cec5SDimitry Andric if (D->hasAttr<IntelOclBiccAttr>())
2460b57cec5SDimitry Andric return CC_IntelOclBicc;
2470b57cec5SDimitry Andric
2480b57cec5SDimitry Andric if (D->hasAttr<MSABIAttr>())
2490b57cec5SDimitry Andric return IsWindows ? CC_C : CC_Win64;
2500b57cec5SDimitry Andric
2510b57cec5SDimitry Andric if (D->hasAttr<SysVABIAttr>())
2520b57cec5SDimitry Andric return IsWindows ? CC_X86_64SysV : CC_C;
2530b57cec5SDimitry Andric
2540b57cec5SDimitry Andric if (D->hasAttr<PreserveMostAttr>())
2550b57cec5SDimitry Andric return CC_PreserveMost;
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric if (D->hasAttr<PreserveAllAttr>())
2580b57cec5SDimitry Andric return CC_PreserveAll;
2590b57cec5SDimitry Andric
2605f757f3fSDimitry Andric if (D->hasAttr<M68kRTDAttr>())
2615f757f3fSDimitry Andric return CC_M68kRTD;
2625f757f3fSDimitry Andric
2630fca6ea1SDimitry Andric if (D->hasAttr<PreserveNoneAttr>())
2640fca6ea1SDimitry Andric return CC_PreserveNone;
2650fca6ea1SDimitry Andric
2660fca6ea1SDimitry Andric if (D->hasAttr<RISCVVectorCCAttr>())
2670fca6ea1SDimitry Andric return CC_RISCVVectorCall;
2680fca6ea1SDimitry Andric
2690b57cec5SDimitry Andric return CC_C;
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric /// Arrange the argument and result information for a call to an
2730b57cec5SDimitry Andric /// unknown C++ non-static member function of the given abstract type.
2740b57cec5SDimitry Andric /// (A null RD means we don't have any meaningful "this" argument type,
2750b57cec5SDimitry Andric /// so fall back to a generic pointer type).
2760b57cec5SDimitry Andric /// The member function must be an ordinary function, i.e. not a
2770b57cec5SDimitry Andric /// constructor or destructor.
2780b57cec5SDimitry Andric const CGFunctionInfo &
arrangeCXXMethodType(const CXXRecordDecl * RD,const FunctionProtoType * FTP,const CXXMethodDecl * MD)2790b57cec5SDimitry Andric CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD,
2800b57cec5SDimitry Andric const FunctionProtoType *FTP,
2810b57cec5SDimitry Andric const CXXMethodDecl *MD) {
2820b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andric // Add the 'this' pointer.
2850b57cec5SDimitry Andric argTypes.push_back(DeriveThisType(RD, MD));
2860b57cec5SDimitry Andric
2870b57cec5SDimitry Andric return ::arrangeLLVMFunctionInfo(
2888a4dda33SDimitry Andric *this, /*instanceMethod=*/true, argTypes,
2890b57cec5SDimitry Andric FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>());
2900b57cec5SDimitry Andric }
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andric /// Set calling convention for CUDA/HIP kernel.
setCUDAKernelCallingConvention(CanQualType & FTy,CodeGenModule & CGM,const FunctionDecl * FD)2930b57cec5SDimitry Andric static void setCUDAKernelCallingConvention(CanQualType &FTy, CodeGenModule &CGM,
2940b57cec5SDimitry Andric const FunctionDecl *FD) {
2950b57cec5SDimitry Andric if (FD->hasAttr<CUDAGlobalAttr>()) {
2960b57cec5SDimitry Andric const FunctionType *FT = FTy->getAs<FunctionType>();
2970b57cec5SDimitry Andric CGM.getTargetCodeGenInfo().setCUDAKernelCallingConvention(FT);
2980b57cec5SDimitry Andric FTy = FT->getCanonicalTypeUnqualified();
2990b57cec5SDimitry Andric }
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric
3020b57cec5SDimitry Andric /// Arrange the argument and result information for a declaration or
3030b57cec5SDimitry Andric /// definition of the given C++ non-static member function. The
3040b57cec5SDimitry Andric /// member function must be an ordinary function, i.e. not a
3050b57cec5SDimitry Andric /// constructor or destructor.
3060b57cec5SDimitry Andric const CGFunctionInfo &
arrangeCXXMethodDeclaration(const CXXMethodDecl * MD)3070b57cec5SDimitry Andric CodeGenTypes::arrangeCXXMethodDeclaration(const CXXMethodDecl *MD) {
3080b57cec5SDimitry Andric assert(!isa<CXXConstructorDecl>(MD) && "wrong method for constructors!");
3090b57cec5SDimitry Andric assert(!isa<CXXDestructorDecl>(MD) && "wrong method for destructors!");
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric CanQualType FT = GetFormalType(MD).getAs<Type>();
3120b57cec5SDimitry Andric setCUDAKernelCallingConvention(FT, CGM, MD);
3130b57cec5SDimitry Andric auto prototype = FT.getAs<FunctionProtoType>();
3140b57cec5SDimitry Andric
3155f757f3fSDimitry Andric if (MD->isImplicitObjectMemberFunction()) {
3160b57cec5SDimitry Andric // The abstract case is perfectly fine.
317*5deeebd8SDimitry Andric const CXXRecordDecl *ThisType =
318*5deeebd8SDimitry Andric getCXXABI().getThisArgumentTypeForMethod(MD);
3190b57cec5SDimitry Andric return arrangeCXXMethodType(ThisType, prototype.getTypePtr(), MD);
3200b57cec5SDimitry Andric }
3210b57cec5SDimitry Andric
3220b57cec5SDimitry Andric return arrangeFreeFunctionType(prototype);
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric
inheritingCtorHasParams(const InheritedConstructor & Inherited,CXXCtorType Type)3250b57cec5SDimitry Andric bool CodeGenTypes::inheritingCtorHasParams(
3260b57cec5SDimitry Andric const InheritedConstructor &Inherited, CXXCtorType Type) {
3270b57cec5SDimitry Andric // Parameters are unnecessary if we're constructing a base class subobject
3280b57cec5SDimitry Andric // and the inherited constructor lives in a virtual base.
3290b57cec5SDimitry Andric return Type == Ctor_Complete ||
3300b57cec5SDimitry Andric !Inherited.getShadowDecl()->constructsVirtualBase() ||
3310b57cec5SDimitry Andric !Target.getCXXABI().hasConstructorVariants();
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric const CGFunctionInfo &
arrangeCXXStructorDeclaration(GlobalDecl GD)3350b57cec5SDimitry Andric CodeGenTypes::arrangeCXXStructorDeclaration(GlobalDecl GD) {
3360b57cec5SDimitry Andric auto *MD = cast<CXXMethodDecl>(GD.getDecl());
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
3390b57cec5SDimitry Andric SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
3401ac55f4cSDimitry Andric
341*5deeebd8SDimitry Andric const CXXRecordDecl *ThisType = getCXXABI().getThisArgumentTypeForMethod(GD);
3421ac55f4cSDimitry Andric argTypes.push_back(DeriveThisType(ThisType, MD));
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andric bool PassParams = true;
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
3470b57cec5SDimitry Andric // A base class inheriting constructor doesn't get forwarded arguments
3480b57cec5SDimitry Andric // needed to construct a virtual base (or base class thereof).
3490b57cec5SDimitry Andric if (auto Inherited = CD->getInheritedConstructor())
3500b57cec5SDimitry Andric PassParams = inheritingCtorHasParams(Inherited, GD.getCtorType());
3510b57cec5SDimitry Andric }
3520b57cec5SDimitry Andric
3530b57cec5SDimitry Andric CanQual<FunctionProtoType> FTP = GetFormalType(MD);
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric // Add the formal parameters.
3560b57cec5SDimitry Andric if (PassParams)
3570b57cec5SDimitry Andric appendParameterTypes(*this, argTypes, paramInfos, FTP);
3580b57cec5SDimitry Andric
3595ffd83dbSDimitry Andric CGCXXABI::AddedStructorArgCounts AddedArgs =
360*5deeebd8SDimitry Andric getCXXABI().buildStructorSignature(GD, argTypes);
3610b57cec5SDimitry Andric if (!paramInfos.empty()) {
3620b57cec5SDimitry Andric // Note: prefix implies after the first param.
3630b57cec5SDimitry Andric if (AddedArgs.Prefix)
3640b57cec5SDimitry Andric paramInfos.insert(paramInfos.begin() + 1, AddedArgs.Prefix,
3650b57cec5SDimitry Andric FunctionProtoType::ExtParameterInfo{});
3660b57cec5SDimitry Andric if (AddedArgs.Suffix)
3670b57cec5SDimitry Andric paramInfos.append(AddedArgs.Suffix,
3680b57cec5SDimitry Andric FunctionProtoType::ExtParameterInfo{});
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric
3710b57cec5SDimitry Andric RequiredArgs required =
3720b57cec5SDimitry Andric (PassParams && MD->isVariadic() ? RequiredArgs(argTypes.size())
3730b57cec5SDimitry Andric : RequiredArgs::All);
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andric FunctionType::ExtInfo extInfo = FTP->getExtInfo();
376*5deeebd8SDimitry Andric CanQualType resultType = getCXXABI().HasThisReturn(GD) ? argTypes.front()
377*5deeebd8SDimitry Andric : getCXXABI().hasMostDerivedReturn(GD)
3780b57cec5SDimitry Andric ? CGM.getContext().VoidPtrTy
3790b57cec5SDimitry Andric : Context.VoidTy;
3808a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::IsInstanceMethod,
3818a4dda33SDimitry Andric argTypes, extInfo, paramInfos, required);
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric
3840b57cec5SDimitry Andric static SmallVector<CanQualType, 16>
getArgTypesForCall(ASTContext & ctx,const CallArgList & args)3850b57cec5SDimitry Andric getArgTypesForCall(ASTContext &ctx, const CallArgList &args) {
3860b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
3870b57cec5SDimitry Andric for (auto &arg : args)
3880b57cec5SDimitry Andric argTypes.push_back(ctx.getCanonicalParamType(arg.Ty));
3890b57cec5SDimitry Andric return argTypes;
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric static SmallVector<CanQualType, 16>
getArgTypesForDeclaration(ASTContext & ctx,const FunctionArgList & args)3930b57cec5SDimitry Andric getArgTypesForDeclaration(ASTContext &ctx, const FunctionArgList &args) {
3940b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
3950b57cec5SDimitry Andric for (auto &arg : args)
3960b57cec5SDimitry Andric argTypes.push_back(ctx.getCanonicalParamType(arg->getType()));
3970b57cec5SDimitry Andric return argTypes;
3980b57cec5SDimitry Andric }
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric static llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16>
getExtParameterInfosForCall(const FunctionProtoType * proto,unsigned prefixArgs,unsigned totalArgs)4010b57cec5SDimitry Andric getExtParameterInfosForCall(const FunctionProtoType *proto,
4020b57cec5SDimitry Andric unsigned prefixArgs, unsigned totalArgs) {
4030b57cec5SDimitry Andric llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> result;
4040b57cec5SDimitry Andric if (proto->hasExtParameterInfos()) {
4050b57cec5SDimitry Andric addExtParameterInfosForCall(result, proto, prefixArgs, totalArgs);
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric return result;
4080b57cec5SDimitry Andric }
4090b57cec5SDimitry Andric
4100b57cec5SDimitry Andric /// Arrange a call to a C++ method, passing the given arguments.
4110b57cec5SDimitry Andric ///
4120b57cec5SDimitry Andric /// ExtraPrefixArgs is the number of ABI-specific args passed after the `this`
4130b57cec5SDimitry Andric /// parameter.
4140b57cec5SDimitry Andric /// ExtraSuffixArgs is the number of ABI-specific args passed at the end of
4150b57cec5SDimitry Andric /// args.
4160b57cec5SDimitry Andric /// PassProtoArgs indicates whether `args` has args for the parameters in the
4170b57cec5SDimitry Andric /// given CXXConstructorDecl.
4180b57cec5SDimitry Andric const CGFunctionInfo &
arrangeCXXConstructorCall(const CallArgList & args,const CXXConstructorDecl * D,CXXCtorType CtorKind,unsigned ExtraPrefixArgs,unsigned ExtraSuffixArgs,bool PassProtoArgs)4190b57cec5SDimitry Andric CodeGenTypes::arrangeCXXConstructorCall(const CallArgList &args,
4200b57cec5SDimitry Andric const CXXConstructorDecl *D,
4210b57cec5SDimitry Andric CXXCtorType CtorKind,
4220b57cec5SDimitry Andric unsigned ExtraPrefixArgs,
4230b57cec5SDimitry Andric unsigned ExtraSuffixArgs,
4240b57cec5SDimitry Andric bool PassProtoArgs) {
4250b57cec5SDimitry Andric // FIXME: Kill copy.
4260b57cec5SDimitry Andric SmallVector<CanQualType, 16> ArgTypes;
4270b57cec5SDimitry Andric for (const auto &Arg : args)
4280b57cec5SDimitry Andric ArgTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
4290b57cec5SDimitry Andric
4300b57cec5SDimitry Andric // +1 for implicit this, which should always be args[0].
4310b57cec5SDimitry Andric unsigned TotalPrefixArgs = 1 + ExtraPrefixArgs;
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric CanQual<FunctionProtoType> FPT = GetFormalType(D);
4340b57cec5SDimitry Andric RequiredArgs Required = PassProtoArgs
4350b57cec5SDimitry Andric ? RequiredArgs::forPrototypePlus(
4360b57cec5SDimitry Andric FPT, TotalPrefixArgs + ExtraSuffixArgs)
4370b57cec5SDimitry Andric : RequiredArgs::All;
4380b57cec5SDimitry Andric
4390b57cec5SDimitry Andric GlobalDecl GD(D, CtorKind);
440*5deeebd8SDimitry Andric CanQualType ResultType = getCXXABI().HasThisReturn(GD) ? ArgTypes.front()
441*5deeebd8SDimitry Andric : getCXXABI().hasMostDerivedReturn(GD)
4420b57cec5SDimitry Andric ? CGM.getContext().VoidPtrTy
4430b57cec5SDimitry Andric : Context.VoidTy;
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric FunctionType::ExtInfo Info = FPT->getExtInfo();
4460b57cec5SDimitry Andric llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> ParamInfos;
4470b57cec5SDimitry Andric // If the prototype args are elided, we should only have ABI-specific args,
4480b57cec5SDimitry Andric // which never have param info.
4490b57cec5SDimitry Andric if (PassProtoArgs && FPT->hasExtParameterInfos()) {
4500b57cec5SDimitry Andric // ABI-specific suffix arguments are treated the same as variadic arguments.
4510b57cec5SDimitry Andric addExtParameterInfosForCall(ParamInfos, FPT.getTypePtr(), TotalPrefixArgs,
4520b57cec5SDimitry Andric ArgTypes.size());
4530b57cec5SDimitry Andric }
4548a4dda33SDimitry Andric
4558a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(ResultType, FnInfoOpts::IsInstanceMethod,
4568a4dda33SDimitry Andric ArgTypes, Info, ParamInfos, Required);
4570b57cec5SDimitry Andric }
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andric /// Arrange the argument and result information for the declaration or
4600b57cec5SDimitry Andric /// definition of the given function.
4610b57cec5SDimitry Andric const CGFunctionInfo &
arrangeFunctionDeclaration(const FunctionDecl * FD)4620b57cec5SDimitry Andric CodeGenTypes::arrangeFunctionDeclaration(const FunctionDecl *FD) {
4630b57cec5SDimitry Andric if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
4645f757f3fSDimitry Andric if (MD->isImplicitObjectMemberFunction())
4650b57cec5SDimitry Andric return arrangeCXXMethodDeclaration(MD);
4660b57cec5SDimitry Andric
4670b57cec5SDimitry Andric CanQualType FTy = FD->getType()->getCanonicalTypeUnqualified();
4680b57cec5SDimitry Andric
4690b57cec5SDimitry Andric assert(isa<FunctionType>(FTy));
4700b57cec5SDimitry Andric setCUDAKernelCallingConvention(FTy, CGM, FD);
4710b57cec5SDimitry Andric
4720b57cec5SDimitry Andric // When declaring a function without a prototype, always use a
4730b57cec5SDimitry Andric // non-variadic type.
4740b57cec5SDimitry Andric if (CanQual<FunctionNoProtoType> noProto = FTy.getAs<FunctionNoProtoType>()) {
4758a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(noProto->getReturnType(), FnInfoOpts::None,
4768a4dda33SDimitry Andric std::nullopt, noProto->getExtInfo(), {},
477bdd1243dSDimitry Andric RequiredArgs::All);
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andric return arrangeFreeFunctionType(FTy.castAs<FunctionProtoType>());
4810b57cec5SDimitry Andric }
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andric /// Arrange the argument and result information for the declaration or
4840b57cec5SDimitry Andric /// definition of an Objective-C method.
4850b57cec5SDimitry Andric const CGFunctionInfo &
arrangeObjCMethodDeclaration(const ObjCMethodDecl * MD)4860b57cec5SDimitry Andric CodeGenTypes::arrangeObjCMethodDeclaration(const ObjCMethodDecl *MD) {
4870b57cec5SDimitry Andric // It happens that this is the same as a call with no optional
4880b57cec5SDimitry Andric // arguments, except also using the formal 'self' type.
4890b57cec5SDimitry Andric return arrangeObjCMessageSendSignature(MD, MD->getSelfDecl()->getType());
4900b57cec5SDimitry Andric }
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andric /// Arrange the argument and result information for the function type
4930b57cec5SDimitry Andric /// through which to perform a send to the given Objective-C method,
4940b57cec5SDimitry Andric /// using the given receiver type. The receiver type is not always
4950b57cec5SDimitry Andric /// the 'self' type of the method or even an Objective-C pointer type.
4960b57cec5SDimitry Andric /// This is *not* the right method for actually performing such a
4970b57cec5SDimitry Andric /// message send, due to the possibility of optional arguments.
4980b57cec5SDimitry Andric const CGFunctionInfo &
arrangeObjCMessageSendSignature(const ObjCMethodDecl * MD,QualType receiverType)4990b57cec5SDimitry Andric CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD,
5000b57cec5SDimitry Andric QualType receiverType) {
5010b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTys;
502bdd1243dSDimitry Andric SmallVector<FunctionProtoType::ExtParameterInfo, 4> extParamInfos(
503bdd1243dSDimitry Andric MD->isDirectMethod() ? 1 : 2);
5040b57cec5SDimitry Andric argTys.push_back(Context.getCanonicalParamType(receiverType));
505bdd1243dSDimitry Andric if (!MD->isDirectMethod())
5060b57cec5SDimitry Andric argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType()));
5070b57cec5SDimitry Andric // FIXME: Kill copy?
5080b57cec5SDimitry Andric for (const auto *I : MD->parameters()) {
5090b57cec5SDimitry Andric argTys.push_back(Context.getCanonicalParamType(I->getType()));
5100b57cec5SDimitry Andric auto extParamInfo = FunctionProtoType::ExtParameterInfo().withIsNoEscape(
5110b57cec5SDimitry Andric I->hasAttr<NoEscapeAttr>());
5120b57cec5SDimitry Andric extParamInfos.push_back(extParamInfo);
5130b57cec5SDimitry Andric }
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andric FunctionType::ExtInfo einfo;
5160b57cec5SDimitry Andric bool IsWindows = getContext().getTargetInfo().getTriple().isOSWindows();
5170b57cec5SDimitry Andric einfo = einfo.withCallingConv(getCallingConventionForDecl(MD, IsWindows));
5180b57cec5SDimitry Andric
5190b57cec5SDimitry Andric if (getContext().getLangOpts().ObjCAutoRefCount &&
5200b57cec5SDimitry Andric MD->hasAttr<NSReturnsRetainedAttr>())
5210b57cec5SDimitry Andric einfo = einfo.withProducesResult(true);
5220b57cec5SDimitry Andric
5230b57cec5SDimitry Andric RequiredArgs required =
5240b57cec5SDimitry Andric (MD->isVariadic() ? RequiredArgs(argTys.size()) : RequiredArgs::All);
5250b57cec5SDimitry Andric
5268a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(GetReturnType(MD->getReturnType()),
5278a4dda33SDimitry Andric FnInfoOpts::None, argTys, einfo, extParamInfos,
5288a4dda33SDimitry Andric required);
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric const CGFunctionInfo &
arrangeUnprototypedObjCMessageSend(QualType returnType,const CallArgList & args)5320b57cec5SDimitry Andric CodeGenTypes::arrangeUnprototypedObjCMessageSend(QualType returnType,
5330b57cec5SDimitry Andric const CallArgList &args) {
5340b57cec5SDimitry Andric auto argTypes = getArgTypesForCall(Context, args);
5350b57cec5SDimitry Andric FunctionType::ExtInfo einfo;
5360b57cec5SDimitry Andric
5378a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(GetReturnType(returnType), FnInfoOpts::None,
5388a4dda33SDimitry Andric argTypes, einfo, {}, RequiredArgs::All);
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric const CGFunctionInfo &
arrangeGlobalDeclaration(GlobalDecl GD)5420b57cec5SDimitry Andric CodeGenTypes::arrangeGlobalDeclaration(GlobalDecl GD) {
5430b57cec5SDimitry Andric // FIXME: Do we need to handle ObjCMethodDecl?
5440b57cec5SDimitry Andric const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
5450b57cec5SDimitry Andric
5460b57cec5SDimitry Andric if (isa<CXXConstructorDecl>(GD.getDecl()) ||
5470b57cec5SDimitry Andric isa<CXXDestructorDecl>(GD.getDecl()))
5480b57cec5SDimitry Andric return arrangeCXXStructorDeclaration(GD);
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric return arrangeFunctionDeclaration(FD);
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric
5530b57cec5SDimitry Andric /// Arrange a thunk that takes 'this' as the first parameter followed by
5540b57cec5SDimitry Andric /// varargs. Return a void pointer, regardless of the actual return type.
5550b57cec5SDimitry Andric /// The body of the thunk will end in a musttail call to a function of the
5560b57cec5SDimitry Andric /// correct type, and the caller will bitcast the function to the correct
5570b57cec5SDimitry Andric /// prototype.
5580b57cec5SDimitry Andric const CGFunctionInfo &
arrangeUnprototypedMustTailThunk(const CXXMethodDecl * MD)5590b57cec5SDimitry Andric CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) {
5600b57cec5SDimitry Andric assert(MD->isVirtual() && "only methods have thunks");
5610b57cec5SDimitry Andric CanQual<FunctionProtoType> FTP = GetFormalType(MD);
5620b57cec5SDimitry Andric CanQualType ArgTys[] = {DeriveThisType(MD->getParent(), MD)};
5638a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::None, ArgTys,
5640b57cec5SDimitry Andric FTP->getExtInfo(), {}, RequiredArgs(1));
5650b57cec5SDimitry Andric }
5660b57cec5SDimitry Andric
5670b57cec5SDimitry Andric const CGFunctionInfo &
arrangeMSCtorClosure(const CXXConstructorDecl * CD,CXXCtorType CT)5680b57cec5SDimitry Andric CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD,
5690b57cec5SDimitry Andric CXXCtorType CT) {
5700b57cec5SDimitry Andric assert(CT == Ctor_CopyingClosure || CT == Ctor_DefaultClosure);
5710b57cec5SDimitry Andric
5720b57cec5SDimitry Andric CanQual<FunctionProtoType> FTP = GetFormalType(CD);
5730b57cec5SDimitry Andric SmallVector<CanQualType, 2> ArgTys;
5740b57cec5SDimitry Andric const CXXRecordDecl *RD = CD->getParent();
5750b57cec5SDimitry Andric ArgTys.push_back(DeriveThisType(RD, CD));
5760b57cec5SDimitry Andric if (CT == Ctor_CopyingClosure)
5770b57cec5SDimitry Andric ArgTys.push_back(*FTP->param_type_begin());
5780b57cec5SDimitry Andric if (RD->getNumVBases() > 0)
5790b57cec5SDimitry Andric ArgTys.push_back(Context.IntTy);
5800b57cec5SDimitry Andric CallingConv CC = Context.getDefaultCallingConvention(
5810b57cec5SDimitry Andric /*IsVariadic=*/false, /*IsCXXMethod=*/true);
5828a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(Context.VoidTy, FnInfoOpts::IsInstanceMethod,
5838a4dda33SDimitry Andric ArgTys, FunctionType::ExtInfo(CC), {},
5840b57cec5SDimitry Andric RequiredArgs::All);
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric /// Arrange a call as unto a free function, except possibly with an
5880b57cec5SDimitry Andric /// additional number of formal parameters considered required.
5890b57cec5SDimitry Andric static const CGFunctionInfo &
arrangeFreeFunctionLikeCall(CodeGenTypes & CGT,CodeGenModule & CGM,const CallArgList & args,const FunctionType * fnType,unsigned numExtraRequiredArgs,bool chainCall)5900b57cec5SDimitry Andric arrangeFreeFunctionLikeCall(CodeGenTypes &CGT,
5910b57cec5SDimitry Andric CodeGenModule &CGM,
5920b57cec5SDimitry Andric const CallArgList &args,
5930b57cec5SDimitry Andric const FunctionType *fnType,
5940b57cec5SDimitry Andric unsigned numExtraRequiredArgs,
5950b57cec5SDimitry Andric bool chainCall) {
5960b57cec5SDimitry Andric assert(args.size() >= numExtraRequiredArgs);
5970b57cec5SDimitry Andric
5980b57cec5SDimitry Andric llvm::SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
5990b57cec5SDimitry Andric
6000b57cec5SDimitry Andric // In most cases, there are no optional arguments.
6010b57cec5SDimitry Andric RequiredArgs required = RequiredArgs::All;
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andric // If we have a variadic prototype, the required arguments are the
6040b57cec5SDimitry Andric // extra prefix plus the arguments in the prototype.
6050b57cec5SDimitry Andric if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
6060b57cec5SDimitry Andric if (proto->isVariadic())
6070b57cec5SDimitry Andric required = RequiredArgs::forPrototypePlus(proto, numExtraRequiredArgs);
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andric if (proto->hasExtParameterInfos())
6100b57cec5SDimitry Andric addExtParameterInfosForCall(paramInfos, proto, numExtraRequiredArgs,
6110b57cec5SDimitry Andric args.size());
6120b57cec5SDimitry Andric
6130b57cec5SDimitry Andric // If we don't have a prototype at all, but we're supposed to
6140b57cec5SDimitry Andric // explicitly use the variadic convention for unprototyped calls,
6150b57cec5SDimitry Andric // treat all of the arguments as required but preserve the nominal
6160b57cec5SDimitry Andric // possibility of variadics.
6170b57cec5SDimitry Andric } else if (CGM.getTargetCodeGenInfo()
6180b57cec5SDimitry Andric .isNoProtoCallVariadic(args,
6190b57cec5SDimitry Andric cast<FunctionNoProtoType>(fnType))) {
6200b57cec5SDimitry Andric required = RequiredArgs(args.size());
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric
6230b57cec5SDimitry Andric // FIXME: Kill copy.
6240b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
6250b57cec5SDimitry Andric for (const auto &arg : args)
6260b57cec5SDimitry Andric argTypes.push_back(CGT.getContext().getCanonicalParamType(arg.Ty));
6278a4dda33SDimitry Andric FnInfoOpts opts = chainCall ? FnInfoOpts::IsChainCall : FnInfoOpts::None;
6280b57cec5SDimitry Andric return CGT.arrangeLLVMFunctionInfo(GetReturnType(fnType->getReturnType()),
6298a4dda33SDimitry Andric opts, argTypes, fnType->getExtInfo(),
6308a4dda33SDimitry Andric paramInfos, required);
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andric /// Figure out the rules for calling a function with the given formal
6340b57cec5SDimitry Andric /// type using the given arguments. The arguments are necessary
6350b57cec5SDimitry Andric /// because the function might be unprototyped, in which case it's
6360b57cec5SDimitry Andric /// target-dependent in crazy ways.
6370b57cec5SDimitry Andric const CGFunctionInfo &
arrangeFreeFunctionCall(const CallArgList & args,const FunctionType * fnType,bool chainCall)6380b57cec5SDimitry Andric CodeGenTypes::arrangeFreeFunctionCall(const CallArgList &args,
6390b57cec5SDimitry Andric const FunctionType *fnType,
6400b57cec5SDimitry Andric bool chainCall) {
6410b57cec5SDimitry Andric return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType,
6420b57cec5SDimitry Andric chainCall ? 1 : 0, chainCall);
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andric /// A block function is essentially a free function with an
6460b57cec5SDimitry Andric /// extra implicit argument.
6470b57cec5SDimitry Andric const CGFunctionInfo &
arrangeBlockFunctionCall(const CallArgList & args,const FunctionType * fnType)6480b57cec5SDimitry Andric CodeGenTypes::arrangeBlockFunctionCall(const CallArgList &args,
6490b57cec5SDimitry Andric const FunctionType *fnType) {
6500b57cec5SDimitry Andric return arrangeFreeFunctionLikeCall(*this, CGM, args, fnType, 1,
6510b57cec5SDimitry Andric /*chainCall=*/false);
6520b57cec5SDimitry Andric }
6530b57cec5SDimitry Andric
6540b57cec5SDimitry Andric const CGFunctionInfo &
arrangeBlockFunctionDeclaration(const FunctionProtoType * proto,const FunctionArgList & params)6550b57cec5SDimitry Andric CodeGenTypes::arrangeBlockFunctionDeclaration(const FunctionProtoType *proto,
6560b57cec5SDimitry Andric const FunctionArgList ¶ms) {
6570b57cec5SDimitry Andric auto paramInfos = getExtParameterInfosForCall(proto, 1, params.size());
6580b57cec5SDimitry Andric auto argTypes = getArgTypesForDeclaration(Context, params);
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andric return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
6618a4dda33SDimitry Andric FnInfoOpts::None, argTypes,
6628a4dda33SDimitry Andric proto->getExtInfo(), paramInfos,
6630b57cec5SDimitry Andric RequiredArgs::forPrototypePlus(proto, 1));
6640b57cec5SDimitry Andric }
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andric const CGFunctionInfo &
arrangeBuiltinFunctionCall(QualType resultType,const CallArgList & args)6670b57cec5SDimitry Andric CodeGenTypes::arrangeBuiltinFunctionCall(QualType resultType,
6680b57cec5SDimitry Andric const CallArgList &args) {
6690b57cec5SDimitry Andric // FIXME: Kill copy.
6700b57cec5SDimitry Andric SmallVector<CanQualType, 16> argTypes;
6710b57cec5SDimitry Andric for (const auto &Arg : args)
6720b57cec5SDimitry Andric argTypes.push_back(Context.getCanonicalParamType(Arg.Ty));
6738a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
6748a4dda33SDimitry Andric argTypes, FunctionType::ExtInfo(),
6750b57cec5SDimitry Andric /*paramInfos=*/{}, RequiredArgs::All);
6760b57cec5SDimitry Andric }
6770b57cec5SDimitry Andric
6780b57cec5SDimitry Andric const CGFunctionInfo &
arrangeBuiltinFunctionDeclaration(QualType resultType,const FunctionArgList & args)6790b57cec5SDimitry Andric CodeGenTypes::arrangeBuiltinFunctionDeclaration(QualType resultType,
6800b57cec5SDimitry Andric const FunctionArgList &args) {
6810b57cec5SDimitry Andric auto argTypes = getArgTypesForDeclaration(Context, args);
6820b57cec5SDimitry Andric
6838a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(GetReturnType(resultType), FnInfoOpts::None,
6848a4dda33SDimitry Andric argTypes, FunctionType::ExtInfo(), {},
6858a4dda33SDimitry Andric RequiredArgs::All);
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric
6880b57cec5SDimitry Andric const CGFunctionInfo &
arrangeBuiltinFunctionDeclaration(CanQualType resultType,ArrayRef<CanQualType> argTypes)6890b57cec5SDimitry Andric CodeGenTypes::arrangeBuiltinFunctionDeclaration(CanQualType resultType,
6900b57cec5SDimitry Andric ArrayRef<CanQualType> argTypes) {
6918a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(resultType, FnInfoOpts::None, argTypes,
6928a4dda33SDimitry Andric FunctionType::ExtInfo(), {},
6938a4dda33SDimitry Andric RequiredArgs::All);
6940b57cec5SDimitry Andric }
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric /// Arrange a call to a C++ method, passing the given arguments.
6970b57cec5SDimitry Andric ///
6980b57cec5SDimitry Andric /// numPrefixArgs is the number of ABI-specific prefix arguments we have. It
6990b57cec5SDimitry Andric /// does not count `this`.
7000b57cec5SDimitry Andric const CGFunctionInfo &
arrangeCXXMethodCall(const CallArgList & args,const FunctionProtoType * proto,RequiredArgs required,unsigned numPrefixArgs)7010b57cec5SDimitry Andric CodeGenTypes::arrangeCXXMethodCall(const CallArgList &args,
7020b57cec5SDimitry Andric const FunctionProtoType *proto,
7030b57cec5SDimitry Andric RequiredArgs required,
7040b57cec5SDimitry Andric unsigned numPrefixArgs) {
7050b57cec5SDimitry Andric assert(numPrefixArgs + 1 <= args.size() &&
7060b57cec5SDimitry Andric "Emitting a call with less args than the required prefix?");
7070b57cec5SDimitry Andric // Add one to account for `this`. It's a bit awkward here, but we don't count
7080b57cec5SDimitry Andric // `this` in similar places elsewhere.
7090b57cec5SDimitry Andric auto paramInfos =
7100b57cec5SDimitry Andric getExtParameterInfosForCall(proto, numPrefixArgs + 1, args.size());
7110b57cec5SDimitry Andric
7120b57cec5SDimitry Andric // FIXME: Kill copy.
7130b57cec5SDimitry Andric auto argTypes = getArgTypesForCall(Context, args);
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andric FunctionType::ExtInfo info = proto->getExtInfo();
7168a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(GetReturnType(proto->getReturnType()),
7178a4dda33SDimitry Andric FnInfoOpts::IsInstanceMethod, argTypes, info,
7188a4dda33SDimitry Andric paramInfos, required);
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric
arrangeNullaryFunction()7210b57cec5SDimitry Andric const CGFunctionInfo &CodeGenTypes::arrangeNullaryFunction() {
7228a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(getContext().VoidTy, FnInfoOpts::None,
7238a4dda33SDimitry Andric std::nullopt, FunctionType::ExtInfo(), {},
7248a4dda33SDimitry Andric RequiredArgs::All);
7250b57cec5SDimitry Andric }
7260b57cec5SDimitry Andric
7270b57cec5SDimitry Andric const CGFunctionInfo &
arrangeCall(const CGFunctionInfo & signature,const CallArgList & args)7280b57cec5SDimitry Andric CodeGenTypes::arrangeCall(const CGFunctionInfo &signature,
7290b57cec5SDimitry Andric const CallArgList &args) {
7300b57cec5SDimitry Andric assert(signature.arg_size() <= args.size());
7310b57cec5SDimitry Andric if (signature.arg_size() == args.size())
7320b57cec5SDimitry Andric return signature;
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andric SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos;
7350b57cec5SDimitry Andric auto sigParamInfos = signature.getExtParameterInfos();
7360b57cec5SDimitry Andric if (!sigParamInfos.empty()) {
7370b57cec5SDimitry Andric paramInfos.append(sigParamInfos.begin(), sigParamInfos.end());
7380b57cec5SDimitry Andric paramInfos.resize(args.size());
7390b57cec5SDimitry Andric }
7400b57cec5SDimitry Andric
7410b57cec5SDimitry Andric auto argTypes = getArgTypesForCall(Context, args);
7420b57cec5SDimitry Andric
7430b57cec5SDimitry Andric assert(signature.getRequiredArgs().allowsOptionalArgs());
7448a4dda33SDimitry Andric FnInfoOpts opts = FnInfoOpts::None;
7458a4dda33SDimitry Andric if (signature.isInstanceMethod())
7468a4dda33SDimitry Andric opts |= FnInfoOpts::IsInstanceMethod;
7478a4dda33SDimitry Andric if (signature.isChainCall())
7488a4dda33SDimitry Andric opts |= FnInfoOpts::IsChainCall;
7498a4dda33SDimitry Andric if (signature.isDelegateCall())
7508a4dda33SDimitry Andric opts |= FnInfoOpts::IsDelegateCall;
7518a4dda33SDimitry Andric return arrangeLLVMFunctionInfo(signature.getReturnType(), opts, argTypes,
7528a4dda33SDimitry Andric signature.getExtInfo(), paramInfos,
7530b57cec5SDimitry Andric signature.getRequiredArgs());
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andric namespace clang {
7570b57cec5SDimitry Andric namespace CodeGen {
7580b57cec5SDimitry Andric void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
7590b57cec5SDimitry Andric }
7600b57cec5SDimitry Andric }
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric /// Arrange the argument and result information for an abstract value
7630b57cec5SDimitry Andric /// of a given function type. This is the method which all of the
7640b57cec5SDimitry Andric /// above functions ultimately defer to.
arrangeLLVMFunctionInfo(CanQualType resultType,FnInfoOpts opts,ArrayRef<CanQualType> argTypes,FunctionType::ExtInfo info,ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,RequiredArgs required)7658a4dda33SDimitry Andric const CGFunctionInfo &CodeGenTypes::arrangeLLVMFunctionInfo(
7668a4dda33SDimitry Andric CanQualType resultType, FnInfoOpts opts, ArrayRef<CanQualType> argTypes,
7670b57cec5SDimitry Andric FunctionType::ExtInfo info,
7680b57cec5SDimitry Andric ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos,
7690b57cec5SDimitry Andric RequiredArgs required) {
7700b57cec5SDimitry Andric assert(llvm::all_of(argTypes,
7710b57cec5SDimitry Andric [](CanQualType T) { return T.isCanonicalAsParam(); }));
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andric // Lookup or create unique function info.
7740b57cec5SDimitry Andric llvm::FoldingSetNodeID ID;
7758a4dda33SDimitry Andric bool isInstanceMethod =
7768a4dda33SDimitry Andric (opts & FnInfoOpts::IsInstanceMethod) == FnInfoOpts::IsInstanceMethod;
7778a4dda33SDimitry Andric bool isChainCall =
7788a4dda33SDimitry Andric (opts & FnInfoOpts::IsChainCall) == FnInfoOpts::IsChainCall;
7798a4dda33SDimitry Andric bool isDelegateCall =
7808a4dda33SDimitry Andric (opts & FnInfoOpts::IsDelegateCall) == FnInfoOpts::IsDelegateCall;
7818a4dda33SDimitry Andric CGFunctionInfo::Profile(ID, isInstanceMethod, isChainCall, isDelegateCall,
7828a4dda33SDimitry Andric info, paramInfos, required, resultType, argTypes);
7830b57cec5SDimitry Andric
7840b57cec5SDimitry Andric void *insertPos = nullptr;
7850b57cec5SDimitry Andric CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, insertPos);
7860b57cec5SDimitry Andric if (FI)
7870b57cec5SDimitry Andric return *FI;
7880b57cec5SDimitry Andric
7890b57cec5SDimitry Andric unsigned CC = ClangCallConvToLLVMCallConv(info.getCC());
7900b57cec5SDimitry Andric
7910b57cec5SDimitry Andric // Construct the function info. We co-allocate the ArgInfos.
7928a4dda33SDimitry Andric FI = CGFunctionInfo::create(CC, isInstanceMethod, isChainCall, isDelegateCall,
7938a4dda33SDimitry Andric info, paramInfos, resultType, argTypes, required);
7940b57cec5SDimitry Andric FunctionInfos.InsertNode(FI, insertPos);
7950b57cec5SDimitry Andric
7960b57cec5SDimitry Andric bool inserted = FunctionsBeingProcessed.insert(FI).second;
7970b57cec5SDimitry Andric (void)inserted;
7980b57cec5SDimitry Andric assert(inserted && "Recursively being processed?");
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andric // Compute ABI information.
8010b57cec5SDimitry Andric if (CC == llvm::CallingConv::SPIR_KERNEL) {
8020b57cec5SDimitry Andric // Force target independent argument handling for the host visible
8030b57cec5SDimitry Andric // kernel functions.
8040b57cec5SDimitry Andric computeSPIRKernelABIInfo(CGM, *FI);
805fe6060f1SDimitry Andric } else if (info.getCC() == CC_Swift || info.getCC() == CC_SwiftAsync) {
8060b57cec5SDimitry Andric swiftcall::computeABIInfo(CGM, *FI);
8070b57cec5SDimitry Andric } else {
808*5deeebd8SDimitry Andric CGM.getABIInfo().computeInfo(*FI);
8090b57cec5SDimitry Andric }
8100b57cec5SDimitry Andric
8110b57cec5SDimitry Andric // Loop over all of the computed argument and return value info. If any of
8120b57cec5SDimitry Andric // them are direct or extend without a specified coerce type, specify the
8130b57cec5SDimitry Andric // default now.
8140b57cec5SDimitry Andric ABIArgInfo &retInfo = FI->getReturnInfo();
8150b57cec5SDimitry Andric if (retInfo.canHaveCoerceToType() && retInfo.getCoerceToType() == nullptr)
8160b57cec5SDimitry Andric retInfo.setCoerceToType(ConvertType(FI->getReturnType()));
8170b57cec5SDimitry Andric
8180b57cec5SDimitry Andric for (auto &I : FI->arguments())
8190b57cec5SDimitry Andric if (I.info.canHaveCoerceToType() && I.info.getCoerceToType() == nullptr)
8200b57cec5SDimitry Andric I.info.setCoerceToType(ConvertType(I.type));
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric bool erased = FunctionsBeingProcessed.erase(FI); (void)erased;
8230b57cec5SDimitry Andric assert(erased && "Not in set?");
8240b57cec5SDimitry Andric
8250b57cec5SDimitry Andric return *FI;
8260b57cec5SDimitry Andric }
8270b57cec5SDimitry Andric
create(unsigned llvmCC,bool instanceMethod,bool chainCall,bool delegateCall,const FunctionType::ExtInfo & info,ArrayRef<ExtParameterInfo> paramInfos,CanQualType resultType,ArrayRef<CanQualType> argTypes,RequiredArgs required)8288a4dda33SDimitry Andric CGFunctionInfo *CGFunctionInfo::create(unsigned llvmCC, bool instanceMethod,
8298a4dda33SDimitry Andric bool chainCall, bool delegateCall,
8300b57cec5SDimitry Andric const FunctionType::ExtInfo &info,
8310b57cec5SDimitry Andric ArrayRef<ExtParameterInfo> paramInfos,
8320b57cec5SDimitry Andric CanQualType resultType,
8330b57cec5SDimitry Andric ArrayRef<CanQualType> argTypes,
8340b57cec5SDimitry Andric RequiredArgs required) {
8350b57cec5SDimitry Andric assert(paramInfos.empty() || paramInfos.size() == argTypes.size());
8360b57cec5SDimitry Andric assert(!required.allowsOptionalArgs() ||
8370b57cec5SDimitry Andric required.getNumRequiredArgs() <= argTypes.size());
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric void *buffer =
8400b57cec5SDimitry Andric operator new(totalSizeToAlloc<ArgInfo, ExtParameterInfo>(
8410b57cec5SDimitry Andric argTypes.size() + 1, paramInfos.size()));
8420b57cec5SDimitry Andric
8430b57cec5SDimitry Andric CGFunctionInfo *FI = new(buffer) CGFunctionInfo();
8440b57cec5SDimitry Andric FI->CallingConvention = llvmCC;
8450b57cec5SDimitry Andric FI->EffectiveCallingConvention = llvmCC;
8460b57cec5SDimitry Andric FI->ASTCallingConvention = info.getCC();
8470b57cec5SDimitry Andric FI->InstanceMethod = instanceMethod;
8480b57cec5SDimitry Andric FI->ChainCall = chainCall;
8498a4dda33SDimitry Andric FI->DelegateCall = delegateCall;
8505ffd83dbSDimitry Andric FI->CmseNSCall = info.getCmseNSCall();
8510b57cec5SDimitry Andric FI->NoReturn = info.getNoReturn();
8520b57cec5SDimitry Andric FI->ReturnsRetained = info.getProducesResult();
8530b57cec5SDimitry Andric FI->NoCallerSavedRegs = info.getNoCallerSavedRegs();
8540b57cec5SDimitry Andric FI->NoCfCheck = info.getNoCfCheck();
8550b57cec5SDimitry Andric FI->Required = required;
8560b57cec5SDimitry Andric FI->HasRegParm = info.getHasRegParm();
8570b57cec5SDimitry Andric FI->RegParm = info.getRegParm();
8580b57cec5SDimitry Andric FI->ArgStruct = nullptr;
8590b57cec5SDimitry Andric FI->ArgStructAlign = 0;
8600b57cec5SDimitry Andric FI->NumArgs = argTypes.size();
8610b57cec5SDimitry Andric FI->HasExtParameterInfos = !paramInfos.empty();
8620b57cec5SDimitry Andric FI->getArgsBuffer()[0].type = resultType;
86381ad6265SDimitry Andric FI->MaxVectorWidth = 0;
8640b57cec5SDimitry Andric for (unsigned i = 0, e = argTypes.size(); i != e; ++i)
8650b57cec5SDimitry Andric FI->getArgsBuffer()[i + 1].type = argTypes[i];
8660b57cec5SDimitry Andric for (unsigned i = 0, e = paramInfos.size(); i != e; ++i)
8670b57cec5SDimitry Andric FI->getExtParameterInfosBuffer()[i] = paramInfos[i];
8680b57cec5SDimitry Andric return FI;
8690b57cec5SDimitry Andric }
8700b57cec5SDimitry Andric
8710b57cec5SDimitry Andric /***/
8720b57cec5SDimitry Andric
8730b57cec5SDimitry Andric namespace {
8740b57cec5SDimitry Andric // ABIArgInfo::Expand implementation.
8750b57cec5SDimitry Andric
8760b57cec5SDimitry Andric // Specifies the way QualType passed as ABIArgInfo::Expand is expanded.
8770b57cec5SDimitry Andric struct TypeExpansion {
8780b57cec5SDimitry Andric enum TypeExpansionKind {
8790b57cec5SDimitry Andric // Elements of constant arrays are expanded recursively.
8800b57cec5SDimitry Andric TEK_ConstantArray,
8810b57cec5SDimitry Andric // Record fields are expanded recursively (but if record is a union, only
8820b57cec5SDimitry Andric // the field with the largest size is expanded).
8830b57cec5SDimitry Andric TEK_Record,
8840b57cec5SDimitry Andric // For complex types, real and imaginary parts are expanded recursively.
8850b57cec5SDimitry Andric TEK_Complex,
8860b57cec5SDimitry Andric // All other types are not expandable.
8870b57cec5SDimitry Andric TEK_None
8880b57cec5SDimitry Andric };
8890b57cec5SDimitry Andric
8900b57cec5SDimitry Andric const TypeExpansionKind Kind;
8910b57cec5SDimitry Andric
TypeExpansion__anonf4c048640211::TypeExpansion8920b57cec5SDimitry Andric TypeExpansion(TypeExpansionKind K) : Kind(K) {}
~TypeExpansion__anonf4c048640211::TypeExpansion8930b57cec5SDimitry Andric virtual ~TypeExpansion() {}
8940b57cec5SDimitry Andric };
8950b57cec5SDimitry Andric
8960b57cec5SDimitry Andric struct ConstantArrayExpansion : TypeExpansion {
8970b57cec5SDimitry Andric QualType EltTy;
8980b57cec5SDimitry Andric uint64_t NumElts;
8990b57cec5SDimitry Andric
ConstantArrayExpansion__anonf4c048640211::ConstantArrayExpansion9000b57cec5SDimitry Andric ConstantArrayExpansion(QualType EltTy, uint64_t NumElts)
9010b57cec5SDimitry Andric : TypeExpansion(TEK_ConstantArray), EltTy(EltTy), NumElts(NumElts) {}
classof__anonf4c048640211::ConstantArrayExpansion9020b57cec5SDimitry Andric static bool classof(const TypeExpansion *TE) {
9030b57cec5SDimitry Andric return TE->Kind == TEK_ConstantArray;
9040b57cec5SDimitry Andric }
9050b57cec5SDimitry Andric };
9060b57cec5SDimitry Andric
9070b57cec5SDimitry Andric struct RecordExpansion : TypeExpansion {
9080b57cec5SDimitry Andric SmallVector<const CXXBaseSpecifier *, 1> Bases;
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andric SmallVector<const FieldDecl *, 1> Fields;
9110b57cec5SDimitry Andric
RecordExpansion__anonf4c048640211::RecordExpansion9120b57cec5SDimitry Andric RecordExpansion(SmallVector<const CXXBaseSpecifier *, 1> &&Bases,
9130b57cec5SDimitry Andric SmallVector<const FieldDecl *, 1> &&Fields)
9140b57cec5SDimitry Andric : TypeExpansion(TEK_Record), Bases(std::move(Bases)),
9150b57cec5SDimitry Andric Fields(std::move(Fields)) {}
classof__anonf4c048640211::RecordExpansion9160b57cec5SDimitry Andric static bool classof(const TypeExpansion *TE) {
9170b57cec5SDimitry Andric return TE->Kind == TEK_Record;
9180b57cec5SDimitry Andric }
9190b57cec5SDimitry Andric };
9200b57cec5SDimitry Andric
9210b57cec5SDimitry Andric struct ComplexExpansion : TypeExpansion {
9220b57cec5SDimitry Andric QualType EltTy;
9230b57cec5SDimitry Andric
ComplexExpansion__anonf4c048640211::ComplexExpansion9240b57cec5SDimitry Andric ComplexExpansion(QualType EltTy) : TypeExpansion(TEK_Complex), EltTy(EltTy) {}
classof__anonf4c048640211::ComplexExpansion9250b57cec5SDimitry Andric static bool classof(const TypeExpansion *TE) {
9260b57cec5SDimitry Andric return TE->Kind == TEK_Complex;
9270b57cec5SDimitry Andric }
9280b57cec5SDimitry Andric };
9290b57cec5SDimitry Andric
9300b57cec5SDimitry Andric struct NoExpansion : TypeExpansion {
NoExpansion__anonf4c048640211::NoExpansion9310b57cec5SDimitry Andric NoExpansion() : TypeExpansion(TEK_None) {}
classof__anonf4c048640211::NoExpansion9320b57cec5SDimitry Andric static bool classof(const TypeExpansion *TE) {
9330b57cec5SDimitry Andric return TE->Kind == TEK_None;
9340b57cec5SDimitry Andric }
9350b57cec5SDimitry Andric };
9360b57cec5SDimitry Andric } // namespace
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andric static std::unique_ptr<TypeExpansion>
getTypeExpansion(QualType Ty,const ASTContext & Context)9390b57cec5SDimitry Andric getTypeExpansion(QualType Ty, const ASTContext &Context) {
9400b57cec5SDimitry Andric if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
9410fca6ea1SDimitry Andric return std::make_unique<ConstantArrayExpansion>(AT->getElementType(),
9420fca6ea1SDimitry Andric AT->getZExtSize());
9430b57cec5SDimitry Andric }
9440b57cec5SDimitry Andric if (const RecordType *RT = Ty->getAs<RecordType>()) {
9450b57cec5SDimitry Andric SmallVector<const CXXBaseSpecifier *, 1> Bases;
9460b57cec5SDimitry Andric SmallVector<const FieldDecl *, 1> Fields;
9470b57cec5SDimitry Andric const RecordDecl *RD = RT->getDecl();
9480b57cec5SDimitry Andric assert(!RD->hasFlexibleArrayMember() &&
9490b57cec5SDimitry Andric "Cannot expand structure with flexible array.");
9500b57cec5SDimitry Andric if (RD->isUnion()) {
9510b57cec5SDimitry Andric // Unions can be here only in degenerative cases - all the fields are same
9520b57cec5SDimitry Andric // after flattening. Thus we have to use the "largest" field.
9530b57cec5SDimitry Andric const FieldDecl *LargestFD = nullptr;
9540b57cec5SDimitry Andric CharUnits UnionSize = CharUnits::Zero();
9550b57cec5SDimitry Andric
9560b57cec5SDimitry Andric for (const auto *FD : RD->fields()) {
9570b57cec5SDimitry Andric if (FD->isZeroLengthBitField(Context))
9580b57cec5SDimitry Andric continue;
9590b57cec5SDimitry Andric assert(!FD->isBitField() &&
9600b57cec5SDimitry Andric "Cannot expand structure with bit-field members.");
9610b57cec5SDimitry Andric CharUnits FieldSize = Context.getTypeSizeInChars(FD->getType());
9620b57cec5SDimitry Andric if (UnionSize < FieldSize) {
9630b57cec5SDimitry Andric UnionSize = FieldSize;
9640b57cec5SDimitry Andric LargestFD = FD;
9650b57cec5SDimitry Andric }
9660b57cec5SDimitry Andric }
9670b57cec5SDimitry Andric if (LargestFD)
9680b57cec5SDimitry Andric Fields.push_back(LargestFD);
9690b57cec5SDimitry Andric } else {
9700b57cec5SDimitry Andric if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
9710b57cec5SDimitry Andric assert(!CXXRD->isDynamicClass() &&
9720b57cec5SDimitry Andric "cannot expand vtable pointers in dynamic classes");
97381ad6265SDimitry Andric llvm::append_range(Bases, llvm::make_pointer_range(CXXRD->bases()));
9740b57cec5SDimitry Andric }
9750b57cec5SDimitry Andric
9760b57cec5SDimitry Andric for (const auto *FD : RD->fields()) {
9770b57cec5SDimitry Andric if (FD->isZeroLengthBitField(Context))
9780b57cec5SDimitry Andric continue;
9790b57cec5SDimitry Andric assert(!FD->isBitField() &&
9800b57cec5SDimitry Andric "Cannot expand structure with bit-field members.");
9810b57cec5SDimitry Andric Fields.push_back(FD);
9820b57cec5SDimitry Andric }
9830b57cec5SDimitry Andric }
984a7dea167SDimitry Andric return std::make_unique<RecordExpansion>(std::move(Bases),
9850b57cec5SDimitry Andric std::move(Fields));
9860b57cec5SDimitry Andric }
9870b57cec5SDimitry Andric if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
988a7dea167SDimitry Andric return std::make_unique<ComplexExpansion>(CT->getElementType());
9890b57cec5SDimitry Andric }
990a7dea167SDimitry Andric return std::make_unique<NoExpansion>();
9910b57cec5SDimitry Andric }
9920b57cec5SDimitry Andric
getExpansionSize(QualType Ty,const ASTContext & Context)9930b57cec5SDimitry Andric static int getExpansionSize(QualType Ty, const ASTContext &Context) {
9940b57cec5SDimitry Andric auto Exp = getTypeExpansion(Ty, Context);
9950b57cec5SDimitry Andric if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
9960b57cec5SDimitry Andric return CAExp->NumElts * getExpansionSize(CAExp->EltTy, Context);
9970b57cec5SDimitry Andric }
9980b57cec5SDimitry Andric if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
9990b57cec5SDimitry Andric int Res = 0;
10000b57cec5SDimitry Andric for (auto BS : RExp->Bases)
10010b57cec5SDimitry Andric Res += getExpansionSize(BS->getType(), Context);
10020b57cec5SDimitry Andric for (auto FD : RExp->Fields)
10030b57cec5SDimitry Andric Res += getExpansionSize(FD->getType(), Context);
10040b57cec5SDimitry Andric return Res;
10050b57cec5SDimitry Andric }
10060b57cec5SDimitry Andric if (isa<ComplexExpansion>(Exp.get()))
10070b57cec5SDimitry Andric return 2;
10080b57cec5SDimitry Andric assert(isa<NoExpansion>(Exp.get()));
10090b57cec5SDimitry Andric return 1;
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric
10120b57cec5SDimitry Andric void
getExpandedTypes(QualType Ty,SmallVectorImpl<llvm::Type * >::iterator & TI)10130b57cec5SDimitry Andric CodeGenTypes::getExpandedTypes(QualType Ty,
10140b57cec5SDimitry Andric SmallVectorImpl<llvm::Type *>::iterator &TI) {
10150b57cec5SDimitry Andric auto Exp = getTypeExpansion(Ty, Context);
10160b57cec5SDimitry Andric if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
10170b57cec5SDimitry Andric for (int i = 0, n = CAExp->NumElts; i < n; i++) {
10180b57cec5SDimitry Andric getExpandedTypes(CAExp->EltTy, TI);
10190b57cec5SDimitry Andric }
10200b57cec5SDimitry Andric } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
10210b57cec5SDimitry Andric for (auto BS : RExp->Bases)
10220b57cec5SDimitry Andric getExpandedTypes(BS->getType(), TI);
10230b57cec5SDimitry Andric for (auto FD : RExp->Fields)
10240b57cec5SDimitry Andric getExpandedTypes(FD->getType(), TI);
10250b57cec5SDimitry Andric } else if (auto CExp = dyn_cast<ComplexExpansion>(Exp.get())) {
10260b57cec5SDimitry Andric llvm::Type *EltTy = ConvertType(CExp->EltTy);
10270b57cec5SDimitry Andric *TI++ = EltTy;
10280b57cec5SDimitry Andric *TI++ = EltTy;
10290b57cec5SDimitry Andric } else {
10300b57cec5SDimitry Andric assert(isa<NoExpansion>(Exp.get()));
10310b57cec5SDimitry Andric *TI++ = ConvertType(Ty);
10320b57cec5SDimitry Andric }
10330b57cec5SDimitry Andric }
10340b57cec5SDimitry Andric
forConstantArrayExpansion(CodeGenFunction & CGF,ConstantArrayExpansion * CAE,Address BaseAddr,llvm::function_ref<void (Address)> Fn)10350b57cec5SDimitry Andric static void forConstantArrayExpansion(CodeGenFunction &CGF,
10360b57cec5SDimitry Andric ConstantArrayExpansion *CAE,
10370b57cec5SDimitry Andric Address BaseAddr,
10380b57cec5SDimitry Andric llvm::function_ref<void(Address)> Fn) {
10390b57cec5SDimitry Andric for (int i = 0, n = CAE->NumElts; i < n; i++) {
10400fca6ea1SDimitry Andric Address EltAddr = CGF.Builder.CreateConstGEP2_32(BaseAddr, 0, i);
10410fca6ea1SDimitry Andric Fn(EltAddr);
10420b57cec5SDimitry Andric }
10430b57cec5SDimitry Andric }
10440b57cec5SDimitry Andric
ExpandTypeFromArgs(QualType Ty,LValue LV,llvm::Function::arg_iterator & AI)10455ffd83dbSDimitry Andric void CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
10465ffd83dbSDimitry Andric llvm::Function::arg_iterator &AI) {
10470b57cec5SDimitry Andric assert(LV.isSimple() &&
10480b57cec5SDimitry Andric "Unexpected non-simple lvalue during struct expansion.");
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andric auto Exp = getTypeExpansion(Ty, getContext());
10510b57cec5SDimitry Andric if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
1052480093f4SDimitry Andric forConstantArrayExpansion(
10530fca6ea1SDimitry Andric *this, CAExp, LV.getAddress(), [&](Address EltAddr) {
10540b57cec5SDimitry Andric LValue LV = MakeAddrLValue(EltAddr, CAExp->EltTy);
10550b57cec5SDimitry Andric ExpandTypeFromArgs(CAExp->EltTy, LV, AI);
10560b57cec5SDimitry Andric });
10570b57cec5SDimitry Andric } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
10580fca6ea1SDimitry Andric Address This = LV.getAddress();
10590b57cec5SDimitry Andric for (const CXXBaseSpecifier *BS : RExp->Bases) {
10600b57cec5SDimitry Andric // Perform a single step derived-to-base conversion.
10610b57cec5SDimitry Andric Address Base =
10620b57cec5SDimitry Andric GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1,
10630b57cec5SDimitry Andric /*NullCheckValue=*/false, SourceLocation());
10640b57cec5SDimitry Andric LValue SubLV = MakeAddrLValue(Base, BS->getType());
10650b57cec5SDimitry Andric
10660b57cec5SDimitry Andric // Recurse onto bases.
10670b57cec5SDimitry Andric ExpandTypeFromArgs(BS->getType(), SubLV, AI);
10680b57cec5SDimitry Andric }
10690b57cec5SDimitry Andric for (auto FD : RExp->Fields) {
10700b57cec5SDimitry Andric // FIXME: What are the right qualifiers here?
10710b57cec5SDimitry Andric LValue SubLV = EmitLValueForFieldInitialization(LV, FD);
10720b57cec5SDimitry Andric ExpandTypeFromArgs(FD->getType(), SubLV, AI);
10730b57cec5SDimitry Andric }
10740b57cec5SDimitry Andric } else if (isa<ComplexExpansion>(Exp.get())) {
10755ffd83dbSDimitry Andric auto realValue = &*AI++;
10765ffd83dbSDimitry Andric auto imagValue = &*AI++;
10770b57cec5SDimitry Andric EmitStoreOfComplex(ComplexPairTy(realValue, imagValue), LV, /*init*/ true);
10780b57cec5SDimitry Andric } else {
1079480093f4SDimitry Andric // Call EmitStoreOfScalar except when the lvalue is a bitfield to emit a
1080480093f4SDimitry Andric // primitive store.
10810b57cec5SDimitry Andric assert(isa<NoExpansion>(Exp.get()));
10826a5eebc1SDimitry Andric llvm::Value *Arg = &*AI++;
10836a5eebc1SDimitry Andric if (LV.isBitField()) {
10846a5eebc1SDimitry Andric EmitStoreThroughLValue(RValue::get(Arg), LV);
10856a5eebc1SDimitry Andric } else {
10866a5eebc1SDimitry Andric // TODO: currently there are some places are inconsistent in what LLVM
10876a5eebc1SDimitry Andric // pointer type they use (see D118744). Once clang uses opaque pointers
10886a5eebc1SDimitry Andric // all LLVM pointer types will be the same and we can remove this check.
10896a5eebc1SDimitry Andric if (Arg->getType()->isPointerTy()) {
10900fca6ea1SDimitry Andric Address Addr = LV.getAddress();
10916a5eebc1SDimitry Andric Arg = Builder.CreateBitCast(Arg, Addr.getElementType());
10926a5eebc1SDimitry Andric }
10936a5eebc1SDimitry Andric EmitStoreOfScalar(Arg, LV);
10946a5eebc1SDimitry Andric }
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric }
10970b57cec5SDimitry Andric
ExpandTypeToArgs(QualType Ty,CallArg Arg,llvm::FunctionType * IRFuncTy,SmallVectorImpl<llvm::Value * > & IRCallArgs,unsigned & IRCallArgPos)10980b57cec5SDimitry Andric void CodeGenFunction::ExpandTypeToArgs(
10990b57cec5SDimitry Andric QualType Ty, CallArg Arg, llvm::FunctionType *IRFuncTy,
11000b57cec5SDimitry Andric SmallVectorImpl<llvm::Value *> &IRCallArgs, unsigned &IRCallArgPos) {
11010b57cec5SDimitry Andric auto Exp = getTypeExpansion(Ty, getContext());
11020b57cec5SDimitry Andric if (auto CAExp = dyn_cast<ConstantArrayExpansion>(Exp.get())) {
11030fca6ea1SDimitry Andric Address Addr = Arg.hasLValue() ? Arg.getKnownLValue().getAddress()
11040b57cec5SDimitry Andric : Arg.getKnownRValue().getAggregateAddress();
11050b57cec5SDimitry Andric forConstantArrayExpansion(
11060b57cec5SDimitry Andric *this, CAExp, Addr, [&](Address EltAddr) {
11070b57cec5SDimitry Andric CallArg EltArg = CallArg(
11080b57cec5SDimitry Andric convertTempToRValue(EltAddr, CAExp->EltTy, SourceLocation()),
11090b57cec5SDimitry Andric CAExp->EltTy);
11100b57cec5SDimitry Andric ExpandTypeToArgs(CAExp->EltTy, EltArg, IRFuncTy, IRCallArgs,
11110b57cec5SDimitry Andric IRCallArgPos);
11120b57cec5SDimitry Andric });
11130b57cec5SDimitry Andric } else if (auto RExp = dyn_cast<RecordExpansion>(Exp.get())) {
11140fca6ea1SDimitry Andric Address This = Arg.hasLValue() ? Arg.getKnownLValue().getAddress()
11150b57cec5SDimitry Andric : Arg.getKnownRValue().getAggregateAddress();
11160b57cec5SDimitry Andric for (const CXXBaseSpecifier *BS : RExp->Bases) {
11170b57cec5SDimitry Andric // Perform a single step derived-to-base conversion.
11180b57cec5SDimitry Andric Address Base =
11190b57cec5SDimitry Andric GetAddressOfBaseClass(This, Ty->getAsCXXRecordDecl(), &BS, &BS + 1,
11200b57cec5SDimitry Andric /*NullCheckValue=*/false, SourceLocation());
11210b57cec5SDimitry Andric CallArg BaseArg = CallArg(RValue::getAggregate(Base), BS->getType());
11220b57cec5SDimitry Andric
11230b57cec5SDimitry Andric // Recurse onto bases.
11240b57cec5SDimitry Andric ExpandTypeToArgs(BS->getType(), BaseArg, IRFuncTy, IRCallArgs,
11250b57cec5SDimitry Andric IRCallArgPos);
11260b57cec5SDimitry Andric }
11270b57cec5SDimitry Andric
11280b57cec5SDimitry Andric LValue LV = MakeAddrLValue(This, Ty);
11290b57cec5SDimitry Andric for (auto FD : RExp->Fields) {
11300b57cec5SDimitry Andric CallArg FldArg =
11310b57cec5SDimitry Andric CallArg(EmitRValueForField(LV, FD, SourceLocation()), FD->getType());
11320b57cec5SDimitry Andric ExpandTypeToArgs(FD->getType(), FldArg, IRFuncTy, IRCallArgs,
11330b57cec5SDimitry Andric IRCallArgPos);
11340b57cec5SDimitry Andric }
11350b57cec5SDimitry Andric } else if (isa<ComplexExpansion>(Exp.get())) {
11360b57cec5SDimitry Andric ComplexPairTy CV = Arg.getKnownRValue().getComplexVal();
11370b57cec5SDimitry Andric IRCallArgs[IRCallArgPos++] = CV.first;
11380b57cec5SDimitry Andric IRCallArgs[IRCallArgPos++] = CV.second;
11390b57cec5SDimitry Andric } else {
11400b57cec5SDimitry Andric assert(isa<NoExpansion>(Exp.get()));
11410b57cec5SDimitry Andric auto RV = Arg.getKnownRValue();
11420b57cec5SDimitry Andric assert(RV.isScalar() &&
11430b57cec5SDimitry Andric "Unexpected non-scalar rvalue during struct expansion.");
11440b57cec5SDimitry Andric
11450b57cec5SDimitry Andric // Insert a bitcast as needed.
11460b57cec5SDimitry Andric llvm::Value *V = RV.getScalarVal();
11470b57cec5SDimitry Andric if (IRCallArgPos < IRFuncTy->getNumParams() &&
11480b57cec5SDimitry Andric V->getType() != IRFuncTy->getParamType(IRCallArgPos))
11490b57cec5SDimitry Andric V = Builder.CreateBitCast(V, IRFuncTy->getParamType(IRCallArgPos));
11500b57cec5SDimitry Andric
11510b57cec5SDimitry Andric IRCallArgs[IRCallArgPos++] = V;
11520b57cec5SDimitry Andric }
11530b57cec5SDimitry Andric }
11540b57cec5SDimitry Andric
11550b57cec5SDimitry Andric /// Create a temporary allocation for the purposes of coercion.
CreateTempAllocaForCoercion(CodeGenFunction & CGF,llvm::Type * Ty,CharUnits MinAlign,const Twine & Name="tmp")11560fca6ea1SDimitry Andric static RawAddress CreateTempAllocaForCoercion(CodeGenFunction &CGF,
11570fca6ea1SDimitry Andric llvm::Type *Ty,
1158e8d8bef9SDimitry Andric CharUnits MinAlign,
1159e8d8bef9SDimitry Andric const Twine &Name = "tmp") {
11600b57cec5SDimitry Andric // Don't use an alignment that's worse than what LLVM would prefer.
1161bdd1243dSDimitry Andric auto PrefAlign = CGF.CGM.getDataLayout().getPrefTypeAlign(Ty);
11620b57cec5SDimitry Andric CharUnits Align = std::max(MinAlign, CharUnits::fromQuantity(PrefAlign));
11630b57cec5SDimitry Andric
1164e8d8bef9SDimitry Andric return CGF.CreateTempAlloca(Ty, Align, Name + ".coerce");
11650b57cec5SDimitry Andric }
11660b57cec5SDimitry Andric
11670b57cec5SDimitry Andric /// EnterStructPointerForCoercedAccess - Given a struct pointer that we are
11680b57cec5SDimitry Andric /// accessing some number of bytes out of it, try to gep into the struct to get
11690b57cec5SDimitry Andric /// at its inner goodness. Dive as deep as possible without entering an element
11700b57cec5SDimitry Andric /// with an in-memory size smaller than DstSize.
11710b57cec5SDimitry Andric static Address
EnterStructPointerForCoercedAccess(Address SrcPtr,llvm::StructType * SrcSTy,uint64_t DstSize,CodeGenFunction & CGF)11720b57cec5SDimitry Andric EnterStructPointerForCoercedAccess(Address SrcPtr,
11730b57cec5SDimitry Andric llvm::StructType *SrcSTy,
11740b57cec5SDimitry Andric uint64_t DstSize, CodeGenFunction &CGF) {
11750b57cec5SDimitry Andric // We can't dive into a zero-element struct.
11760b57cec5SDimitry Andric if (SrcSTy->getNumElements() == 0) return SrcPtr;
11770b57cec5SDimitry Andric
11780b57cec5SDimitry Andric llvm::Type *FirstElt = SrcSTy->getElementType(0);
11790b57cec5SDimitry Andric
11800b57cec5SDimitry Andric // If the first elt is at least as large as what we're looking for, or if the
11810b57cec5SDimitry Andric // first element is the same size as the whole struct, we can enter it. The
11820b57cec5SDimitry Andric // comparison must be made on the store size and not the alloca size. Using
11830b57cec5SDimitry Andric // the alloca size may overstate the size of the load.
11840b57cec5SDimitry Andric uint64_t FirstEltSize =
11850b57cec5SDimitry Andric CGF.CGM.getDataLayout().getTypeStoreSize(FirstElt);
11860b57cec5SDimitry Andric if (FirstEltSize < DstSize &&
11870b57cec5SDimitry Andric FirstEltSize < CGF.CGM.getDataLayout().getTypeStoreSize(SrcSTy))
11880b57cec5SDimitry Andric return SrcPtr;
11890b57cec5SDimitry Andric
11900b57cec5SDimitry Andric // GEP into the first element.
11910b57cec5SDimitry Andric SrcPtr = CGF.Builder.CreateStructGEP(SrcPtr, 0, "coerce.dive");
11920b57cec5SDimitry Andric
11930b57cec5SDimitry Andric // If the first element is a struct, recurse.
11940b57cec5SDimitry Andric llvm::Type *SrcTy = SrcPtr.getElementType();
11950b57cec5SDimitry Andric if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy))
11960b57cec5SDimitry Andric return EnterStructPointerForCoercedAccess(SrcPtr, SrcSTy, DstSize, CGF);
11970b57cec5SDimitry Andric
11980b57cec5SDimitry Andric return SrcPtr;
11990b57cec5SDimitry Andric }
12000b57cec5SDimitry Andric
12010b57cec5SDimitry Andric /// CoerceIntOrPtrToIntOrPtr - Convert a value Val to the specific Ty where both
12020b57cec5SDimitry Andric /// are either integers or pointers. This does a truncation of the value if it
12030b57cec5SDimitry Andric /// is too large or a zero extension if it is too small.
12040b57cec5SDimitry Andric ///
12050b57cec5SDimitry Andric /// This behaves as if the value were coerced through memory, so on big-endian
12060b57cec5SDimitry Andric /// targets the high bits are preserved in a truncation, while little-endian
12070b57cec5SDimitry Andric /// targets preserve the low bits.
CoerceIntOrPtrToIntOrPtr(llvm::Value * Val,llvm::Type * Ty,CodeGenFunction & CGF)12080b57cec5SDimitry Andric static llvm::Value *CoerceIntOrPtrToIntOrPtr(llvm::Value *Val,
12090b57cec5SDimitry Andric llvm::Type *Ty,
12100b57cec5SDimitry Andric CodeGenFunction &CGF) {
12110b57cec5SDimitry Andric if (Val->getType() == Ty)
12120b57cec5SDimitry Andric return Val;
12130b57cec5SDimitry Andric
12140b57cec5SDimitry Andric if (isa<llvm::PointerType>(Val->getType())) {
12150b57cec5SDimitry Andric // If this is Pointer->Pointer avoid conversion to and from int.
12160b57cec5SDimitry Andric if (isa<llvm::PointerType>(Ty))
12170b57cec5SDimitry Andric return CGF.Builder.CreateBitCast(Val, Ty, "coerce.val");
12180b57cec5SDimitry Andric
12190b57cec5SDimitry Andric // Convert the pointer to an integer so we can play with its width.
12200b57cec5SDimitry Andric Val = CGF.Builder.CreatePtrToInt(Val, CGF.IntPtrTy, "coerce.val.pi");
12210b57cec5SDimitry Andric }
12220b57cec5SDimitry Andric
12230b57cec5SDimitry Andric llvm::Type *DestIntTy = Ty;
12240b57cec5SDimitry Andric if (isa<llvm::PointerType>(DestIntTy))
12250b57cec5SDimitry Andric DestIntTy = CGF.IntPtrTy;
12260b57cec5SDimitry Andric
12270b57cec5SDimitry Andric if (Val->getType() != DestIntTy) {
12280b57cec5SDimitry Andric const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
12290b57cec5SDimitry Andric if (DL.isBigEndian()) {
12300b57cec5SDimitry Andric // Preserve the high bits on big-endian targets.
12310b57cec5SDimitry Andric // That is what memory coercion does.
12320b57cec5SDimitry Andric uint64_t SrcSize = DL.getTypeSizeInBits(Val->getType());
12330b57cec5SDimitry Andric uint64_t DstSize = DL.getTypeSizeInBits(DestIntTy);
12340b57cec5SDimitry Andric
12350b57cec5SDimitry Andric if (SrcSize > DstSize) {
12360b57cec5SDimitry Andric Val = CGF.Builder.CreateLShr(Val, SrcSize - DstSize, "coerce.highbits");
12370b57cec5SDimitry Andric Val = CGF.Builder.CreateTrunc(Val, DestIntTy, "coerce.val.ii");
12380b57cec5SDimitry Andric } else {
12390b57cec5SDimitry Andric Val = CGF.Builder.CreateZExt(Val, DestIntTy, "coerce.val.ii");
12400b57cec5SDimitry Andric Val = CGF.Builder.CreateShl(Val, DstSize - SrcSize, "coerce.highbits");
12410b57cec5SDimitry Andric }
12420b57cec5SDimitry Andric } else {
12430b57cec5SDimitry Andric // Little-endian targets preserve the low bits. No shifts required.
12440b57cec5SDimitry Andric Val = CGF.Builder.CreateIntCast(Val, DestIntTy, false, "coerce.val.ii");
12450b57cec5SDimitry Andric }
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric
12480b57cec5SDimitry Andric if (isa<llvm::PointerType>(Ty))
12490b57cec5SDimitry Andric Val = CGF.Builder.CreateIntToPtr(Val, Ty, "coerce.val.ip");
12500b57cec5SDimitry Andric return Val;
12510b57cec5SDimitry Andric }
12520b57cec5SDimitry Andric
12530b57cec5SDimitry Andric
12540b57cec5SDimitry Andric
12550b57cec5SDimitry Andric /// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as
12560b57cec5SDimitry Andric /// a pointer to an object of type \arg Ty, known to be aligned to
12570b57cec5SDimitry Andric /// \arg SrcAlign bytes.
12580b57cec5SDimitry Andric ///
12590b57cec5SDimitry Andric /// This safely handles the case when the src type is smaller than the
12600b57cec5SDimitry Andric /// destination type; in this situation the values of bits which not
12610b57cec5SDimitry Andric /// present in the src are undefined.
CreateCoercedLoad(Address Src,llvm::Type * Ty,CodeGenFunction & CGF)12620b57cec5SDimitry Andric static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
12630b57cec5SDimitry Andric CodeGenFunction &CGF) {
12640b57cec5SDimitry Andric llvm::Type *SrcTy = Src.getElementType();
12650b57cec5SDimitry Andric
12660b57cec5SDimitry Andric // If SrcTy and Ty are the same, just do a load.
12670b57cec5SDimitry Andric if (SrcTy == Ty)
12680b57cec5SDimitry Andric return CGF.Builder.CreateLoad(Src);
12690b57cec5SDimitry Andric
1270e8d8bef9SDimitry Andric llvm::TypeSize DstSize = CGF.CGM.getDataLayout().getTypeAllocSize(Ty);
12710b57cec5SDimitry Andric
12720b57cec5SDimitry Andric if (llvm::StructType *SrcSTy = dyn_cast<llvm::StructType>(SrcTy)) {
1273e8d8bef9SDimitry Andric Src = EnterStructPointerForCoercedAccess(Src, SrcSTy,
1274bdd1243dSDimitry Andric DstSize.getFixedValue(), CGF);
12755ffd83dbSDimitry Andric SrcTy = Src.getElementType();
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric
1278e8d8bef9SDimitry Andric llvm::TypeSize SrcSize = CGF.CGM.getDataLayout().getTypeAllocSize(SrcTy);
12790b57cec5SDimitry Andric
12800b57cec5SDimitry Andric // If the source and destination are integer or pointer types, just do an
12810b57cec5SDimitry Andric // extension or truncation to the desired type.
12820b57cec5SDimitry Andric if ((isa<llvm::IntegerType>(Ty) || isa<llvm::PointerType>(Ty)) &&
12830b57cec5SDimitry Andric (isa<llvm::IntegerType>(SrcTy) || isa<llvm::PointerType>(SrcTy))) {
12840b57cec5SDimitry Andric llvm::Value *Load = CGF.Builder.CreateLoad(Src);
12850b57cec5SDimitry Andric return CoerceIntOrPtrToIntOrPtr(Load, Ty, CGF);
12860b57cec5SDimitry Andric }
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andric // If load is legal, just bitcast the src pointer.
1289e8d8bef9SDimitry Andric if (!SrcSize.isScalable() && !DstSize.isScalable() &&
1290bdd1243dSDimitry Andric SrcSize.getFixedValue() >= DstSize.getFixedValue()) {
12910b57cec5SDimitry Andric // Generally SrcSize is never greater than DstSize, since this means we are
12920b57cec5SDimitry Andric // losing bits. However, this can happen in cases where the structure has
12930b57cec5SDimitry Andric // additional padding, for example due to a user specified alignment.
12940b57cec5SDimitry Andric //
12950b57cec5SDimitry Andric // FIXME: Assert that we aren't truncating non-padding bits when have access
12960b57cec5SDimitry Andric // to that information.
129706c3fb27SDimitry Andric Src = Src.withElementType(Ty);
12980b57cec5SDimitry Andric return CGF.Builder.CreateLoad(Src);
12990b57cec5SDimitry Andric }
13000b57cec5SDimitry Andric
1301e8d8bef9SDimitry Andric // If coercing a fixed vector to a scalable vector for ABI compatibility, and
130281ad6265SDimitry Andric // the types match, use the llvm.vector.insert intrinsic to perform the
130381ad6265SDimitry Andric // conversion.
13040fca6ea1SDimitry Andric if (auto *ScalableDstTy = dyn_cast<llvm::ScalableVectorType>(Ty)) {
13050fca6ea1SDimitry Andric if (auto *FixedSrcTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
13060fca6ea1SDimitry Andric // If we are casting a fixed i8 vector to a scalable i1 predicate
1307349cc55cSDimitry Andric // vector, use a vector insert and bitcast the result.
13080fca6ea1SDimitry Andric if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
13090fca6ea1SDimitry Andric ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
13100fca6ea1SDimitry Andric FixedSrcTy->getElementType()->isIntegerTy(8)) {
13110fca6ea1SDimitry Andric ScalableDstTy = llvm::ScalableVectorType::get(
13120fca6ea1SDimitry Andric FixedSrcTy->getElementType(),
13130fca6ea1SDimitry Andric ScalableDstTy->getElementCount().getKnownMinValue() / 8);
1314349cc55cSDimitry Andric }
13150fca6ea1SDimitry Andric if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
1316e8d8bef9SDimitry Andric auto *Load = CGF.Builder.CreateLoad(Src);
13170fca6ea1SDimitry Andric auto *UndefVec = llvm::UndefValue::get(ScalableDstTy);
1318e8d8bef9SDimitry Andric auto *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
1319349cc55cSDimitry Andric llvm::Value *Result = CGF.Builder.CreateInsertVector(
13200fca6ea1SDimitry Andric ScalableDstTy, UndefVec, Load, Zero, "cast.scalable");
13210fca6ea1SDimitry Andric if (ScalableDstTy != Ty)
13220fca6ea1SDimitry Andric Result = CGF.Builder.CreateBitCast(Result, Ty);
1323349cc55cSDimitry Andric return Result;
1324e8d8bef9SDimitry Andric }
1325e8d8bef9SDimitry Andric }
1326e8d8bef9SDimitry Andric }
1327e8d8bef9SDimitry Andric
13280b57cec5SDimitry Andric // Otherwise do coercion through memory. This is stupid, but simple.
13290fca6ea1SDimitry Andric RawAddress Tmp =
1330e8d8bef9SDimitry Andric CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment(), Src.getName());
1331e8d8bef9SDimitry Andric CGF.Builder.CreateMemCpy(
13320fca6ea1SDimitry Andric Tmp.getPointer(), Tmp.getAlignment().getAsAlign(),
13330fca6ea1SDimitry Andric Src.emitRawPointer(CGF), Src.getAlignment().getAsAlign(),
1334bdd1243dSDimitry Andric llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize.getKnownMinValue()));
13350b57cec5SDimitry Andric return CGF.Builder.CreateLoad(Tmp);
13360b57cec5SDimitry Andric }
13370b57cec5SDimitry Andric
CreateCoercedStore(llvm::Value * Src,Address Dst,llvm::TypeSize DstSize,bool DstIsVolatile)1338c80e69b0SDimitry Andric void CodeGenFunction::CreateCoercedStore(llvm::Value *Src, Address Dst,
1339c80e69b0SDimitry Andric llvm::TypeSize DstSize,
1340c80e69b0SDimitry Andric bool DstIsVolatile) {
1341c80e69b0SDimitry Andric if (!DstSize)
1342c80e69b0SDimitry Andric return;
1343c80e69b0SDimitry Andric
1344c80e69b0SDimitry Andric llvm::Type *SrcTy = Src->getType();
1345c80e69b0SDimitry Andric llvm::TypeSize SrcSize = CGM.getDataLayout().getTypeAllocSize(SrcTy);
1346c80e69b0SDimitry Andric
1347c80e69b0SDimitry Andric // GEP into structs to try to make types match.
1348c80e69b0SDimitry Andric // FIXME: This isn't really that useful with opaque types, but it impacts a
1349c80e69b0SDimitry Andric // lot of regression tests.
1350c80e69b0SDimitry Andric if (SrcTy != Dst.getElementType()) {
1351c80e69b0SDimitry Andric if (llvm::StructType *DstSTy =
1352c80e69b0SDimitry Andric dyn_cast<llvm::StructType>(Dst.getElementType())) {
1353c80e69b0SDimitry Andric assert(!SrcSize.isScalable());
1354c80e69b0SDimitry Andric Dst = EnterStructPointerForCoercedAccess(Dst, DstSTy,
1355c80e69b0SDimitry Andric SrcSize.getFixedValue(), *this);
1356c80e69b0SDimitry Andric }
1357c80e69b0SDimitry Andric }
1358c80e69b0SDimitry Andric
1359c80e69b0SDimitry Andric if (SrcSize.isScalable() || SrcSize <= DstSize) {
1360c80e69b0SDimitry Andric if (SrcTy->isIntegerTy() && Dst.getElementType()->isPointerTy() &&
1361c80e69b0SDimitry Andric SrcSize == CGM.getDataLayout().getTypeAllocSize(Dst.getElementType())) {
1362c80e69b0SDimitry Andric // If the value is supposed to be a pointer, convert it before storing it.
1363c80e69b0SDimitry Andric Src = CoerceIntOrPtrToIntOrPtr(Src, Dst.getElementType(), *this);
1364c80e69b0SDimitry Andric Builder.CreateStore(Src, Dst, DstIsVolatile);
1365c80e69b0SDimitry Andric } else if (llvm::StructType *STy =
1366c80e69b0SDimitry Andric dyn_cast<llvm::StructType>(Src->getType())) {
13670b57cec5SDimitry Andric // Prefer scalar stores to first-class aggregate stores.
1368c80e69b0SDimitry Andric Dst = Dst.withElementType(SrcTy);
13690b57cec5SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1370c80e69b0SDimitry Andric Address EltPtr = Builder.CreateStructGEP(Dst, i);
1371c80e69b0SDimitry Andric llvm::Value *Elt = Builder.CreateExtractValue(Src, i);
1372c80e69b0SDimitry Andric Builder.CreateStore(Elt, EltPtr, DstIsVolatile);
13730b57cec5SDimitry Andric }
13740b57cec5SDimitry Andric } else {
1375c80e69b0SDimitry Andric Builder.CreateStore(Src, Dst.withElementType(SrcTy), DstIsVolatile);
13760b57cec5SDimitry Andric }
1377c80e69b0SDimitry Andric } else if (SrcTy->isIntegerTy()) {
1378c80e69b0SDimitry Andric // If the source is a simple integer, coerce it directly.
1379c80e69b0SDimitry Andric llvm::Type *DstIntTy = Builder.getIntNTy(DstSize.getFixedValue() * 8);
1380c80e69b0SDimitry Andric Src = CoerceIntOrPtrToIntOrPtr(Src, DstIntTy, *this);
1381c80e69b0SDimitry Andric Builder.CreateStore(Src, Dst.withElementType(DstIntTy), DstIsVolatile);
13820b57cec5SDimitry Andric } else {
13830b57cec5SDimitry Andric // Otherwise do coercion through memory. This is stupid, but
13840b57cec5SDimitry Andric // simple.
13850b57cec5SDimitry Andric
13860b57cec5SDimitry Andric // Generally SrcSize is never greater than DstSize, since this means we are
13870b57cec5SDimitry Andric // losing bits. However, this can happen in cases where the structure has
13880b57cec5SDimitry Andric // additional padding, for example due to a user specified alignment.
13890b57cec5SDimitry Andric //
13900b57cec5SDimitry Andric // FIXME: Assert that we aren't truncating non-padding bits when have access
13910b57cec5SDimitry Andric // to that information.
13920fca6ea1SDimitry Andric RawAddress Tmp =
1393c80e69b0SDimitry Andric CreateTempAllocaForCoercion(*this, SrcTy, Dst.getAlignment());
1394c80e69b0SDimitry Andric Builder.CreateStore(Src, Tmp);
1395c80e69b0SDimitry Andric Builder.CreateMemCpy(Dst.emitRawPointer(*this),
1396c80e69b0SDimitry Andric Dst.getAlignment().getAsAlign(), Tmp.getPointer(),
1397c80e69b0SDimitry Andric Tmp.getAlignment().getAsAlign(),
1398c80e69b0SDimitry Andric Builder.CreateTypeSize(IntPtrTy, DstSize));
13990b57cec5SDimitry Andric }
14000b57cec5SDimitry Andric }
14010b57cec5SDimitry Andric
emitAddressAtOffset(CodeGenFunction & CGF,Address addr,const ABIArgInfo & info)14020b57cec5SDimitry Andric static Address emitAddressAtOffset(CodeGenFunction &CGF, Address addr,
14030b57cec5SDimitry Andric const ABIArgInfo &info) {
14040b57cec5SDimitry Andric if (unsigned offset = info.getDirectOffset()) {
140506c3fb27SDimitry Andric addr = addr.withElementType(CGF.Int8Ty);
14060b57cec5SDimitry Andric addr = CGF.Builder.CreateConstInBoundsByteGEP(addr,
14070b57cec5SDimitry Andric CharUnits::fromQuantity(offset));
140806c3fb27SDimitry Andric addr = addr.withElementType(info.getCoerceToType());
14090b57cec5SDimitry Andric }
14100b57cec5SDimitry Andric return addr;
14110b57cec5SDimitry Andric }
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andric namespace {
14140b57cec5SDimitry Andric
14150b57cec5SDimitry Andric /// Encapsulates information about the way function arguments from
14160b57cec5SDimitry Andric /// CGFunctionInfo should be passed to actual LLVM IR function.
14170b57cec5SDimitry Andric class ClangToLLVMArgMapping {
14180b57cec5SDimitry Andric static const unsigned InvalidIndex = ~0U;
14190b57cec5SDimitry Andric unsigned InallocaArgNo;
14200b57cec5SDimitry Andric unsigned SRetArgNo;
14210b57cec5SDimitry Andric unsigned TotalIRArgs;
14220b57cec5SDimitry Andric
14230b57cec5SDimitry Andric /// Arguments of LLVM IR function corresponding to single Clang argument.
14240b57cec5SDimitry Andric struct IRArgs {
14250b57cec5SDimitry Andric unsigned PaddingArgIndex;
14260b57cec5SDimitry Andric // Argument is expanded to IR arguments at positions
14270b57cec5SDimitry Andric // [FirstArgIndex, FirstArgIndex + NumberOfArgs).
14280b57cec5SDimitry Andric unsigned FirstArgIndex;
14290b57cec5SDimitry Andric unsigned NumberOfArgs;
14300b57cec5SDimitry Andric
IRArgs__anonf4c048640511::ClangToLLVMArgMapping::IRArgs14310b57cec5SDimitry Andric IRArgs()
14320b57cec5SDimitry Andric : PaddingArgIndex(InvalidIndex), FirstArgIndex(InvalidIndex),
14330b57cec5SDimitry Andric NumberOfArgs(0) {}
14340b57cec5SDimitry Andric };
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andric SmallVector<IRArgs, 8> ArgInfo;
14370b57cec5SDimitry Andric
14380b57cec5SDimitry Andric public:
ClangToLLVMArgMapping(const ASTContext & Context,const CGFunctionInfo & FI,bool OnlyRequiredArgs=false)14390b57cec5SDimitry Andric ClangToLLVMArgMapping(const ASTContext &Context, const CGFunctionInfo &FI,
14400b57cec5SDimitry Andric bool OnlyRequiredArgs = false)
14410b57cec5SDimitry Andric : InallocaArgNo(InvalidIndex), SRetArgNo(InvalidIndex), TotalIRArgs(0),
14420b57cec5SDimitry Andric ArgInfo(OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size()) {
14430b57cec5SDimitry Andric construct(Context, FI, OnlyRequiredArgs);
14440b57cec5SDimitry Andric }
14450b57cec5SDimitry Andric
hasInallocaArg() const14460b57cec5SDimitry Andric bool hasInallocaArg() const { return InallocaArgNo != InvalidIndex; }
getInallocaArgNo() const14470b57cec5SDimitry Andric unsigned getInallocaArgNo() const {
14480b57cec5SDimitry Andric assert(hasInallocaArg());
14490b57cec5SDimitry Andric return InallocaArgNo;
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric
hasSRetArg() const14520b57cec5SDimitry Andric bool hasSRetArg() const { return SRetArgNo != InvalidIndex; }
getSRetArgNo() const14530b57cec5SDimitry Andric unsigned getSRetArgNo() const {
14540b57cec5SDimitry Andric assert(hasSRetArg());
14550b57cec5SDimitry Andric return SRetArgNo;
14560b57cec5SDimitry Andric }
14570b57cec5SDimitry Andric
totalIRArgs() const14580b57cec5SDimitry Andric unsigned totalIRArgs() const { return TotalIRArgs; }
14590b57cec5SDimitry Andric
hasPaddingArg(unsigned ArgNo) const14600b57cec5SDimitry Andric bool hasPaddingArg(unsigned ArgNo) const {
14610b57cec5SDimitry Andric assert(ArgNo < ArgInfo.size());
14620b57cec5SDimitry Andric return ArgInfo[ArgNo].PaddingArgIndex != InvalidIndex;
14630b57cec5SDimitry Andric }
getPaddingArgNo(unsigned ArgNo) const14640b57cec5SDimitry Andric unsigned getPaddingArgNo(unsigned ArgNo) const {
14650b57cec5SDimitry Andric assert(hasPaddingArg(ArgNo));
14660b57cec5SDimitry Andric return ArgInfo[ArgNo].PaddingArgIndex;
14670b57cec5SDimitry Andric }
14680b57cec5SDimitry Andric
14690b57cec5SDimitry Andric /// Returns index of first IR argument corresponding to ArgNo, and their
14700b57cec5SDimitry Andric /// quantity.
getIRArgs(unsigned ArgNo) const14710b57cec5SDimitry Andric std::pair<unsigned, unsigned> getIRArgs(unsigned ArgNo) const {
14720b57cec5SDimitry Andric assert(ArgNo < ArgInfo.size());
14730b57cec5SDimitry Andric return std::make_pair(ArgInfo[ArgNo].FirstArgIndex,
14740b57cec5SDimitry Andric ArgInfo[ArgNo].NumberOfArgs);
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric
14770b57cec5SDimitry Andric private:
14780b57cec5SDimitry Andric void construct(const ASTContext &Context, const CGFunctionInfo &FI,
14790b57cec5SDimitry Andric bool OnlyRequiredArgs);
14800b57cec5SDimitry Andric };
14810b57cec5SDimitry Andric
construct(const ASTContext & Context,const CGFunctionInfo & FI,bool OnlyRequiredArgs)14820b57cec5SDimitry Andric void ClangToLLVMArgMapping::construct(const ASTContext &Context,
14830b57cec5SDimitry Andric const CGFunctionInfo &FI,
14840b57cec5SDimitry Andric bool OnlyRequiredArgs) {
14850b57cec5SDimitry Andric unsigned IRArgNo = 0;
14860b57cec5SDimitry Andric bool SwapThisWithSRet = false;
14870b57cec5SDimitry Andric const ABIArgInfo &RetAI = FI.getReturnInfo();
14880b57cec5SDimitry Andric
14890b57cec5SDimitry Andric if (RetAI.getKind() == ABIArgInfo::Indirect) {
14900b57cec5SDimitry Andric SwapThisWithSRet = RetAI.isSRetAfterThis();
14910b57cec5SDimitry Andric SRetArgNo = SwapThisWithSRet ? 1 : IRArgNo++;
14920b57cec5SDimitry Andric }
14930b57cec5SDimitry Andric
14940b57cec5SDimitry Andric unsigned ArgNo = 0;
14950b57cec5SDimitry Andric unsigned NumArgs = OnlyRequiredArgs ? FI.getNumRequiredArgs() : FI.arg_size();
14960b57cec5SDimitry Andric for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(); ArgNo < NumArgs;
14970b57cec5SDimitry Andric ++I, ++ArgNo) {
14980b57cec5SDimitry Andric assert(I != FI.arg_end());
14990b57cec5SDimitry Andric QualType ArgType = I->type;
15000b57cec5SDimitry Andric const ABIArgInfo &AI = I->info;
15010b57cec5SDimitry Andric // Collect data about IR arguments corresponding to Clang argument ArgNo.
15020b57cec5SDimitry Andric auto &IRArgs = ArgInfo[ArgNo];
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andric if (AI.getPaddingType())
15050b57cec5SDimitry Andric IRArgs.PaddingArgIndex = IRArgNo++;
15060b57cec5SDimitry Andric
15070b57cec5SDimitry Andric switch (AI.getKind()) {
15080b57cec5SDimitry Andric case ABIArgInfo::Extend:
15090b57cec5SDimitry Andric case ABIArgInfo::Direct: {
15100b57cec5SDimitry Andric // FIXME: handle sseregparm someday...
15110b57cec5SDimitry Andric llvm::StructType *STy = dyn_cast<llvm::StructType>(AI.getCoerceToType());
15120b57cec5SDimitry Andric if (AI.isDirect() && AI.getCanBeFlattened() && STy) {
15130b57cec5SDimitry Andric IRArgs.NumberOfArgs = STy->getNumElements();
15140b57cec5SDimitry Andric } else {
15150b57cec5SDimitry Andric IRArgs.NumberOfArgs = 1;
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric break;
15180b57cec5SDimitry Andric }
15190b57cec5SDimitry Andric case ABIArgInfo::Indirect:
1520e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased:
15210b57cec5SDimitry Andric IRArgs.NumberOfArgs = 1;
15220b57cec5SDimitry Andric break;
15230b57cec5SDimitry Andric case ABIArgInfo::Ignore:
15240b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
15250b57cec5SDimitry Andric // ignore and inalloca doesn't have matching LLVM parameters.
15260b57cec5SDimitry Andric IRArgs.NumberOfArgs = 0;
15270b57cec5SDimitry Andric break;
15280b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand:
15290b57cec5SDimitry Andric IRArgs.NumberOfArgs = AI.getCoerceAndExpandTypeSequence().size();
15300b57cec5SDimitry Andric break;
15310b57cec5SDimitry Andric case ABIArgInfo::Expand:
15320b57cec5SDimitry Andric IRArgs.NumberOfArgs = getExpansionSize(ArgType, Context);
15330b57cec5SDimitry Andric break;
15340b57cec5SDimitry Andric }
15350b57cec5SDimitry Andric
15360b57cec5SDimitry Andric if (IRArgs.NumberOfArgs > 0) {
15370b57cec5SDimitry Andric IRArgs.FirstArgIndex = IRArgNo;
15380b57cec5SDimitry Andric IRArgNo += IRArgs.NumberOfArgs;
15390b57cec5SDimitry Andric }
15400b57cec5SDimitry Andric
15410b57cec5SDimitry Andric // Skip over the sret parameter when it comes second. We already handled it
15420b57cec5SDimitry Andric // above.
15430b57cec5SDimitry Andric if (IRArgNo == 1 && SwapThisWithSRet)
15440b57cec5SDimitry Andric IRArgNo++;
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric assert(ArgNo == ArgInfo.size());
15470b57cec5SDimitry Andric
15480b57cec5SDimitry Andric if (FI.usesInAlloca())
15490b57cec5SDimitry Andric InallocaArgNo = IRArgNo++;
15500b57cec5SDimitry Andric
15510b57cec5SDimitry Andric TotalIRArgs = IRArgNo;
15520b57cec5SDimitry Andric }
15530b57cec5SDimitry Andric } // namespace
15540b57cec5SDimitry Andric
15550b57cec5SDimitry Andric /***/
15560b57cec5SDimitry Andric
ReturnTypeUsesSRet(const CGFunctionInfo & FI)15570b57cec5SDimitry Andric bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
15580b57cec5SDimitry Andric const auto &RI = FI.getReturnInfo();
15590b57cec5SDimitry Andric return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
15600b57cec5SDimitry Andric }
15610b57cec5SDimitry Andric
ReturnTypeHasInReg(const CGFunctionInfo & FI)15625678d1d9SDimitry Andric bool CodeGenModule::ReturnTypeHasInReg(const CGFunctionInfo &FI) {
15635678d1d9SDimitry Andric const auto &RI = FI.getReturnInfo();
15645678d1d9SDimitry Andric return RI.getInReg();
15655678d1d9SDimitry Andric }
15665678d1d9SDimitry Andric
ReturnSlotInterferesWithArgs(const CGFunctionInfo & FI)15670b57cec5SDimitry Andric bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
15680b57cec5SDimitry Andric return ReturnTypeUsesSRet(FI) &&
15690b57cec5SDimitry Andric getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs();
15700b57cec5SDimitry Andric }
15710b57cec5SDimitry Andric
ReturnTypeUsesFPRet(QualType ResultType)15720b57cec5SDimitry Andric bool CodeGenModule::ReturnTypeUsesFPRet(QualType ResultType) {
15730b57cec5SDimitry Andric if (const BuiltinType *BT = ResultType->getAs<BuiltinType>()) {
15740b57cec5SDimitry Andric switch (BT->getKind()) {
15750b57cec5SDimitry Andric default:
15760b57cec5SDimitry Andric return false;
15770b57cec5SDimitry Andric case BuiltinType::Float:
1578349cc55cSDimitry Andric return getTarget().useObjCFPRetForRealType(FloatModeKind::Float);
15790b57cec5SDimitry Andric case BuiltinType::Double:
1580349cc55cSDimitry Andric return getTarget().useObjCFPRetForRealType(FloatModeKind::Double);
15810b57cec5SDimitry Andric case BuiltinType::LongDouble:
1582349cc55cSDimitry Andric return getTarget().useObjCFPRetForRealType(FloatModeKind::LongDouble);
15830b57cec5SDimitry Andric }
15840b57cec5SDimitry Andric }
15850b57cec5SDimitry Andric
15860b57cec5SDimitry Andric return false;
15870b57cec5SDimitry Andric }
15880b57cec5SDimitry Andric
ReturnTypeUsesFP2Ret(QualType ResultType)15890b57cec5SDimitry Andric bool CodeGenModule::ReturnTypeUsesFP2Ret(QualType ResultType) {
15900b57cec5SDimitry Andric if (const ComplexType *CT = ResultType->getAs<ComplexType>()) {
15910b57cec5SDimitry Andric if (const BuiltinType *BT = CT->getElementType()->getAs<BuiltinType>()) {
15920b57cec5SDimitry Andric if (BT->getKind() == BuiltinType::LongDouble)
15930b57cec5SDimitry Andric return getTarget().useObjCFP2RetForComplexLongDouble();
15940b57cec5SDimitry Andric }
15950b57cec5SDimitry Andric }
15960b57cec5SDimitry Andric
15970b57cec5SDimitry Andric return false;
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric
GetFunctionType(GlobalDecl GD)16000b57cec5SDimitry Andric llvm::FunctionType *CodeGenTypes::GetFunctionType(GlobalDecl GD) {
16010b57cec5SDimitry Andric const CGFunctionInfo &FI = arrangeGlobalDeclaration(GD);
16020b57cec5SDimitry Andric return GetFunctionType(FI);
16030b57cec5SDimitry Andric }
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andric llvm::FunctionType *
GetFunctionType(const CGFunctionInfo & FI)16060b57cec5SDimitry Andric CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) {
16070b57cec5SDimitry Andric
16080b57cec5SDimitry Andric bool Inserted = FunctionsBeingProcessed.insert(&FI).second;
16090b57cec5SDimitry Andric (void)Inserted;
16100b57cec5SDimitry Andric assert(Inserted && "Recursively being processed?");
16110b57cec5SDimitry Andric
16120b57cec5SDimitry Andric llvm::Type *resultType = nullptr;
16130b57cec5SDimitry Andric const ABIArgInfo &retAI = FI.getReturnInfo();
16140b57cec5SDimitry Andric switch (retAI.getKind()) {
16150b57cec5SDimitry Andric case ABIArgInfo::Expand:
1616e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased:
16170b57cec5SDimitry Andric llvm_unreachable("Invalid ABI kind for return argument");
16180b57cec5SDimitry Andric
16190b57cec5SDimitry Andric case ABIArgInfo::Extend:
16200b57cec5SDimitry Andric case ABIArgInfo::Direct:
16210b57cec5SDimitry Andric resultType = retAI.getCoerceToType();
16220b57cec5SDimitry Andric break;
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
16250b57cec5SDimitry Andric if (retAI.getInAllocaSRet()) {
16260b57cec5SDimitry Andric // sret things on win32 aren't void, they return the sret pointer.
16270b57cec5SDimitry Andric QualType ret = FI.getReturnType();
1628bdd1243dSDimitry Andric unsigned addressSpace = CGM.getTypes().getTargetAddressSpace(ret);
162906c3fb27SDimitry Andric resultType = llvm::PointerType::get(getLLVMContext(), addressSpace);
16300b57cec5SDimitry Andric } else {
16310b57cec5SDimitry Andric resultType = llvm::Type::getVoidTy(getLLVMContext());
16320b57cec5SDimitry Andric }
16330b57cec5SDimitry Andric break;
16340b57cec5SDimitry Andric
16350b57cec5SDimitry Andric case ABIArgInfo::Indirect:
16360b57cec5SDimitry Andric case ABIArgInfo::Ignore:
16370b57cec5SDimitry Andric resultType = llvm::Type::getVoidTy(getLLVMContext());
16380b57cec5SDimitry Andric break;
16390b57cec5SDimitry Andric
16400b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand:
16410b57cec5SDimitry Andric resultType = retAI.getUnpaddedCoerceAndExpandType();
16420b57cec5SDimitry Andric break;
16430b57cec5SDimitry Andric }
16440b57cec5SDimitry Andric
16450b57cec5SDimitry Andric ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI, true);
16460b57cec5SDimitry Andric SmallVector<llvm::Type*, 8> ArgTypes(IRFunctionArgs.totalIRArgs());
16470b57cec5SDimitry Andric
16480b57cec5SDimitry Andric // Add type for sret argument.
16490b57cec5SDimitry Andric if (IRFunctionArgs.hasSRetArg()) {
16500b57cec5SDimitry Andric QualType Ret = FI.getReturnType();
1651bdd1243dSDimitry Andric unsigned AddressSpace = CGM.getTypes().getTargetAddressSpace(Ret);
16520b57cec5SDimitry Andric ArgTypes[IRFunctionArgs.getSRetArgNo()] =
165306c3fb27SDimitry Andric llvm::PointerType::get(getLLVMContext(), AddressSpace);
16540b57cec5SDimitry Andric }
16550b57cec5SDimitry Andric
16560b57cec5SDimitry Andric // Add type for inalloca argument.
165706c3fb27SDimitry Andric if (IRFunctionArgs.hasInallocaArg())
165806c3fb27SDimitry Andric ArgTypes[IRFunctionArgs.getInallocaArgNo()] =
165906c3fb27SDimitry Andric llvm::PointerType::getUnqual(getLLVMContext());
16600b57cec5SDimitry Andric
16610b57cec5SDimitry Andric // Add in all of the required arguments.
16620b57cec5SDimitry Andric unsigned ArgNo = 0;
16630b57cec5SDimitry Andric CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
16640b57cec5SDimitry Andric ie = it + FI.getNumRequiredArgs();
16650b57cec5SDimitry Andric for (; it != ie; ++it, ++ArgNo) {
16660b57cec5SDimitry Andric const ABIArgInfo &ArgInfo = it->info;
16670b57cec5SDimitry Andric
16680b57cec5SDimitry Andric // Insert a padding type to ensure proper alignment.
16690b57cec5SDimitry Andric if (IRFunctionArgs.hasPaddingArg(ArgNo))
16700b57cec5SDimitry Andric ArgTypes[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
16710b57cec5SDimitry Andric ArgInfo.getPaddingType();
16720b57cec5SDimitry Andric
16730b57cec5SDimitry Andric unsigned FirstIRArg, NumIRArgs;
16740b57cec5SDimitry Andric std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
16750b57cec5SDimitry Andric
16760b57cec5SDimitry Andric switch (ArgInfo.getKind()) {
16770b57cec5SDimitry Andric case ABIArgInfo::Ignore:
16780b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
16790b57cec5SDimitry Andric assert(NumIRArgs == 0);
16800b57cec5SDimitry Andric break;
16810b57cec5SDimitry Andric
168206c3fb27SDimitry Andric case ABIArgInfo::Indirect:
16830b57cec5SDimitry Andric assert(NumIRArgs == 1);
16840b57cec5SDimitry Andric // indirect arguments are always on the stack, which is alloca addr space.
168506c3fb27SDimitry Andric ArgTypes[FirstIRArg] = llvm::PointerType::get(
168606c3fb27SDimitry Andric getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace());
16870b57cec5SDimitry Andric break;
168806c3fb27SDimitry Andric case ABIArgInfo::IndirectAliased:
1689e8d8bef9SDimitry Andric assert(NumIRArgs == 1);
169006c3fb27SDimitry Andric ArgTypes[FirstIRArg] = llvm::PointerType::get(
169106c3fb27SDimitry Andric getLLVMContext(), ArgInfo.getIndirectAddrSpace());
1692e8d8bef9SDimitry Andric break;
16930b57cec5SDimitry Andric case ABIArgInfo::Extend:
16940b57cec5SDimitry Andric case ABIArgInfo::Direct: {
16950b57cec5SDimitry Andric // Fast-isel and the optimizer generally like scalar values better than
16960b57cec5SDimitry Andric // FCAs, so we flatten them if this is safe to do for this argument.
16970b57cec5SDimitry Andric llvm::Type *argType = ArgInfo.getCoerceToType();
16980b57cec5SDimitry Andric llvm::StructType *st = dyn_cast<llvm::StructType>(argType);
16990b57cec5SDimitry Andric if (st && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) {
17000b57cec5SDimitry Andric assert(NumIRArgs == st->getNumElements());
17010b57cec5SDimitry Andric for (unsigned i = 0, e = st->getNumElements(); i != e; ++i)
17020b57cec5SDimitry Andric ArgTypes[FirstIRArg + i] = st->getElementType(i);
17030b57cec5SDimitry Andric } else {
17040b57cec5SDimitry Andric assert(NumIRArgs == 1);
17050b57cec5SDimitry Andric ArgTypes[FirstIRArg] = argType;
17060b57cec5SDimitry Andric }
17070b57cec5SDimitry Andric break;
17080b57cec5SDimitry Andric }
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand: {
17110b57cec5SDimitry Andric auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
1712bdd1243dSDimitry Andric for (auto *EltTy : ArgInfo.getCoerceAndExpandTypeSequence()) {
17130b57cec5SDimitry Andric *ArgTypesIter++ = EltTy;
17140b57cec5SDimitry Andric }
17150b57cec5SDimitry Andric assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
17160b57cec5SDimitry Andric break;
17170b57cec5SDimitry Andric }
17180b57cec5SDimitry Andric
17190b57cec5SDimitry Andric case ABIArgInfo::Expand:
17200b57cec5SDimitry Andric auto ArgTypesIter = ArgTypes.begin() + FirstIRArg;
17210b57cec5SDimitry Andric getExpandedTypes(it->type, ArgTypesIter);
17220b57cec5SDimitry Andric assert(ArgTypesIter == ArgTypes.begin() + FirstIRArg + NumIRArgs);
17230b57cec5SDimitry Andric break;
17240b57cec5SDimitry Andric }
17250b57cec5SDimitry Andric }
17260b57cec5SDimitry Andric
17270b57cec5SDimitry Andric bool Erased = FunctionsBeingProcessed.erase(&FI); (void)Erased;
17280b57cec5SDimitry Andric assert(Erased && "Not in set?");
17290b57cec5SDimitry Andric
17300b57cec5SDimitry Andric return llvm::FunctionType::get(resultType, ArgTypes, FI.isVariadic());
17310b57cec5SDimitry Andric }
17320b57cec5SDimitry Andric
GetFunctionTypeForVTable(GlobalDecl GD)17330b57cec5SDimitry Andric llvm::Type *CodeGenTypes::GetFunctionTypeForVTable(GlobalDecl GD) {
17340b57cec5SDimitry Andric const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
173506c3fb27SDimitry Andric const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
17360b57cec5SDimitry Andric
17370b57cec5SDimitry Andric if (!isFuncTypeConvertible(FPT))
17380b57cec5SDimitry Andric return llvm::StructType::get(getLLVMContext());
17390b57cec5SDimitry Andric
17400b57cec5SDimitry Andric return GetFunctionType(GD);
17410b57cec5SDimitry Andric }
17420b57cec5SDimitry Andric
AddAttributesFromFunctionProtoType(ASTContext & Ctx,llvm::AttrBuilder & FuncAttrs,const FunctionProtoType * FPT)17430b57cec5SDimitry Andric static void AddAttributesFromFunctionProtoType(ASTContext &Ctx,
17440b57cec5SDimitry Andric llvm::AttrBuilder &FuncAttrs,
17450b57cec5SDimitry Andric const FunctionProtoType *FPT) {
17460b57cec5SDimitry Andric if (!FPT)
17470b57cec5SDimitry Andric return;
17480b57cec5SDimitry Andric
17490b57cec5SDimitry Andric if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) &&
17500b57cec5SDimitry Andric FPT->isNothrow())
17510b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
17525f757f3fSDimitry Andric
17537a6dacacSDimitry Andric unsigned SMEBits = FPT->getAArch64SMEAttributes();
17547a6dacacSDimitry Andric if (SMEBits & FunctionType::SME_PStateSMEnabledMask)
17555f757f3fSDimitry Andric FuncAttrs.addAttribute("aarch64_pstate_sm_enabled");
17567a6dacacSDimitry Andric if (SMEBits & FunctionType::SME_PStateSMCompatibleMask)
17575f757f3fSDimitry Andric FuncAttrs.addAttribute("aarch64_pstate_sm_compatible");
17587a6dacacSDimitry Andric
17597a6dacacSDimitry Andric // ZA
17600fca6ea1SDimitry Andric if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Preserves)
17610fca6ea1SDimitry Andric FuncAttrs.addAttribute("aarch64_preserves_za");
17620fca6ea1SDimitry Andric if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_In)
17630fca6ea1SDimitry Andric FuncAttrs.addAttribute("aarch64_in_za");
17640fca6ea1SDimitry Andric if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_Out)
17650fca6ea1SDimitry Andric FuncAttrs.addAttribute("aarch64_out_za");
17660fca6ea1SDimitry Andric if (FunctionType::getArmZAState(SMEBits) == FunctionType::ARM_InOut)
17670fca6ea1SDimitry Andric FuncAttrs.addAttribute("aarch64_inout_za");
17680b57cec5SDimitry Andric
17697a6dacacSDimitry Andric // ZT0
17707a6dacacSDimitry Andric if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Preserves)
17717a6dacacSDimitry Andric FuncAttrs.addAttribute("aarch64_preserves_zt0");
17727a6dacacSDimitry Andric if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_In)
17737a6dacacSDimitry Andric FuncAttrs.addAttribute("aarch64_in_zt0");
17747a6dacacSDimitry Andric if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_Out)
17757a6dacacSDimitry Andric FuncAttrs.addAttribute("aarch64_out_zt0");
17767a6dacacSDimitry Andric if (FunctionType::getArmZT0State(SMEBits) == FunctionType::ARM_InOut)
17777a6dacacSDimitry Andric FuncAttrs.addAttribute("aarch64_inout_zt0");
17787a6dacacSDimitry Andric }
17797a6dacacSDimitry Andric
AddAttributesFromOMPAssumes(llvm::AttrBuilder & FuncAttrs,const Decl * Callee)17800fca6ea1SDimitry Andric static void AddAttributesFromOMPAssumes(llvm::AttrBuilder &FuncAttrs,
1781349cc55cSDimitry Andric const Decl *Callee) {
1782349cc55cSDimitry Andric if (!Callee)
1783349cc55cSDimitry Andric return;
1784349cc55cSDimitry Andric
1785349cc55cSDimitry Andric SmallVector<StringRef, 4> Attrs;
1786349cc55cSDimitry Andric
17870fca6ea1SDimitry Andric for (const OMPAssumeAttr *AA : Callee->specific_attrs<OMPAssumeAttr>())
1788349cc55cSDimitry Andric AA->getAssumption().split(Attrs, ",");
1789349cc55cSDimitry Andric
1790349cc55cSDimitry Andric if (!Attrs.empty())
1791349cc55cSDimitry Andric FuncAttrs.addAttribute(llvm::AssumptionAttrKey,
1792349cc55cSDimitry Andric llvm::join(Attrs.begin(), Attrs.end(), ","));
1793349cc55cSDimitry Andric }
1794349cc55cSDimitry Andric
MayDropFunctionReturn(const ASTContext & Context,QualType ReturnType) const1795fe6060f1SDimitry Andric bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context,
1796bdd1243dSDimitry Andric QualType ReturnType) const {
1797fe6060f1SDimitry Andric // We can't just discard the return value for a record type with a
1798fe6060f1SDimitry Andric // complex destructor or a non-trivially copyable type.
1799fe6060f1SDimitry Andric if (const RecordType *RT =
1800fe6060f1SDimitry Andric ReturnType.getCanonicalType()->getAs<RecordType>()) {
1801fe6060f1SDimitry Andric if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
1802fe6060f1SDimitry Andric return ClassDecl->hasTrivialDestructor();
1803fe6060f1SDimitry Andric }
1804fe6060f1SDimitry Andric return ReturnType.isTriviallyCopyableType(Context);
1805fe6060f1SDimitry Andric }
1806fe6060f1SDimitry Andric
HasStrictReturn(const CodeGenModule & Module,QualType RetTy,const Decl * TargetDecl)1807bdd1243dSDimitry Andric static bool HasStrictReturn(const CodeGenModule &Module, QualType RetTy,
1808bdd1243dSDimitry Andric const Decl *TargetDecl) {
1809bdd1243dSDimitry Andric // As-is msan can not tolerate noundef mismatch between caller and
1810bdd1243dSDimitry Andric // implementation. Mismatch is possible for e.g. indirect calls from C-caller
1811bdd1243dSDimitry Andric // into C++. Such mismatches lead to confusing false reports. To avoid
1812bdd1243dSDimitry Andric // expensive workaround on msan we enforce initialization event in uncommon
1813bdd1243dSDimitry Andric // cases where it's allowed.
1814bdd1243dSDimitry Andric if (Module.getLangOpts().Sanitize.has(SanitizerKind::Memory))
1815bdd1243dSDimitry Andric return true;
1816bdd1243dSDimitry Andric // C++ explicitly makes returning undefined values UB. C's rule only applies
1817bdd1243dSDimitry Andric // to used values, so we never mark them noundef for now.
1818bdd1243dSDimitry Andric if (!Module.getLangOpts().CPlusPlus)
1819bdd1243dSDimitry Andric return false;
1820bdd1243dSDimitry Andric if (TargetDecl) {
1821bdd1243dSDimitry Andric if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(TargetDecl)) {
1822bdd1243dSDimitry Andric if (FDecl->isExternC())
1823bdd1243dSDimitry Andric return false;
1824bdd1243dSDimitry Andric } else if (const VarDecl *VDecl = dyn_cast<VarDecl>(TargetDecl)) {
1825bdd1243dSDimitry Andric // Function pointer.
1826bdd1243dSDimitry Andric if (VDecl->isExternC())
1827bdd1243dSDimitry Andric return false;
1828bdd1243dSDimitry Andric }
1829bdd1243dSDimitry Andric }
1830bdd1243dSDimitry Andric
1831bdd1243dSDimitry Andric // We don't want to be too aggressive with the return checking, unless
1832bdd1243dSDimitry Andric // it's explicit in the code opts or we're using an appropriate sanitizer.
1833bdd1243dSDimitry Andric // Try to respect what the programmer intended.
1834bdd1243dSDimitry Andric return Module.getCodeGenOpts().StrictReturn ||
1835bdd1243dSDimitry Andric !Module.MayDropFunctionReturn(Module.getContext(), RetTy) ||
1836bdd1243dSDimitry Andric Module.getLangOpts().Sanitize.has(SanitizerKind::Return);
1837bdd1243dSDimitry Andric }
1838bdd1243dSDimitry Andric
183906c3fb27SDimitry Andric /// Add denormal-fp-math and denormal-fp-math-f32 as appropriate for the
184006c3fb27SDimitry Andric /// requested denormal behavior, accounting for the overriding behavior of the
184106c3fb27SDimitry Andric /// -f32 case.
addDenormalModeAttrs(llvm::DenormalMode FPDenormalMode,llvm::DenormalMode FP32DenormalMode,llvm::AttrBuilder & FuncAttrs)184206c3fb27SDimitry Andric static void addDenormalModeAttrs(llvm::DenormalMode FPDenormalMode,
184306c3fb27SDimitry Andric llvm::DenormalMode FP32DenormalMode,
184406c3fb27SDimitry Andric llvm::AttrBuilder &FuncAttrs) {
184506c3fb27SDimitry Andric if (FPDenormalMode != llvm::DenormalMode::getDefault())
184606c3fb27SDimitry Andric FuncAttrs.addAttribute("denormal-fp-math", FPDenormalMode.str());
184706c3fb27SDimitry Andric
184806c3fb27SDimitry Andric if (FP32DenormalMode != FPDenormalMode && FP32DenormalMode.isValid())
184906c3fb27SDimitry Andric FuncAttrs.addAttribute("denormal-fp-math-f32", FP32DenormalMode.str());
185006c3fb27SDimitry Andric }
185106c3fb27SDimitry Andric
185206c3fb27SDimitry Andric /// Add default attributes to a function, which have merge semantics under
185306c3fb27SDimitry Andric /// -mlink-builtin-bitcode and should not simply overwrite any existing
185406c3fb27SDimitry Andric /// attributes in the linked library.
185506c3fb27SDimitry Andric static void
addMergableDefaultFunctionAttributes(const CodeGenOptions & CodeGenOpts,llvm::AttrBuilder & FuncAttrs)185606c3fb27SDimitry Andric addMergableDefaultFunctionAttributes(const CodeGenOptions &CodeGenOpts,
185706c3fb27SDimitry Andric llvm::AttrBuilder &FuncAttrs) {
185806c3fb27SDimitry Andric addDenormalModeAttrs(CodeGenOpts.FPDenormalMode, CodeGenOpts.FP32DenormalMode,
185906c3fb27SDimitry Andric FuncAttrs);
186006c3fb27SDimitry Andric }
186106c3fb27SDimitry Andric
getTrivialDefaultFunctionAttributes(StringRef Name,bool HasOptnone,const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts,bool AttrOnCallSite,llvm::AttrBuilder & FuncAttrs)186206c3fb27SDimitry Andric static void getTrivialDefaultFunctionAttributes(
186306c3fb27SDimitry Andric StringRef Name, bool HasOptnone, const CodeGenOptions &CodeGenOpts,
186406c3fb27SDimitry Andric const LangOptions &LangOpts, bool AttrOnCallSite,
18650b57cec5SDimitry Andric llvm::AttrBuilder &FuncAttrs) {
18660b57cec5SDimitry Andric // OptimizeNoneAttr takes precedence over -Os or -Oz. No warning needed.
18670b57cec5SDimitry Andric if (!HasOptnone) {
18680b57cec5SDimitry Andric if (CodeGenOpts.OptimizeSize)
18690b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::OptimizeForSize);
18700b57cec5SDimitry Andric if (CodeGenOpts.OptimizeSize == 2)
18710b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::MinSize);
18720b57cec5SDimitry Andric }
18730b57cec5SDimitry Andric
18740b57cec5SDimitry Andric if (CodeGenOpts.DisableRedZone)
18750b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoRedZone);
18760b57cec5SDimitry Andric if (CodeGenOpts.IndirectTlsSegRefs)
18770b57cec5SDimitry Andric FuncAttrs.addAttribute("indirect-tls-seg-refs");
18780b57cec5SDimitry Andric if (CodeGenOpts.NoImplicitFloat)
18790b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat);
18800b57cec5SDimitry Andric
18810b57cec5SDimitry Andric if (AttrOnCallSite) {
18820b57cec5SDimitry Andric // Attributes that should go on the call site only.
188381ad6265SDimitry Andric // FIXME: Look for 'BuiltinAttr' on the function rather than re-checking
188481ad6265SDimitry Andric // the -fno-builtin-foo list.
1885fe6060f1SDimitry Andric if (!CodeGenOpts.SimplifyLibCalls || LangOpts.isNoBuiltinFunc(Name))
18860b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoBuiltin);
18870b57cec5SDimitry Andric if (!CodeGenOpts.TrapFuncName.empty())
18880b57cec5SDimitry Andric FuncAttrs.addAttribute("trap-func-name", CodeGenOpts.TrapFuncName);
18890b57cec5SDimitry Andric } else {
1890a7dea167SDimitry Andric switch (CodeGenOpts.getFramePointer()) {
1891a7dea167SDimitry Andric case CodeGenOptions::FramePointerKind::None:
1892bdd1243dSDimitry Andric // This is the default behavior.
1893a7dea167SDimitry Andric break;
18940fca6ea1SDimitry Andric case CodeGenOptions::FramePointerKind::Reserved:
1895a7dea167SDimitry Andric case CodeGenOptions::FramePointerKind::NonLeaf:
1896a7dea167SDimitry Andric case CodeGenOptions::FramePointerKind::All:
1897bdd1243dSDimitry Andric FuncAttrs.addAttribute("frame-pointer",
1898bdd1243dSDimitry Andric CodeGenOptions::getFramePointerKindName(
1899bdd1243dSDimitry Andric CodeGenOpts.getFramePointer()));
19000b57cec5SDimitry Andric }
19010b57cec5SDimitry Andric
1902fe6060f1SDimitry Andric if (CodeGenOpts.LessPreciseFPMAD)
1903fe6060f1SDimitry Andric FuncAttrs.addAttribute("less-precise-fpmad", "true");
19040b57cec5SDimitry Andric
19050b57cec5SDimitry Andric if (CodeGenOpts.NullPointerIsValid)
19065ffd83dbSDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
19075ffd83dbSDimitry Andric
190881ad6265SDimitry Andric if (LangOpts.getDefaultExceptionMode() == LangOptions::FPE_Ignore)
1909fe6060f1SDimitry Andric FuncAttrs.addAttribute("no-trapping-math", "true");
19100b57cec5SDimitry Andric
19110b57cec5SDimitry Andric // TODO: Are these all needed?
19120b57cec5SDimitry Andric // unsafe/inf/nan/nsz are handled by instruction-level FastMathFlags.
1913fe6060f1SDimitry Andric if (LangOpts.NoHonorInfs)
1914fe6060f1SDimitry Andric FuncAttrs.addAttribute("no-infs-fp-math", "true");
1915fe6060f1SDimitry Andric if (LangOpts.NoHonorNaNs)
1916fe6060f1SDimitry Andric FuncAttrs.addAttribute("no-nans-fp-math", "true");
1917349cc55cSDimitry Andric if (LangOpts.ApproxFunc)
1918349cc55cSDimitry Andric FuncAttrs.addAttribute("approx-func-fp-math", "true");
1919bdd1243dSDimitry Andric if (LangOpts.AllowFPReassoc && LangOpts.AllowRecip &&
1920bdd1243dSDimitry Andric LangOpts.NoSignedZero && LangOpts.ApproxFunc &&
1921bdd1243dSDimitry Andric (LangOpts.getDefaultFPContractMode() ==
1922bdd1243dSDimitry Andric LangOptions::FPModeKind::FPM_Fast ||
1923bdd1243dSDimitry Andric LangOpts.getDefaultFPContractMode() ==
1924bdd1243dSDimitry Andric LangOptions::FPModeKind::FPM_FastHonorPragmas))
1925fe6060f1SDimitry Andric FuncAttrs.addAttribute("unsafe-fp-math", "true");
1926fe6060f1SDimitry Andric if (CodeGenOpts.SoftFloat)
1927fe6060f1SDimitry Andric FuncAttrs.addAttribute("use-soft-float", "true");
19280b57cec5SDimitry Andric FuncAttrs.addAttribute("stack-protector-buffer-size",
19290b57cec5SDimitry Andric llvm::utostr(CodeGenOpts.SSPBufferSize));
1930fe6060f1SDimitry Andric if (LangOpts.NoSignedZero)
1931fe6060f1SDimitry Andric FuncAttrs.addAttribute("no-signed-zeros-fp-math", "true");
19320b57cec5SDimitry Andric
19330b57cec5SDimitry Andric // TODO: Reciprocal estimate codegen options should apply to instructions?
19340b57cec5SDimitry Andric const std::vector<std::string> &Recips = CodeGenOpts.Reciprocals;
19350b57cec5SDimitry Andric if (!Recips.empty())
19360b57cec5SDimitry Andric FuncAttrs.addAttribute("reciprocal-estimates",
19370b57cec5SDimitry Andric llvm::join(Recips, ","));
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andric if (!CodeGenOpts.PreferVectorWidth.empty() &&
19400b57cec5SDimitry Andric CodeGenOpts.PreferVectorWidth != "none")
19410b57cec5SDimitry Andric FuncAttrs.addAttribute("prefer-vector-width",
19420b57cec5SDimitry Andric CodeGenOpts.PreferVectorWidth);
19430b57cec5SDimitry Andric
19440b57cec5SDimitry Andric if (CodeGenOpts.StackRealignment)
19450b57cec5SDimitry Andric FuncAttrs.addAttribute("stackrealign");
19460b57cec5SDimitry Andric if (CodeGenOpts.Backchain)
19470b57cec5SDimitry Andric FuncAttrs.addAttribute("backchain");
19485ffd83dbSDimitry Andric if (CodeGenOpts.EnableSegmentedStacks)
19495ffd83dbSDimitry Andric FuncAttrs.addAttribute("split-stack");
19500b57cec5SDimitry Andric
19510b57cec5SDimitry Andric if (CodeGenOpts.SpeculativeLoadHardening)
19520b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
195381ad6265SDimitry Andric
195481ad6265SDimitry Andric // Add zero-call-used-regs attribute.
195581ad6265SDimitry Andric switch (CodeGenOpts.getZeroCallUsedRegs()) {
195681ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Skip:
195781ad6265SDimitry Andric FuncAttrs.removeAttribute("zero-call-used-regs");
195881ad6265SDimitry Andric break;
195981ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPRArg:
196081ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "used-gpr-arg");
196181ad6265SDimitry Andric break;
196281ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedGPR:
196381ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "used-gpr");
196481ad6265SDimitry Andric break;
196581ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::UsedArg:
196681ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "used-arg");
196781ad6265SDimitry Andric break;
196881ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::Used:
196981ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "used");
197081ad6265SDimitry Andric break;
197181ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPRArg:
197281ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "all-gpr-arg");
197381ad6265SDimitry Andric break;
197481ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllGPR:
197581ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "all-gpr");
197681ad6265SDimitry Andric break;
197781ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::AllArg:
197881ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "all-arg");
197981ad6265SDimitry Andric break;
198081ad6265SDimitry Andric case llvm::ZeroCallUsedRegs::ZeroCallUsedRegsKind::All:
198181ad6265SDimitry Andric FuncAttrs.addAttribute("zero-call-used-regs", "all");
198281ad6265SDimitry Andric break;
198381ad6265SDimitry Andric }
19840b57cec5SDimitry Andric }
19850b57cec5SDimitry Andric
198606c3fb27SDimitry Andric if (LangOpts.assumeFunctionsAreConvergent()) {
19870b57cec5SDimitry Andric // Conservatively, mark all functions and calls in CUDA and OpenCL as
19880b57cec5SDimitry Andric // convergent (meaning, they may call an intrinsically convergent op, such
19890b57cec5SDimitry Andric // as __syncthreads() / barrier(), and so can't have certain optimizations
19900b57cec5SDimitry Andric // applied around them). LLVM will remove this attribute where it safely
19910b57cec5SDimitry Andric // can.
19920b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::Convergent);
19930b57cec5SDimitry Andric }
19940b57cec5SDimitry Andric
1995bdd1243dSDimitry Andric // TODO: NoUnwind attribute should be added for other GPU modes HIP,
199606c3fb27SDimitry Andric // OpenMP offload. AFAIK, neither of them support exceptions in device code.
199706c3fb27SDimitry Andric if ((LangOpts.CUDA && LangOpts.CUDAIsDevice) || LangOpts.OpenCL ||
199806c3fb27SDimitry Andric LangOpts.SYCLIsDevice) {
19990b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
20000b57cec5SDimitry Andric }
20010b57cec5SDimitry Andric
20020b57cec5SDimitry Andric for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) {
20030b57cec5SDimitry Andric StringRef Var, Value;
20040b57cec5SDimitry Andric std::tie(Var, Value) = Attr.split('=');
20050b57cec5SDimitry Andric FuncAttrs.addAttribute(Var, Value);
20060b57cec5SDimitry Andric }
20070fca6ea1SDimitry Andric
20080fca6ea1SDimitry Andric TargetInfo::BranchProtectionInfo BPI(LangOpts);
200962987288SDimitry Andric TargetCodeGenInfo::initBranchProtectionFnAttributes(BPI, FuncAttrs);
20100b57cec5SDimitry Andric }
20110b57cec5SDimitry Andric
20125f757f3fSDimitry Andric /// Merges `target-features` from \TargetOpts and \F, and sets the result in
20135f757f3fSDimitry Andric /// \FuncAttr
20145f757f3fSDimitry Andric /// * features from \F are always kept
20155f757f3fSDimitry Andric /// * a feature from \TargetOpts is kept if itself and its opposite are absent
20165f757f3fSDimitry Andric /// from \F
20175f757f3fSDimitry Andric static void
overrideFunctionFeaturesWithTargetFeatures(llvm::AttrBuilder & FuncAttr,const llvm::Function & F,const TargetOptions & TargetOpts)20185f757f3fSDimitry Andric overrideFunctionFeaturesWithTargetFeatures(llvm::AttrBuilder &FuncAttr,
20195f757f3fSDimitry Andric const llvm::Function &F,
20205f757f3fSDimitry Andric const TargetOptions &TargetOpts) {
20215f757f3fSDimitry Andric auto FFeatures = F.getFnAttribute("target-features");
20225f757f3fSDimitry Andric
20235f757f3fSDimitry Andric llvm::StringSet<> MergedNames;
20245f757f3fSDimitry Andric SmallVector<StringRef> MergedFeatures;
20255f757f3fSDimitry Andric MergedFeatures.reserve(TargetOpts.Features.size());
20265f757f3fSDimitry Andric
20275f757f3fSDimitry Andric auto AddUnmergedFeatures = [&](auto &&FeatureRange) {
20285f757f3fSDimitry Andric for (StringRef Feature : FeatureRange) {
20295f757f3fSDimitry Andric if (Feature.empty())
20305f757f3fSDimitry Andric continue;
20315f757f3fSDimitry Andric assert(Feature[0] == '+' || Feature[0] == '-');
20325f757f3fSDimitry Andric StringRef Name = Feature.drop_front(1);
20335f757f3fSDimitry Andric bool Merged = !MergedNames.insert(Name).second;
20345f757f3fSDimitry Andric if (!Merged)
20355f757f3fSDimitry Andric MergedFeatures.push_back(Feature);
20365f757f3fSDimitry Andric }
20375f757f3fSDimitry Andric };
20385f757f3fSDimitry Andric
20395f757f3fSDimitry Andric if (FFeatures.isValid())
20405f757f3fSDimitry Andric AddUnmergedFeatures(llvm::split(FFeatures.getValueAsString(), ','));
20415f757f3fSDimitry Andric AddUnmergedFeatures(TargetOpts.Features);
20425f757f3fSDimitry Andric
20435f757f3fSDimitry Andric if (!MergedFeatures.empty()) {
20445f757f3fSDimitry Andric llvm::sort(MergedFeatures);
20455f757f3fSDimitry Andric FuncAttr.addAttribute("target-features", llvm::join(MergedFeatures, ","));
20465f757f3fSDimitry Andric }
20475f757f3fSDimitry Andric }
20485f757f3fSDimitry Andric
mergeDefaultFunctionDefinitionAttributes(llvm::Function & F,const CodeGenOptions & CodeGenOpts,const LangOptions & LangOpts,const TargetOptions & TargetOpts,bool WillInternalize)20495f757f3fSDimitry Andric void CodeGen::mergeDefaultFunctionDefinitionAttributes(
20505f757f3fSDimitry Andric llvm::Function &F, const CodeGenOptions &CodeGenOpts,
205106c3fb27SDimitry Andric const LangOptions &LangOpts, const TargetOptions &TargetOpts,
205206c3fb27SDimitry Andric bool WillInternalize) {
205306c3fb27SDimitry Andric
205406c3fb27SDimitry Andric llvm::AttrBuilder FuncAttrs(F.getContext());
205506c3fb27SDimitry Andric // Here we only extract the options that are relevant compared to the version
205606c3fb27SDimitry Andric // from GetCPUAndFeaturesAttributes.
205706c3fb27SDimitry Andric if (!TargetOpts.CPU.empty())
205806c3fb27SDimitry Andric FuncAttrs.addAttribute("target-cpu", TargetOpts.CPU);
205906c3fb27SDimitry Andric if (!TargetOpts.TuneCPU.empty())
206006c3fb27SDimitry Andric FuncAttrs.addAttribute("tune-cpu", TargetOpts.TuneCPU);
206106c3fb27SDimitry Andric
206206c3fb27SDimitry Andric ::getTrivialDefaultFunctionAttributes(F.getName(), F.hasOptNone(),
206306c3fb27SDimitry Andric CodeGenOpts, LangOpts,
206406c3fb27SDimitry Andric /*AttrOnCallSite=*/false, FuncAttrs);
206506c3fb27SDimitry Andric
206606c3fb27SDimitry Andric if (!WillInternalize && F.isInterposable()) {
206706c3fb27SDimitry Andric // Do not promote "dynamic" denormal-fp-math to this translation unit's
206806c3fb27SDimitry Andric // setting for weak functions that won't be internalized. The user has no
206906c3fb27SDimitry Andric // real control for how builtin bitcode is linked, so we shouldn't assume
207006c3fb27SDimitry Andric // later copies will use a consistent mode.
207106c3fb27SDimitry Andric F.addFnAttrs(FuncAttrs);
207206c3fb27SDimitry Andric return;
207306c3fb27SDimitry Andric }
207406c3fb27SDimitry Andric
207506c3fb27SDimitry Andric llvm::AttributeMask AttrsToRemove;
207606c3fb27SDimitry Andric
207706c3fb27SDimitry Andric llvm::DenormalMode DenormModeToMerge = F.getDenormalModeRaw();
207806c3fb27SDimitry Andric llvm::DenormalMode DenormModeToMergeF32 = F.getDenormalModeF32Raw();
207906c3fb27SDimitry Andric llvm::DenormalMode Merged =
208006c3fb27SDimitry Andric CodeGenOpts.FPDenormalMode.mergeCalleeMode(DenormModeToMerge);
208106c3fb27SDimitry Andric llvm::DenormalMode MergedF32 = CodeGenOpts.FP32DenormalMode;
208206c3fb27SDimitry Andric
208306c3fb27SDimitry Andric if (DenormModeToMergeF32.isValid()) {
208406c3fb27SDimitry Andric MergedF32 =
208506c3fb27SDimitry Andric CodeGenOpts.FP32DenormalMode.mergeCalleeMode(DenormModeToMergeF32);
208606c3fb27SDimitry Andric }
208706c3fb27SDimitry Andric
208806c3fb27SDimitry Andric if (Merged == llvm::DenormalMode::getDefault()) {
208906c3fb27SDimitry Andric AttrsToRemove.addAttribute("denormal-fp-math");
209006c3fb27SDimitry Andric } else if (Merged != DenormModeToMerge) {
209106c3fb27SDimitry Andric // Overwrite existing attribute
209206c3fb27SDimitry Andric FuncAttrs.addAttribute("denormal-fp-math",
209306c3fb27SDimitry Andric CodeGenOpts.FPDenormalMode.str());
209406c3fb27SDimitry Andric }
209506c3fb27SDimitry Andric
209606c3fb27SDimitry Andric if (MergedF32 == llvm::DenormalMode::getDefault()) {
209706c3fb27SDimitry Andric AttrsToRemove.addAttribute("denormal-fp-math-f32");
209806c3fb27SDimitry Andric } else if (MergedF32 != DenormModeToMergeF32) {
209906c3fb27SDimitry Andric // Overwrite existing attribute
210006c3fb27SDimitry Andric FuncAttrs.addAttribute("denormal-fp-math-f32",
210106c3fb27SDimitry Andric CodeGenOpts.FP32DenormalMode.str());
210206c3fb27SDimitry Andric }
210306c3fb27SDimitry Andric
210406c3fb27SDimitry Andric F.removeFnAttrs(AttrsToRemove);
210506c3fb27SDimitry Andric addDenormalModeAttrs(Merged, MergedF32, FuncAttrs);
21065f757f3fSDimitry Andric
21075f757f3fSDimitry Andric overrideFunctionFeaturesWithTargetFeatures(FuncAttrs, F, TargetOpts);
21085f757f3fSDimitry Andric
210906c3fb27SDimitry Andric F.addFnAttrs(FuncAttrs);
211006c3fb27SDimitry Andric }
211106c3fb27SDimitry Andric
getTrivialDefaultFunctionAttributes(StringRef Name,bool HasOptnone,bool AttrOnCallSite,llvm::AttrBuilder & FuncAttrs)211206c3fb27SDimitry Andric void CodeGenModule::getTrivialDefaultFunctionAttributes(
211306c3fb27SDimitry Andric StringRef Name, bool HasOptnone, bool AttrOnCallSite,
211406c3fb27SDimitry Andric llvm::AttrBuilder &FuncAttrs) {
211506c3fb27SDimitry Andric ::getTrivialDefaultFunctionAttributes(Name, HasOptnone, getCodeGenOpts(),
211606c3fb27SDimitry Andric getLangOpts(), AttrOnCallSite,
211706c3fb27SDimitry Andric FuncAttrs);
211806c3fb27SDimitry Andric }
211906c3fb27SDimitry Andric
getDefaultFunctionAttributes(StringRef Name,bool HasOptnone,bool AttrOnCallSite,llvm::AttrBuilder & FuncAttrs)212006c3fb27SDimitry Andric void CodeGenModule::getDefaultFunctionAttributes(StringRef Name,
212106c3fb27SDimitry Andric bool HasOptnone,
212206c3fb27SDimitry Andric bool AttrOnCallSite,
212306c3fb27SDimitry Andric llvm::AttrBuilder &FuncAttrs) {
212406c3fb27SDimitry Andric getTrivialDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite,
212506c3fb27SDimitry Andric FuncAttrs);
212606c3fb27SDimitry Andric // If we're just getting the default, get the default values for mergeable
212706c3fb27SDimitry Andric // attributes.
212806c3fb27SDimitry Andric if (!AttrOnCallSite)
212906c3fb27SDimitry Andric addMergableDefaultFunctionAttributes(CodeGenOpts, FuncAttrs);
213006c3fb27SDimitry Andric }
213106c3fb27SDimitry Andric
addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder & attrs)21325ffd83dbSDimitry Andric void CodeGenModule::addDefaultFunctionDefinitionAttributes(
21335ffd83dbSDimitry Andric llvm::AttrBuilder &attrs) {
21345ffd83dbSDimitry Andric getDefaultFunctionAttributes(/*function name*/ "", /*optnone*/ false,
21355ffd83dbSDimitry Andric /*for call*/ false, attrs);
21365ffd83dbSDimitry Andric GetCPUAndFeaturesAttributes(GlobalDecl(), attrs);
21375ffd83dbSDimitry Andric }
21385ffd83dbSDimitry Andric
addNoBuiltinAttributes(llvm::AttrBuilder & FuncAttrs,const LangOptions & LangOpts,const NoBuiltinAttr * NBA=nullptr)21395ffd83dbSDimitry Andric static void addNoBuiltinAttributes(llvm::AttrBuilder &FuncAttrs,
21405ffd83dbSDimitry Andric const LangOptions &LangOpts,
21415ffd83dbSDimitry Andric const NoBuiltinAttr *NBA = nullptr) {
21425ffd83dbSDimitry Andric auto AddNoBuiltinAttr = [&FuncAttrs](StringRef BuiltinName) {
21435ffd83dbSDimitry Andric SmallString<32> AttributeName;
21445ffd83dbSDimitry Andric AttributeName += "no-builtin-";
21455ffd83dbSDimitry Andric AttributeName += BuiltinName;
21465ffd83dbSDimitry Andric FuncAttrs.addAttribute(AttributeName);
21475ffd83dbSDimitry Andric };
21485ffd83dbSDimitry Andric
21495ffd83dbSDimitry Andric // First, handle the language options passed through -fno-builtin.
21505ffd83dbSDimitry Andric if (LangOpts.NoBuiltin) {
21515ffd83dbSDimitry Andric // -fno-builtin disables them all.
21525ffd83dbSDimitry Andric FuncAttrs.addAttribute("no-builtins");
21535ffd83dbSDimitry Andric return;
21545ffd83dbSDimitry Andric }
21555ffd83dbSDimitry Andric
21565ffd83dbSDimitry Andric // Then, add attributes for builtins specified through -fno-builtin-<name>.
21575ffd83dbSDimitry Andric llvm::for_each(LangOpts.NoBuiltinFuncs, AddNoBuiltinAttr);
21585ffd83dbSDimitry Andric
21595ffd83dbSDimitry Andric // Now, let's check the __attribute__((no_builtin("...")) attribute added to
21605ffd83dbSDimitry Andric // the source.
21615ffd83dbSDimitry Andric if (!NBA)
21625ffd83dbSDimitry Andric return;
21635ffd83dbSDimitry Andric
21645ffd83dbSDimitry Andric // If there is a wildcard in the builtin names specified through the
21655ffd83dbSDimitry Andric // attribute, disable them all.
21665ffd83dbSDimitry Andric if (llvm::is_contained(NBA->builtinNames(), "*")) {
21675ffd83dbSDimitry Andric FuncAttrs.addAttribute("no-builtins");
21685ffd83dbSDimitry Andric return;
21695ffd83dbSDimitry Andric }
21705ffd83dbSDimitry Andric
21715ffd83dbSDimitry Andric // And last, add the rest of the builtin names.
21725ffd83dbSDimitry Andric llvm::for_each(NBA->builtinNames(), AddNoBuiltinAttr);
21735ffd83dbSDimitry Andric }
21745ffd83dbSDimitry Andric
DetermineNoUndef(QualType QTy,CodeGenTypes & Types,const llvm::DataLayout & DL,const ABIArgInfo & AI,bool CheckCoerce=true)2175fe6060f1SDimitry Andric static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types,
2176fe6060f1SDimitry Andric const llvm::DataLayout &DL, const ABIArgInfo &AI,
2177fe6060f1SDimitry Andric bool CheckCoerce = true) {
2178fe6060f1SDimitry Andric llvm::Type *Ty = Types.ConvertTypeForMem(QTy);
21795f757f3fSDimitry Andric if (AI.getKind() == ABIArgInfo::Indirect ||
21805f757f3fSDimitry Andric AI.getKind() == ABIArgInfo::IndirectAliased)
2181fe6060f1SDimitry Andric return true;
2182fe6060f1SDimitry Andric if (AI.getKind() == ABIArgInfo::Extend)
2183fe6060f1SDimitry Andric return true;
2184fe6060f1SDimitry Andric if (!DL.typeSizeEqualsStoreSize(Ty))
2185fe6060f1SDimitry Andric // TODO: This will result in a modest amount of values not marked noundef
2186fe6060f1SDimitry Andric // when they could be. We care about values that *invisibly* contain undef
2187fe6060f1SDimitry Andric // bits from the perspective of LLVM IR.
2188fe6060f1SDimitry Andric return false;
2189fe6060f1SDimitry Andric if (CheckCoerce && AI.canHaveCoerceToType()) {
2190fe6060f1SDimitry Andric llvm::Type *CoerceTy = AI.getCoerceToType();
2191fe6060f1SDimitry Andric if (llvm::TypeSize::isKnownGT(DL.getTypeSizeInBits(CoerceTy),
2192fe6060f1SDimitry Andric DL.getTypeSizeInBits(Ty)))
2193fe6060f1SDimitry Andric // If we're coercing to a type with a greater size than the canonical one,
2194fe6060f1SDimitry Andric // we're introducing new undef bits.
2195fe6060f1SDimitry Andric // Coercing to a type of smaller or equal size is ok, as we know that
2196fe6060f1SDimitry Andric // there's no internal padding (typeSizeEqualsStoreSize).
2197fe6060f1SDimitry Andric return false;
2198fe6060f1SDimitry Andric }
21990eae32dcSDimitry Andric if (QTy->isBitIntType())
2200fe6060f1SDimitry Andric return true;
2201fe6060f1SDimitry Andric if (QTy->isReferenceType())
2202fe6060f1SDimitry Andric return true;
2203fe6060f1SDimitry Andric if (QTy->isNullPtrType())
2204fe6060f1SDimitry Andric return false;
2205fe6060f1SDimitry Andric if (QTy->isMemberPointerType())
2206fe6060f1SDimitry Andric // TODO: Some member pointers are `noundef`, but it depends on the ABI. For
2207fe6060f1SDimitry Andric // now, never mark them.
2208fe6060f1SDimitry Andric return false;
2209fe6060f1SDimitry Andric if (QTy->isScalarType()) {
2210fe6060f1SDimitry Andric if (const ComplexType *Complex = dyn_cast<ComplexType>(QTy))
2211fe6060f1SDimitry Andric return DetermineNoUndef(Complex->getElementType(), Types, DL, AI, false);
2212fe6060f1SDimitry Andric return true;
2213fe6060f1SDimitry Andric }
2214fe6060f1SDimitry Andric if (const VectorType *Vector = dyn_cast<VectorType>(QTy))
2215fe6060f1SDimitry Andric return DetermineNoUndef(Vector->getElementType(), Types, DL, AI, false);
2216fe6060f1SDimitry Andric if (const MatrixType *Matrix = dyn_cast<MatrixType>(QTy))
2217fe6060f1SDimitry Andric return DetermineNoUndef(Matrix->getElementType(), Types, DL, AI, false);
2218fe6060f1SDimitry Andric if (const ArrayType *Array = dyn_cast<ArrayType>(QTy))
2219fe6060f1SDimitry Andric return DetermineNoUndef(Array->getElementType(), Types, DL, AI, false);
2220fe6060f1SDimitry Andric
2221fe6060f1SDimitry Andric // TODO: Some structs may be `noundef`, in specific situations.
2222fe6060f1SDimitry Andric return false;
2223fe6060f1SDimitry Andric }
2224fe6060f1SDimitry Andric
2225bdd1243dSDimitry Andric /// Check if the argument of a function has maybe_undef attribute.
IsArgumentMaybeUndef(const Decl * TargetDecl,unsigned NumRequiredArgs,unsigned ArgNo)2226bdd1243dSDimitry Andric static bool IsArgumentMaybeUndef(const Decl *TargetDecl,
2227bdd1243dSDimitry Andric unsigned NumRequiredArgs, unsigned ArgNo) {
2228bdd1243dSDimitry Andric const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2229bdd1243dSDimitry Andric if (!FD)
2230bdd1243dSDimitry Andric return false;
2231bdd1243dSDimitry Andric
2232bdd1243dSDimitry Andric // Assume variadic arguments do not have maybe_undef attribute.
2233bdd1243dSDimitry Andric if (ArgNo >= NumRequiredArgs)
2234bdd1243dSDimitry Andric return false;
2235bdd1243dSDimitry Andric
2236bdd1243dSDimitry Andric // Check if argument has maybe_undef attribute.
2237bdd1243dSDimitry Andric if (ArgNo < FD->getNumParams()) {
2238bdd1243dSDimitry Andric const ParmVarDecl *Param = FD->getParamDecl(ArgNo);
2239bdd1243dSDimitry Andric if (Param && Param->hasAttr<MaybeUndefAttr>())
2240bdd1243dSDimitry Andric return true;
2241bdd1243dSDimitry Andric }
2242bdd1243dSDimitry Andric
2243bdd1243dSDimitry Andric return false;
2244bdd1243dSDimitry Andric }
2245bdd1243dSDimitry Andric
224606c3fb27SDimitry Andric /// Test if it's legal to apply nofpclass for the given parameter type and it's
224706c3fb27SDimitry Andric /// lowered IR type.
canApplyNoFPClass(const ABIArgInfo & AI,QualType ParamType,bool IsReturn)224806c3fb27SDimitry Andric static bool canApplyNoFPClass(const ABIArgInfo &AI, QualType ParamType,
224906c3fb27SDimitry Andric bool IsReturn) {
225006c3fb27SDimitry Andric // Should only apply to FP types in the source, not ABI promoted.
225106c3fb27SDimitry Andric if (!ParamType->hasFloatingRepresentation())
225206c3fb27SDimitry Andric return false;
225306c3fb27SDimitry Andric
225406c3fb27SDimitry Andric // The promoted-to IR type also needs to support nofpclass.
225506c3fb27SDimitry Andric llvm::Type *IRTy = AI.getCoerceToType();
225606c3fb27SDimitry Andric if (llvm::AttributeFuncs::isNoFPClassCompatibleType(IRTy))
225706c3fb27SDimitry Andric return true;
225806c3fb27SDimitry Andric
225906c3fb27SDimitry Andric if (llvm::StructType *ST = dyn_cast<llvm::StructType>(IRTy)) {
226006c3fb27SDimitry Andric return !IsReturn && AI.getCanBeFlattened() &&
226106c3fb27SDimitry Andric llvm::all_of(ST->elements(), [](llvm::Type *Ty) {
226206c3fb27SDimitry Andric return llvm::AttributeFuncs::isNoFPClassCompatibleType(Ty);
226306c3fb27SDimitry Andric });
226406c3fb27SDimitry Andric }
226506c3fb27SDimitry Andric
226606c3fb27SDimitry Andric return false;
226706c3fb27SDimitry Andric }
226806c3fb27SDimitry Andric
226906c3fb27SDimitry Andric /// Return the nofpclass mask that can be applied to floating-point parameters.
getNoFPClassTestMask(const LangOptions & LangOpts)227006c3fb27SDimitry Andric static llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts) {
227106c3fb27SDimitry Andric llvm::FPClassTest Mask = llvm::fcNone;
227206c3fb27SDimitry Andric if (LangOpts.NoHonorInfs)
227306c3fb27SDimitry Andric Mask |= llvm::fcInf;
227406c3fb27SDimitry Andric if (LangOpts.NoHonorNaNs)
227506c3fb27SDimitry Andric Mask |= llvm::fcNan;
227606c3fb27SDimitry Andric return Mask;
227706c3fb27SDimitry Andric }
227806c3fb27SDimitry Andric
AdjustMemoryAttribute(StringRef Name,CGCalleeInfo CalleeInfo,llvm::AttributeList & Attrs)22795f757f3fSDimitry Andric void CodeGenModule::AdjustMemoryAttribute(StringRef Name,
22805f757f3fSDimitry Andric CGCalleeInfo CalleeInfo,
22815f757f3fSDimitry Andric llvm::AttributeList &Attrs) {
22825f757f3fSDimitry Andric if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
22835f757f3fSDimitry Andric Attrs = Attrs.removeFnAttribute(getLLVMContext(), llvm::Attribute::Memory);
22845f757f3fSDimitry Andric llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
22855f757f3fSDimitry Andric getLLVMContext(), llvm::MemoryEffects::writeOnly());
22865f757f3fSDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), MemoryAttr);
22875f757f3fSDimitry Andric }
22885f757f3fSDimitry Andric }
22895f757f3fSDimitry Andric
22905ffd83dbSDimitry Andric /// Construct the IR attribute list of a function or call.
22915ffd83dbSDimitry Andric ///
22925ffd83dbSDimitry Andric /// When adding an attribute, please consider where it should be handled:
22935ffd83dbSDimitry Andric ///
22945ffd83dbSDimitry Andric /// - getDefaultFunctionAttributes is for attributes that are essentially
22955ffd83dbSDimitry Andric /// part of the global target configuration (but perhaps can be
22965ffd83dbSDimitry Andric /// overridden on a per-function basis). Adding attributes there
22975ffd83dbSDimitry Andric /// will cause them to also be set in frontends that build on Clang's
22985ffd83dbSDimitry Andric /// target-configuration logic, as well as for code defined in library
22995ffd83dbSDimitry Andric /// modules such as CUDA's libdevice.
23005ffd83dbSDimitry Andric ///
23015ffd83dbSDimitry Andric /// - ConstructAttributeList builds on top of getDefaultFunctionAttributes
23025ffd83dbSDimitry Andric /// and adds declaration-specific, convention-specific, and
23035ffd83dbSDimitry Andric /// frontend-specific logic. The last is of particular importance:
23045ffd83dbSDimitry Andric /// attributes that restrict how the frontend generates code must be
23055ffd83dbSDimitry Andric /// added here rather than getDefaultFunctionAttributes.
23065ffd83dbSDimitry Andric ///
ConstructAttributeList(StringRef Name,const CGFunctionInfo & FI,CGCalleeInfo CalleeInfo,llvm::AttributeList & AttrList,unsigned & CallingConv,bool AttrOnCallSite,bool IsThunk)2307fe6060f1SDimitry Andric void CodeGenModule::ConstructAttributeList(StringRef Name,
2308fe6060f1SDimitry Andric const CGFunctionInfo &FI,
2309fe6060f1SDimitry Andric CGCalleeInfo CalleeInfo,
2310fe6060f1SDimitry Andric llvm::AttributeList &AttrList,
2311fe6060f1SDimitry Andric unsigned &CallingConv,
2312fe6060f1SDimitry Andric bool AttrOnCallSite, bool IsThunk) {
231304eeddc0SDimitry Andric llvm::AttrBuilder FuncAttrs(getLLVMContext());
231404eeddc0SDimitry Andric llvm::AttrBuilder RetAttrs(getLLVMContext());
23150b57cec5SDimitry Andric
23165ffd83dbSDimitry Andric // Collect function IR attributes from the CC lowering.
23175ffd83dbSDimitry Andric // We'll collect the paramete and result attributes later.
23180b57cec5SDimitry Andric CallingConv = FI.getEffectiveCallingConvention();
23190b57cec5SDimitry Andric if (FI.isNoReturn())
23200b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
23215ffd83dbSDimitry Andric if (FI.isCmseNSCall())
23225ffd83dbSDimitry Andric FuncAttrs.addAttribute("cmse_nonsecure_call");
23230b57cec5SDimitry Andric
23245ffd83dbSDimitry Andric // Collect function IR attributes from the callee prototype if we have one.
23250b57cec5SDimitry Andric AddAttributesFromFunctionProtoType(getContext(), FuncAttrs,
23260b57cec5SDimitry Andric CalleeInfo.getCalleeFunctionProtoType());
23270b57cec5SDimitry Andric
23280b57cec5SDimitry Andric const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl();
23290b57cec5SDimitry Andric
2330349cc55cSDimitry Andric // Attach assumption attributes to the declaration. If this is a call
2331349cc55cSDimitry Andric // site, attach assumptions from the caller to the call as well.
23320fca6ea1SDimitry Andric AddAttributesFromOMPAssumes(FuncAttrs, TargetDecl);
2333349cc55cSDimitry Andric
23340b57cec5SDimitry Andric bool HasOptnone = false;
23355ffd83dbSDimitry Andric // The NoBuiltinAttr attached to the target FunctionDecl.
23365ffd83dbSDimitry Andric const NoBuiltinAttr *NBA = nullptr;
23375ffd83dbSDimitry Andric
2338bdd1243dSDimitry Andric // Some ABIs may result in additional accesses to arguments that may
2339bdd1243dSDimitry Andric // otherwise not be present.
2340bdd1243dSDimitry Andric auto AddPotentialArgAccess = [&]() {
2341bdd1243dSDimitry Andric llvm::Attribute A = FuncAttrs.getAttribute(llvm::Attribute::Memory);
2342bdd1243dSDimitry Andric if (A.isValid())
2343bdd1243dSDimitry Andric FuncAttrs.addMemoryAttr(A.getMemoryEffects() |
2344bdd1243dSDimitry Andric llvm::MemoryEffects::argMemOnly());
2345bdd1243dSDimitry Andric };
2346bdd1243dSDimitry Andric
23475ffd83dbSDimitry Andric // Collect function IR attributes based on declaration-specific
23485ffd83dbSDimitry Andric // information.
23490b57cec5SDimitry Andric // FIXME: handle sseregparm someday...
23500b57cec5SDimitry Andric if (TargetDecl) {
23510b57cec5SDimitry Andric if (TargetDecl->hasAttr<ReturnsTwiceAttr>())
23520b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::ReturnsTwice);
23530b57cec5SDimitry Andric if (TargetDecl->hasAttr<NoThrowAttr>())
23540b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
23550b57cec5SDimitry Andric if (TargetDecl->hasAttr<NoReturnAttr>())
23560b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
23570b57cec5SDimitry Andric if (TargetDecl->hasAttr<ColdAttr>())
23580b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::Cold);
2359e8d8bef9SDimitry Andric if (TargetDecl->hasAttr<HotAttr>())
2360e8d8bef9SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::Hot);
23610b57cec5SDimitry Andric if (TargetDecl->hasAttr<NoDuplicateAttr>())
23620b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate);
23630b57cec5SDimitry Andric if (TargetDecl->hasAttr<ConvergentAttr>())
23640b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::Convergent);
23650b57cec5SDimitry Andric
23660b57cec5SDimitry Andric if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
23670b57cec5SDimitry Andric AddAttributesFromFunctionProtoType(
23680b57cec5SDimitry Andric getContext(), FuncAttrs, Fn->getType()->getAs<FunctionProtoType>());
23695ffd83dbSDimitry Andric if (AttrOnCallSite && Fn->isReplaceableGlobalAllocationFunction()) {
23705ffd83dbSDimitry Andric // A sane operator new returns a non-aliasing pointer.
23715ffd83dbSDimitry Andric auto Kind = Fn->getDeclName().getCXXOverloadedOperator();
23725ffd83dbSDimitry Andric if (getCodeGenOpts().AssumeSaneOperatorNew &&
23735ffd83dbSDimitry Andric (Kind == OO_New || Kind == OO_Array_New))
23745ffd83dbSDimitry Andric RetAttrs.addAttribute(llvm::Attribute::NoAlias);
23755ffd83dbSDimitry Andric }
23760b57cec5SDimitry Andric const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Fn);
2377480093f4SDimitry Andric const bool IsVirtualCall = MD && MD->isVirtual();
2378480093f4SDimitry Andric // Don't use [[noreturn]], _Noreturn or [[no_builtin]] for a call to a
2379480093f4SDimitry Andric // virtual function. These attributes are not inherited by overloads.
2380480093f4SDimitry Andric if (!(AttrOnCallSite && IsVirtualCall)) {
2381480093f4SDimitry Andric if (Fn->isNoReturn())
23820b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
23835ffd83dbSDimitry Andric NBA = Fn->getAttr<NoBuiltinAttr>();
2384480093f4SDimitry Andric }
238506c3fb27SDimitry Andric }
238606c3fb27SDimitry Andric
238706c3fb27SDimitry Andric if (isa<FunctionDecl>(TargetDecl) || isa<VarDecl>(TargetDecl)) {
2388e8d8bef9SDimitry Andric // Only place nomerge attribute on call sites, never functions. This
2389e8d8bef9SDimitry Andric // allows it to work on indirect virtual function calls.
2390e8d8bef9SDimitry Andric if (AttrOnCallSite && TargetDecl->hasAttr<NoMergeAttr>())
2391e8d8bef9SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoMerge);
23920b57cec5SDimitry Andric }
23930b57cec5SDimitry Andric
23940b57cec5SDimitry Andric // 'const', 'pure' and 'noalias' attributed functions are also nounwind.
23950b57cec5SDimitry Andric if (TargetDecl->hasAttr<ConstAttr>()) {
2396bdd1243dSDimitry Andric FuncAttrs.addMemoryAttr(llvm::MemoryEffects::none());
23970b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2398d409305fSDimitry Andric // gcc specifies that 'const' functions have greater restrictions than
2399d409305fSDimitry Andric // 'pure' functions, so they also cannot have infinite loops.
2400d409305fSDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
24010b57cec5SDimitry Andric } else if (TargetDecl->hasAttr<PureAttr>()) {
2402bdd1243dSDimitry Andric FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
24030b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
2404d409305fSDimitry Andric // gcc specifies that 'pure' functions cannot have infinite loops.
2405d409305fSDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
24060b57cec5SDimitry Andric } else if (TargetDecl->hasAttr<NoAliasAttr>()) {
24075f757f3fSDimitry Andric FuncAttrs.addMemoryAttr(llvm::MemoryEffects::inaccessibleOrArgMemOnly());
24080b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
24090b57cec5SDimitry Andric }
24100b57cec5SDimitry Andric if (TargetDecl->hasAttr<RestrictAttr>())
24110b57cec5SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::NoAlias);
24120b57cec5SDimitry Andric if (TargetDecl->hasAttr<ReturnsNonNullAttr>() &&
24130b57cec5SDimitry Andric !CodeGenOpts.NullPointerIsValid)
24140b57cec5SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::NonNull);
24150b57cec5SDimitry Andric if (TargetDecl->hasAttr<AnyX86NoCallerSavedRegistersAttr>())
24160b57cec5SDimitry Andric FuncAttrs.addAttribute("no_caller_saved_registers");
24170b57cec5SDimitry Andric if (TargetDecl->hasAttr<AnyX86NoCfCheckAttr>())
24180b57cec5SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoCfCheck);
2419e8d8bef9SDimitry Andric if (TargetDecl->hasAttr<LeafAttr>())
2420e8d8bef9SDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NoCallback);
24210b57cec5SDimitry Andric
24220b57cec5SDimitry Andric HasOptnone = TargetDecl->hasAttr<OptimizeNoneAttr>();
24230b57cec5SDimitry Andric if (auto *AllocSize = TargetDecl->getAttr<AllocSizeAttr>()) {
2424bdd1243dSDimitry Andric std::optional<unsigned> NumElemsParam;
24250b57cec5SDimitry Andric if (AllocSize->getNumElemsParam().isValid())
24260b57cec5SDimitry Andric NumElemsParam = AllocSize->getNumElemsParam().getLLVMIndex();
24270b57cec5SDimitry Andric FuncAttrs.addAllocSizeAttr(AllocSize->getElemSizeParam().getLLVMIndex(),
24280b57cec5SDimitry Andric NumElemsParam);
24290b57cec5SDimitry Andric }
24300b57cec5SDimitry Andric
24315ffd83dbSDimitry Andric if (TargetDecl->hasAttr<OpenCLKernelAttr>()) {
24320b57cec5SDimitry Andric if (getLangOpts().OpenCLVersion <= 120) {
24330b57cec5SDimitry Andric // OpenCL v1.2 Work groups are always uniform
24340b57cec5SDimitry Andric FuncAttrs.addAttribute("uniform-work-group-size", "true");
24350b57cec5SDimitry Andric } else {
24360b57cec5SDimitry Andric // OpenCL v2.0 Work groups may be whether uniform or not.
24370b57cec5SDimitry Andric // '-cl-uniform-work-group-size' compile option gets a hint
24380b57cec5SDimitry Andric // to the compiler that the global work-size be a multiple of
24390b57cec5SDimitry Andric // the work-group size specified to clEnqueueNDRangeKernel
24400b57cec5SDimitry Andric // (i.e. work groups are uniform).
24415f757f3fSDimitry Andric FuncAttrs.addAttribute(
24425f757f3fSDimitry Andric "uniform-work-group-size",
24435f757f3fSDimitry Andric llvm::toStringRef(getLangOpts().OffloadUniformBlock));
24440b57cec5SDimitry Andric }
24450b57cec5SDimitry Andric }
24465f757f3fSDimitry Andric
24475f757f3fSDimitry Andric if (TargetDecl->hasAttr<CUDAGlobalAttr>() &&
24485f757f3fSDimitry Andric getLangOpts().OffloadUniformBlock)
24495f757f3fSDimitry Andric FuncAttrs.addAttribute("uniform-work-group-size", "true");
24505f757f3fSDimitry Andric
24515f757f3fSDimitry Andric if (TargetDecl->hasAttr<ArmLocallyStreamingAttr>())
24525f757f3fSDimitry Andric FuncAttrs.addAttribute("aarch64_pstate_sm_body");
24535ffd83dbSDimitry Andric }
24540b57cec5SDimitry Andric
24555ffd83dbSDimitry Andric // Attach "no-builtins" attributes to:
24565ffd83dbSDimitry Andric // * call sites: both `nobuiltin` and "no-builtins" or "no-builtin-<name>".
24575ffd83dbSDimitry Andric // * definitions: "no-builtins" or "no-builtin-<name>" only.
24585ffd83dbSDimitry Andric // The attributes can come from:
24595ffd83dbSDimitry Andric // * LangOpts: -ffreestanding, -fno-builtin, -fno-builtin-<name>
24605ffd83dbSDimitry Andric // * FunctionDecl attributes: __attribute__((no_builtin(...)))
24615ffd83dbSDimitry Andric addNoBuiltinAttributes(FuncAttrs, getLangOpts(), NBA);
24625ffd83dbSDimitry Andric
24635ffd83dbSDimitry Andric // Collect function IR attributes based on global settiings.
24645ffd83dbSDimitry Andric getDefaultFunctionAttributes(Name, HasOptnone, AttrOnCallSite, FuncAttrs);
24655ffd83dbSDimitry Andric
24665ffd83dbSDimitry Andric // Override some default IR attributes based on declaration-specific
24675ffd83dbSDimitry Andric // information.
24685ffd83dbSDimitry Andric if (TargetDecl) {
24695ffd83dbSDimitry Andric if (TargetDecl->hasAttr<NoSpeculativeLoadHardeningAttr>())
24705ffd83dbSDimitry Andric FuncAttrs.removeAttribute(llvm::Attribute::SpeculativeLoadHardening);
24715ffd83dbSDimitry Andric if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>())
24725ffd83dbSDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening);
24735ffd83dbSDimitry Andric if (TargetDecl->hasAttr<NoSplitStackAttr>())
24745ffd83dbSDimitry Andric FuncAttrs.removeAttribute("split-stack");
247581ad6265SDimitry Andric if (TargetDecl->hasAttr<ZeroCallUsedRegsAttr>()) {
247681ad6265SDimitry Andric // A function "__attribute__((...))" overrides the command-line flag.
247781ad6265SDimitry Andric auto Kind =
247881ad6265SDimitry Andric TargetDecl->getAttr<ZeroCallUsedRegsAttr>()->getZeroCallUsedRegs();
247981ad6265SDimitry Andric FuncAttrs.removeAttribute("zero-call-used-regs");
248081ad6265SDimitry Andric FuncAttrs.addAttribute(
248181ad6265SDimitry Andric "zero-call-used-regs",
248281ad6265SDimitry Andric ZeroCallUsedRegsAttr::ConvertZeroCallUsedRegsKindToStr(Kind));
248381ad6265SDimitry Andric }
24845ffd83dbSDimitry Andric
24855ffd83dbSDimitry Andric // Add NonLazyBind attribute to function declarations when -fno-plt
24865ffd83dbSDimitry Andric // is used.
24875ffd83dbSDimitry Andric // FIXME: what if we just haven't processed the function definition
24885ffd83dbSDimitry Andric // yet, or if it's an external definition like C99 inline?
24895ffd83dbSDimitry Andric if (CodeGenOpts.NoPLT) {
24905ffd83dbSDimitry Andric if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) {
24915ffd83dbSDimitry Andric if (!Fn->isDefined() && !AttrOnCallSite) {
24925ffd83dbSDimitry Andric FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind);
24935ffd83dbSDimitry Andric }
24945ffd83dbSDimitry Andric }
24955ffd83dbSDimitry Andric }
24965ffd83dbSDimitry Andric }
24975ffd83dbSDimitry Andric
2498fe6060f1SDimitry Andric // Add "sample-profile-suffix-elision-policy" attribute for internal linkage
2499fe6060f1SDimitry Andric // functions with -funique-internal-linkage-names.
2500fe6060f1SDimitry Andric if (TargetDecl && CodeGenOpts.UniqueInternalLinkageNames) {
2501bdd1243dSDimitry Andric if (const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
2502bdd1243dSDimitry Andric if (!FD->isExternallyVisible())
2503fe6060f1SDimitry Andric FuncAttrs.addAttribute("sample-profile-suffix-elision-policy",
2504fe6060f1SDimitry Andric "selected");
2505fe6060f1SDimitry Andric }
2506fe6060f1SDimitry Andric }
2507fe6060f1SDimitry Andric
25085ffd83dbSDimitry Andric // Collect non-call-site function IR attributes from declaration-specific
25095ffd83dbSDimitry Andric // information.
25100b57cec5SDimitry Andric if (!AttrOnCallSite) {
25115ffd83dbSDimitry Andric if (TargetDecl && TargetDecl->hasAttr<CmseNSEntryAttr>())
25125ffd83dbSDimitry Andric FuncAttrs.addAttribute("cmse_nonsecure_entry");
25130b57cec5SDimitry Andric
25145ffd83dbSDimitry Andric // Whether tail calls are enabled.
25155ffd83dbSDimitry Andric auto shouldDisableTailCalls = [&] {
25165ffd83dbSDimitry Andric // Should this be honored in getDefaultFunctionAttributes?
25170b57cec5SDimitry Andric if (CodeGenOpts.DisableTailCalls)
25185ffd83dbSDimitry Andric return true;
25195ffd83dbSDimitry Andric
25205ffd83dbSDimitry Andric if (!TargetDecl)
25215ffd83dbSDimitry Andric return false;
25225ffd83dbSDimitry Andric
25230b57cec5SDimitry Andric if (TargetDecl->hasAttr<DisableTailCallsAttr>() ||
25240b57cec5SDimitry Andric TargetDecl->hasAttr<AnyX86InterruptAttr>())
25255ffd83dbSDimitry Andric return true;
25265ffd83dbSDimitry Andric
25275ffd83dbSDimitry Andric if (CodeGenOpts.NoEscapingBlockTailCalls) {
25280b57cec5SDimitry Andric if (const auto *BD = dyn_cast<BlockDecl>(TargetDecl))
25290b57cec5SDimitry Andric if (!BD->doesNotEscape())
25305ffd83dbSDimitry Andric return true;
25310b57cec5SDimitry Andric }
25320b57cec5SDimitry Andric
25335ffd83dbSDimitry Andric return false;
25345ffd83dbSDimitry Andric };
2535fe6060f1SDimitry Andric if (shouldDisableTailCalls())
2536fe6060f1SDimitry Andric FuncAttrs.addAttribute("disable-tail-calls", "true");
25375ffd83dbSDimitry Andric
25385ffd83dbSDimitry Andric // CPU/feature overrides. addDefaultFunctionDefinitionAttributes
25395ffd83dbSDimitry Andric // handles these separately to set them based on the global defaults.
25400b57cec5SDimitry Andric GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs);
25410b57cec5SDimitry Andric }
25420b57cec5SDimitry Andric
25435ffd83dbSDimitry Andric // Collect attributes from arguments and return values.
25440b57cec5SDimitry Andric ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI);
25450b57cec5SDimitry Andric
25460b57cec5SDimitry Andric QualType RetTy = FI.getReturnType();
25470b57cec5SDimitry Andric const ABIArgInfo &RetAI = FI.getReturnInfo();
2548fe6060f1SDimitry Andric const llvm::DataLayout &DL = getDataLayout();
2549fe6060f1SDimitry Andric
2550fe6060f1SDimitry Andric // Determine if the return type could be partially undef
2551bdd1243dSDimitry Andric if (CodeGenOpts.EnableNoundefAttrs &&
2552bdd1243dSDimitry Andric HasStrictReturn(*this, RetTy, TargetDecl)) {
2553fe6060f1SDimitry Andric if (!RetTy->isVoidType() && RetAI.getKind() != ABIArgInfo::Indirect &&
2554fe6060f1SDimitry Andric DetermineNoUndef(RetTy, getTypes(), DL, RetAI))
2555fe6060f1SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::NoUndef);
2556fe6060f1SDimitry Andric }
2557fe6060f1SDimitry Andric
25580b57cec5SDimitry Andric switch (RetAI.getKind()) {
25590b57cec5SDimitry Andric case ABIArgInfo::Extend:
25600b57cec5SDimitry Andric if (RetAI.isSignExt())
25610b57cec5SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::SExt);
25620b57cec5SDimitry Andric else
25630b57cec5SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::ZExt);
2564bdd1243dSDimitry Andric [[fallthrough]];
25650b57cec5SDimitry Andric case ABIArgInfo::Direct:
25660b57cec5SDimitry Andric if (RetAI.getInReg())
25670b57cec5SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::InReg);
256806c3fb27SDimitry Andric
256906c3fb27SDimitry Andric if (canApplyNoFPClass(RetAI, RetTy, true))
257006c3fb27SDimitry Andric RetAttrs.addNoFPClassAttr(getNoFPClassTestMask(getLangOpts()));
257106c3fb27SDimitry Andric
25720b57cec5SDimitry Andric break;
25730b57cec5SDimitry Andric case ABIArgInfo::Ignore:
25740b57cec5SDimitry Andric break;
25750b57cec5SDimitry Andric
25760b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
25770b57cec5SDimitry Andric case ABIArgInfo::Indirect: {
25780b57cec5SDimitry Andric // inalloca and sret disable readnone and readonly
2579bdd1243dSDimitry Andric AddPotentialArgAccess();
25800b57cec5SDimitry Andric break;
25810b57cec5SDimitry Andric }
25820b57cec5SDimitry Andric
25830b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand:
25840b57cec5SDimitry Andric break;
25850b57cec5SDimitry Andric
25860b57cec5SDimitry Andric case ABIArgInfo::Expand:
2587e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased:
25880b57cec5SDimitry Andric llvm_unreachable("Invalid ABI kind for return argument");
25890b57cec5SDimitry Andric }
25900b57cec5SDimitry Andric
2591fe6060f1SDimitry Andric if (!IsThunk) {
2592fe6060f1SDimitry Andric // FIXME: fix this properly, https://reviews.llvm.org/D100388
25930b57cec5SDimitry Andric if (const auto *RefTy = RetTy->getAs<ReferenceType>()) {
25940b57cec5SDimitry Andric QualType PTy = RefTy->getPointeeType();
25950b57cec5SDimitry Andric if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
25965ffd83dbSDimitry Andric RetAttrs.addDereferenceableAttr(
25975ffd83dbSDimitry Andric getMinimumObjectSize(PTy).getQuantity());
2598bdd1243dSDimitry Andric if (getTypes().getTargetAddressSpace(PTy) == 0 &&
25990b57cec5SDimitry Andric !CodeGenOpts.NullPointerIsValid)
26000b57cec5SDimitry Andric RetAttrs.addAttribute(llvm::Attribute::NonNull);
26015ffd83dbSDimitry Andric if (PTy->isObjectType()) {
26025ffd83dbSDimitry Andric llvm::Align Alignment =
26035ffd83dbSDimitry Andric getNaturalPointeeTypeAlignment(RetTy).getAsAlign();
26045ffd83dbSDimitry Andric RetAttrs.addAlignmentAttr(Alignment);
26055ffd83dbSDimitry Andric }
26060b57cec5SDimitry Andric }
2607fe6060f1SDimitry Andric }
26080b57cec5SDimitry Andric
26090b57cec5SDimitry Andric bool hasUsedSRet = false;
26100b57cec5SDimitry Andric SmallVector<llvm::AttributeSet, 4> ArgAttrs(IRFunctionArgs.totalIRArgs());
26110b57cec5SDimitry Andric
26120b57cec5SDimitry Andric // Attach attributes to sret.
26130b57cec5SDimitry Andric if (IRFunctionArgs.hasSRetArg()) {
261404eeddc0SDimitry Andric llvm::AttrBuilder SRETAttrs(getLLVMContext());
2615e8d8bef9SDimitry Andric SRETAttrs.addStructRetAttr(getTypes().ConvertTypeForMem(RetTy));
2616297eecfbSDimitry Andric SRETAttrs.addAttribute(llvm::Attribute::Writable);
2617297eecfbSDimitry Andric SRETAttrs.addAttribute(llvm::Attribute::DeadOnUnwind);
26180b57cec5SDimitry Andric hasUsedSRet = true;
26190b57cec5SDimitry Andric if (RetAI.getInReg())
26200b57cec5SDimitry Andric SRETAttrs.addAttribute(llvm::Attribute::InReg);
26215ffd83dbSDimitry Andric SRETAttrs.addAlignmentAttr(RetAI.getIndirectAlign().getQuantity());
26220b57cec5SDimitry Andric ArgAttrs[IRFunctionArgs.getSRetArgNo()] =
26230b57cec5SDimitry Andric llvm::AttributeSet::get(getLLVMContext(), SRETAttrs);
26240b57cec5SDimitry Andric }
26250b57cec5SDimitry Andric
26260b57cec5SDimitry Andric // Attach attributes to inalloca argument.
26270b57cec5SDimitry Andric if (IRFunctionArgs.hasInallocaArg()) {
262804eeddc0SDimitry Andric llvm::AttrBuilder Attrs(getLLVMContext());
2629fe6060f1SDimitry Andric Attrs.addInAllocaAttr(FI.getArgStruct());
26300b57cec5SDimitry Andric ArgAttrs[IRFunctionArgs.getInallocaArgNo()] =
26310b57cec5SDimitry Andric llvm::AttributeSet::get(getLLVMContext(), Attrs);
26320b57cec5SDimitry Andric }
26330b57cec5SDimitry Andric
2634fe6060f1SDimitry Andric // Apply `nonnull`, `dereferencable(N)` and `align N` to the `this` argument,
2635fe6060f1SDimitry Andric // unless this is a thunk function.
2636fe6060f1SDimitry Andric // FIXME: fix this properly, https://reviews.llvm.org/D100388
2637e8d8bef9SDimitry Andric if (FI.isInstanceMethod() && !IRFunctionArgs.hasInallocaArg() &&
2638fe6060f1SDimitry Andric !FI.arg_begin()->type->isVoidPointerType() && !IsThunk) {
2639e8d8bef9SDimitry Andric auto IRArgs = IRFunctionArgs.getIRArgs(0);
2640e8d8bef9SDimitry Andric
2641e8d8bef9SDimitry Andric assert(IRArgs.second == 1 && "Expected only a single `this` pointer.");
2642e8d8bef9SDimitry Andric
264304eeddc0SDimitry Andric llvm::AttrBuilder Attrs(getLLVMContext());
2644e8d8bef9SDimitry Andric
2645fe6060f1SDimitry Andric QualType ThisTy =
26465f757f3fSDimitry Andric FI.arg_begin()->type.getTypePtr()->getPointeeType();
2647fe6060f1SDimitry Andric
2648e8d8bef9SDimitry Andric if (!CodeGenOpts.NullPointerIsValid &&
2649bdd1243dSDimitry Andric getTypes().getTargetAddressSpace(FI.arg_begin()->type) == 0) {
2650e8d8bef9SDimitry Andric Attrs.addAttribute(llvm::Attribute::NonNull);
2651fe6060f1SDimitry Andric Attrs.addDereferenceableAttr(getMinimumObjectSize(ThisTy).getQuantity());
2652e8d8bef9SDimitry Andric } else {
2653e8d8bef9SDimitry Andric // FIXME dereferenceable should be correct here, regardless of
2654e8d8bef9SDimitry Andric // NullPointerIsValid. However, dereferenceable currently does not always
2655e8d8bef9SDimitry Andric // respect NullPointerIsValid and may imply nonnull and break the program.
2656e8d8bef9SDimitry Andric // See https://reviews.llvm.org/D66618 for discussions.
2657e8d8bef9SDimitry Andric Attrs.addDereferenceableOrNullAttr(
2658e8d8bef9SDimitry Andric getMinimumObjectSize(
2659e8d8bef9SDimitry Andric FI.arg_begin()->type.castAs<PointerType>()->getPointeeType())
2660e8d8bef9SDimitry Andric .getQuantity());
2661e8d8bef9SDimitry Andric }
2662e8d8bef9SDimitry Andric
2663fe6060f1SDimitry Andric llvm::Align Alignment =
2664fe6060f1SDimitry Andric getNaturalTypeAlignment(ThisTy, /*BaseInfo=*/nullptr,
2665fe6060f1SDimitry Andric /*TBAAInfo=*/nullptr, /*forPointeeType=*/true)
2666fe6060f1SDimitry Andric .getAsAlign();
2667fe6060f1SDimitry Andric Attrs.addAlignmentAttr(Alignment);
2668fe6060f1SDimitry Andric
2669e8d8bef9SDimitry Andric ArgAttrs[IRArgs.first] = llvm::AttributeSet::get(getLLVMContext(), Attrs);
2670e8d8bef9SDimitry Andric }
2671e8d8bef9SDimitry Andric
26720b57cec5SDimitry Andric unsigned ArgNo = 0;
26730b57cec5SDimitry Andric for (CGFunctionInfo::const_arg_iterator I = FI.arg_begin(),
26740b57cec5SDimitry Andric E = FI.arg_end();
26750b57cec5SDimitry Andric I != E; ++I, ++ArgNo) {
26760b57cec5SDimitry Andric QualType ParamType = I->type;
26770b57cec5SDimitry Andric const ABIArgInfo &AI = I->info;
267804eeddc0SDimitry Andric llvm::AttrBuilder Attrs(getLLVMContext());
26790b57cec5SDimitry Andric
26800b57cec5SDimitry Andric // Add attribute for padding argument, if necessary.
26810b57cec5SDimitry Andric if (IRFunctionArgs.hasPaddingArg(ArgNo)) {
26820b57cec5SDimitry Andric if (AI.getPaddingInReg()) {
26830b57cec5SDimitry Andric ArgAttrs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
26840b57cec5SDimitry Andric llvm::AttributeSet::get(
26850b57cec5SDimitry Andric getLLVMContext(),
268604eeddc0SDimitry Andric llvm::AttrBuilder(getLLVMContext()).addAttribute(llvm::Attribute::InReg));
26870b57cec5SDimitry Andric }
26880b57cec5SDimitry Andric }
26890b57cec5SDimitry Andric
2690fe6060f1SDimitry Andric // Decide whether the argument we're handling could be partially undef
269181ad6265SDimitry Andric if (CodeGenOpts.EnableNoundefAttrs &&
269204eeddc0SDimitry Andric DetermineNoUndef(ParamType, getTypes(), DL, AI)) {
2693fe6060f1SDimitry Andric Attrs.addAttribute(llvm::Attribute::NoUndef);
269404eeddc0SDimitry Andric }
2695fe6060f1SDimitry Andric
26960b57cec5SDimitry Andric // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
26970b57cec5SDimitry Andric // have the corresponding parameter variable. It doesn't make
26980b57cec5SDimitry Andric // sense to do it here because parameters are so messed up.
26990b57cec5SDimitry Andric switch (AI.getKind()) {
27000b57cec5SDimitry Andric case ABIArgInfo::Extend:
27010b57cec5SDimitry Andric if (AI.isSignExt())
27020b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::SExt);
27030b57cec5SDimitry Andric else
27040b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::ZExt);
2705bdd1243dSDimitry Andric [[fallthrough]];
27060b57cec5SDimitry Andric case ABIArgInfo::Direct:
27070b57cec5SDimitry Andric if (ArgNo == 0 && FI.isChainCall())
27080b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::Nest);
27090b57cec5SDimitry Andric else if (AI.getInReg())
27100b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::InReg);
2711fe6060f1SDimitry Andric Attrs.addStackAlignmentAttr(llvm::MaybeAlign(AI.getDirectAlign()));
27120b57cec5SDimitry Andric
271306c3fb27SDimitry Andric if (canApplyNoFPClass(AI, ParamType, false))
271406c3fb27SDimitry Andric Attrs.addNoFPClassAttr(getNoFPClassTestMask(getLangOpts()));
271506c3fb27SDimitry Andric break;
27160b57cec5SDimitry Andric case ABIArgInfo::Indirect: {
27170b57cec5SDimitry Andric if (AI.getInReg())
27180b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::InReg);
27190b57cec5SDimitry Andric
27200b57cec5SDimitry Andric if (AI.getIndirectByVal())
27210b57cec5SDimitry Andric Attrs.addByValAttr(getTypes().ConvertTypeForMem(ParamType));
27220b57cec5SDimitry Andric
2723e8d8bef9SDimitry Andric auto *Decl = ParamType->getAsRecordDecl();
2724e8d8bef9SDimitry Andric if (CodeGenOpts.PassByValueIsNoAlias && Decl &&
27255f757f3fSDimitry Andric Decl->getArgPassingRestrictions() ==
27265f757f3fSDimitry Andric RecordArgPassingKind::CanPassInRegs)
2727e8d8bef9SDimitry Andric // When calling the function, the pointer passed in will be the only
2728e8d8bef9SDimitry Andric // reference to the underlying object. Mark it accordingly.
2729e8d8bef9SDimitry Andric Attrs.addAttribute(llvm::Attribute::NoAlias);
2730e8d8bef9SDimitry Andric
2731e8d8bef9SDimitry Andric // TODO: We could add the byref attribute if not byval, but it would
2732e8d8bef9SDimitry Andric // require updating many testcases.
2733e8d8bef9SDimitry Andric
27340b57cec5SDimitry Andric CharUnits Align = AI.getIndirectAlign();
27350b57cec5SDimitry Andric
27360b57cec5SDimitry Andric // In a byval argument, it is important that the required
27370b57cec5SDimitry Andric // alignment of the type is honored, as LLVM might be creating a
27380b57cec5SDimitry Andric // *new* stack object, and needs to know what alignment to give
27390b57cec5SDimitry Andric // it. (Sometimes it can deduce a sensible alignment on its own,
27400b57cec5SDimitry Andric // but not if clang decides it must emit a packed struct, or the
27410b57cec5SDimitry Andric // user specifies increased alignment requirements.)
27420b57cec5SDimitry Andric //
27430b57cec5SDimitry Andric // This is different from indirect *not* byval, where the object
27440b57cec5SDimitry Andric // exists already, and the align attribute is purely
27450b57cec5SDimitry Andric // informative.
27460b57cec5SDimitry Andric assert(!Align.isZero());
27470b57cec5SDimitry Andric
27480b57cec5SDimitry Andric // For now, only add this when we have a byval argument.
27490b57cec5SDimitry Andric // TODO: be less lazy about updating test cases.
27500b57cec5SDimitry Andric if (AI.getIndirectByVal())
27510b57cec5SDimitry Andric Attrs.addAlignmentAttr(Align.getQuantity());
27520b57cec5SDimitry Andric
27530b57cec5SDimitry Andric // byval disables readnone and readonly.
2754bdd1243dSDimitry Andric AddPotentialArgAccess();
2755e8d8bef9SDimitry Andric break;
2756e8d8bef9SDimitry Andric }
2757e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased: {
2758e8d8bef9SDimitry Andric CharUnits Align = AI.getIndirectAlign();
2759e8d8bef9SDimitry Andric Attrs.addByRefAttr(getTypes().ConvertTypeForMem(ParamType));
2760e8d8bef9SDimitry Andric Attrs.addAlignmentAttr(Align.getQuantity());
27610b57cec5SDimitry Andric break;
27620b57cec5SDimitry Andric }
27630b57cec5SDimitry Andric case ABIArgInfo::Ignore:
27640b57cec5SDimitry Andric case ABIArgInfo::Expand:
27650b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand:
27660b57cec5SDimitry Andric break;
27670b57cec5SDimitry Andric
27680b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
27690b57cec5SDimitry Andric // inalloca disables readnone and readonly.
2770bdd1243dSDimitry Andric AddPotentialArgAccess();
27710b57cec5SDimitry Andric continue;
27720b57cec5SDimitry Andric }
27730b57cec5SDimitry Andric
27740b57cec5SDimitry Andric if (const auto *RefTy = ParamType->getAs<ReferenceType>()) {
27750b57cec5SDimitry Andric QualType PTy = RefTy->getPointeeType();
27760b57cec5SDimitry Andric if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
27775ffd83dbSDimitry Andric Attrs.addDereferenceableAttr(
27785ffd83dbSDimitry Andric getMinimumObjectSize(PTy).getQuantity());
2779bdd1243dSDimitry Andric if (getTypes().getTargetAddressSpace(PTy) == 0 &&
27800b57cec5SDimitry Andric !CodeGenOpts.NullPointerIsValid)
27810b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::NonNull);
27825ffd83dbSDimitry Andric if (PTy->isObjectType()) {
27835ffd83dbSDimitry Andric llvm::Align Alignment =
27845ffd83dbSDimitry Andric getNaturalPointeeTypeAlignment(ParamType).getAsAlign();
27855ffd83dbSDimitry Andric Attrs.addAlignmentAttr(Alignment);
27865ffd83dbSDimitry Andric }
27870b57cec5SDimitry Andric }
27880b57cec5SDimitry Andric
278981ad6265SDimitry Andric // From OpenCL spec v3.0.10 section 6.3.5 Alignment of Types:
279081ad6265SDimitry Andric // > For arguments to a __kernel function declared to be a pointer to a
279181ad6265SDimitry Andric // > data type, the OpenCL compiler can assume that the pointee is always
279281ad6265SDimitry Andric // > appropriately aligned as required by the data type.
279381ad6265SDimitry Andric if (TargetDecl && TargetDecl->hasAttr<OpenCLKernelAttr>() &&
279481ad6265SDimitry Andric ParamType->isPointerType()) {
279581ad6265SDimitry Andric QualType PTy = ParamType->getPointeeType();
279681ad6265SDimitry Andric if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
279781ad6265SDimitry Andric llvm::Align Alignment =
279881ad6265SDimitry Andric getNaturalPointeeTypeAlignment(ParamType).getAsAlign();
279981ad6265SDimitry Andric Attrs.addAlignmentAttr(Alignment);
280081ad6265SDimitry Andric }
280181ad6265SDimitry Andric }
280281ad6265SDimitry Andric
28030b57cec5SDimitry Andric switch (FI.getExtParameterInfo(ArgNo).getABI()) {
28040b57cec5SDimitry Andric case ParameterABI::Ordinary:
28050b57cec5SDimitry Andric break;
28060b57cec5SDimitry Andric
28070b57cec5SDimitry Andric case ParameterABI::SwiftIndirectResult: {
28080b57cec5SDimitry Andric // Add 'sret' if we haven't already used it for something, but
28090b57cec5SDimitry Andric // only if the result is void.
28100b57cec5SDimitry Andric if (!hasUsedSRet && RetTy->isVoidType()) {
2811e8d8bef9SDimitry Andric Attrs.addStructRetAttr(getTypes().ConvertTypeForMem(ParamType));
28120b57cec5SDimitry Andric hasUsedSRet = true;
28130b57cec5SDimitry Andric }
28140b57cec5SDimitry Andric
28150b57cec5SDimitry Andric // Add 'noalias' in either case.
28160b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::NoAlias);
28170b57cec5SDimitry Andric
28180b57cec5SDimitry Andric // Add 'dereferenceable' and 'alignment'.
28190b57cec5SDimitry Andric auto PTy = ParamType->getPointeeType();
28200b57cec5SDimitry Andric if (!PTy->isIncompleteType() && PTy->isConstantSizeType()) {
28210b57cec5SDimitry Andric auto info = getContext().getTypeInfoInChars(PTy);
2822e8d8bef9SDimitry Andric Attrs.addDereferenceableAttr(info.Width.getQuantity());
2823e8d8bef9SDimitry Andric Attrs.addAlignmentAttr(info.Align.getAsAlign());
28240b57cec5SDimitry Andric }
28250b57cec5SDimitry Andric break;
28260b57cec5SDimitry Andric }
28270b57cec5SDimitry Andric
28280b57cec5SDimitry Andric case ParameterABI::SwiftErrorResult:
28290b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::SwiftError);
28300b57cec5SDimitry Andric break;
28310b57cec5SDimitry Andric
28320b57cec5SDimitry Andric case ParameterABI::SwiftContext:
28330b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::SwiftSelf);
28340b57cec5SDimitry Andric break;
2835fe6060f1SDimitry Andric
2836fe6060f1SDimitry Andric case ParameterABI::SwiftAsyncContext:
2837fe6060f1SDimitry Andric Attrs.addAttribute(llvm::Attribute::SwiftAsync);
2838fe6060f1SDimitry Andric break;
28390b57cec5SDimitry Andric }
28400b57cec5SDimitry Andric
28410b57cec5SDimitry Andric if (FI.getExtParameterInfo(ArgNo).isNoEscape())
28420b57cec5SDimitry Andric Attrs.addAttribute(llvm::Attribute::NoCapture);
28430b57cec5SDimitry Andric
28440b57cec5SDimitry Andric if (Attrs.hasAttributes()) {
28450b57cec5SDimitry Andric unsigned FirstIRArg, NumIRArgs;
28460b57cec5SDimitry Andric std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
28470b57cec5SDimitry Andric for (unsigned i = 0; i < NumIRArgs; i++)
284804eeddc0SDimitry Andric ArgAttrs[FirstIRArg + i] = ArgAttrs[FirstIRArg + i].addAttributes(
284904eeddc0SDimitry Andric getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), Attrs));
28500b57cec5SDimitry Andric }
28510b57cec5SDimitry Andric }
28520b57cec5SDimitry Andric assert(ArgNo == FI.arg_size());
28530b57cec5SDimitry Andric
28540b57cec5SDimitry Andric AttrList = llvm::AttributeList::get(
28550b57cec5SDimitry Andric getLLVMContext(), llvm::AttributeSet::get(getLLVMContext(), FuncAttrs),
28560b57cec5SDimitry Andric llvm::AttributeSet::get(getLLVMContext(), RetAttrs), ArgAttrs);
28570b57cec5SDimitry Andric }
28580b57cec5SDimitry Andric
28590b57cec5SDimitry Andric /// An argument came in as a promoted argument; demote it back to its
28600b57cec5SDimitry Andric /// declared type.
emitArgumentDemotion(CodeGenFunction & CGF,const VarDecl * var,llvm::Value * value)28610b57cec5SDimitry Andric static llvm::Value *emitArgumentDemotion(CodeGenFunction &CGF,
28620b57cec5SDimitry Andric const VarDecl *var,
28630b57cec5SDimitry Andric llvm::Value *value) {
28640b57cec5SDimitry Andric llvm::Type *varType = CGF.ConvertType(var->getType());
28650b57cec5SDimitry Andric
28660b57cec5SDimitry Andric // This can happen with promotions that actually don't change the
28670b57cec5SDimitry Andric // underlying type, like the enum promotions.
28680b57cec5SDimitry Andric if (value->getType() == varType) return value;
28690b57cec5SDimitry Andric
28700b57cec5SDimitry Andric assert((varType->isIntegerTy() || varType->isFloatingPointTy())
28710b57cec5SDimitry Andric && "unexpected promotion type");
28720b57cec5SDimitry Andric
28730b57cec5SDimitry Andric if (isa<llvm::IntegerType>(varType))
28740b57cec5SDimitry Andric return CGF.Builder.CreateTrunc(value, varType, "arg.unpromote");
28750b57cec5SDimitry Andric
28760b57cec5SDimitry Andric return CGF.Builder.CreateFPCast(value, varType, "arg.unpromote");
28770b57cec5SDimitry Andric }
28780b57cec5SDimitry Andric
28790b57cec5SDimitry Andric /// Returns the attribute (either parameter attribute, or function
28800b57cec5SDimitry Andric /// attribute), which declares argument ArgNo to be non-null.
getNonNullAttr(const Decl * FD,const ParmVarDecl * PVD,QualType ArgType,unsigned ArgNo)28810b57cec5SDimitry Andric static const NonNullAttr *getNonNullAttr(const Decl *FD, const ParmVarDecl *PVD,
28820b57cec5SDimitry Andric QualType ArgType, unsigned ArgNo) {
28830b57cec5SDimitry Andric // FIXME: __attribute__((nonnull)) can also be applied to:
28840b57cec5SDimitry Andric // - references to pointers, where the pointee is known to be
28850b57cec5SDimitry Andric // nonnull (apparently a Clang extension)
28860b57cec5SDimitry Andric // - transparent unions containing pointers
28870b57cec5SDimitry Andric // In the former case, LLVM IR cannot represent the constraint. In
28880b57cec5SDimitry Andric // the latter case, we have no guarantee that the transparent union
28890b57cec5SDimitry Andric // is in fact passed as a pointer.
28900b57cec5SDimitry Andric if (!ArgType->isAnyPointerType() && !ArgType->isBlockPointerType())
28910b57cec5SDimitry Andric return nullptr;
28920b57cec5SDimitry Andric // First, check attribute on parameter itself.
28930b57cec5SDimitry Andric if (PVD) {
28940b57cec5SDimitry Andric if (auto ParmNNAttr = PVD->getAttr<NonNullAttr>())
28950b57cec5SDimitry Andric return ParmNNAttr;
28960b57cec5SDimitry Andric }
28970b57cec5SDimitry Andric // Check function attributes.
28980b57cec5SDimitry Andric if (!FD)
28990b57cec5SDimitry Andric return nullptr;
29000b57cec5SDimitry Andric for (const auto *NNAttr : FD->specific_attrs<NonNullAttr>()) {
29010b57cec5SDimitry Andric if (NNAttr->isNonNull(ArgNo))
29020b57cec5SDimitry Andric return NNAttr;
29030b57cec5SDimitry Andric }
29040b57cec5SDimitry Andric return nullptr;
29050b57cec5SDimitry Andric }
29060b57cec5SDimitry Andric
29070b57cec5SDimitry Andric namespace {
29080b57cec5SDimitry Andric struct CopyBackSwiftError final : EHScopeStack::Cleanup {
29090b57cec5SDimitry Andric Address Temp;
29100b57cec5SDimitry Andric Address Arg;
CopyBackSwiftError__anonf4c048640b11::CopyBackSwiftError29110b57cec5SDimitry Andric CopyBackSwiftError(Address temp, Address arg) : Temp(temp), Arg(arg) {}
Emit__anonf4c048640b11::CopyBackSwiftError29120b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override {
29130b57cec5SDimitry Andric llvm::Value *errorValue = CGF.Builder.CreateLoad(Temp);
29140b57cec5SDimitry Andric CGF.Builder.CreateStore(errorValue, Arg);
29150b57cec5SDimitry Andric }
29160b57cec5SDimitry Andric };
29170b57cec5SDimitry Andric }
29180b57cec5SDimitry Andric
EmitFunctionProlog(const CGFunctionInfo & FI,llvm::Function * Fn,const FunctionArgList & Args)29190b57cec5SDimitry Andric void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
29200b57cec5SDimitry Andric llvm::Function *Fn,
29210b57cec5SDimitry Andric const FunctionArgList &Args) {
29220b57cec5SDimitry Andric if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>())
29230b57cec5SDimitry Andric // Naked functions don't have prologues.
29240b57cec5SDimitry Andric return;
29250b57cec5SDimitry Andric
29260b57cec5SDimitry Andric // If this is an implicit-return-zero function, go ahead and
29270b57cec5SDimitry Andric // initialize the return value. TODO: it might be nice to have
29280b57cec5SDimitry Andric // a more general mechanism for this that didn't require synthesized
29290b57cec5SDimitry Andric // return statements.
29300b57cec5SDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl)) {
29310b57cec5SDimitry Andric if (FD->hasImplicitReturnZero()) {
29320b57cec5SDimitry Andric QualType RetTy = FD->getReturnType().getUnqualifiedType();
29330b57cec5SDimitry Andric llvm::Type* LLVMTy = CGM.getTypes().ConvertType(RetTy);
29340b57cec5SDimitry Andric llvm::Constant* Zero = llvm::Constant::getNullValue(LLVMTy);
29350b57cec5SDimitry Andric Builder.CreateStore(Zero, ReturnValue);
29360b57cec5SDimitry Andric }
29370b57cec5SDimitry Andric }
29380b57cec5SDimitry Andric
29390b57cec5SDimitry Andric // FIXME: We no longer need the types from FunctionArgList; lift up and
29400b57cec5SDimitry Andric // simplify.
29410b57cec5SDimitry Andric
29420b57cec5SDimitry Andric ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), FI);
29435ffd83dbSDimitry Andric assert(Fn->arg_size() == IRFunctionArgs.totalIRArgs());
29440b57cec5SDimitry Andric
29450b57cec5SDimitry Andric // If we're using inalloca, all the memory arguments are GEPs off of the last
29460b57cec5SDimitry Andric // parameter, which is a pointer to the complete memory area.
29470b57cec5SDimitry Andric Address ArgStruct = Address::invalid();
294806c3fb27SDimitry Andric if (IRFunctionArgs.hasInallocaArg())
29495ffd83dbSDimitry Andric ArgStruct = Address(Fn->getArg(IRFunctionArgs.getInallocaArgNo()),
295081ad6265SDimitry Andric FI.getArgStruct(), FI.getArgStructAlignment());
29510b57cec5SDimitry Andric
29520b57cec5SDimitry Andric // Name the struct return parameter.
29530b57cec5SDimitry Andric if (IRFunctionArgs.hasSRetArg()) {
29545ffd83dbSDimitry Andric auto AI = Fn->getArg(IRFunctionArgs.getSRetArgNo());
29550b57cec5SDimitry Andric AI->setName("agg.result");
29560b57cec5SDimitry Andric AI->addAttr(llvm::Attribute::NoAlias);
29570b57cec5SDimitry Andric }
29580b57cec5SDimitry Andric
29590b57cec5SDimitry Andric // Track if we received the parameter as a pointer (indirect, byval, or
29600b57cec5SDimitry Andric // inalloca). If already have a pointer, EmitParmDecl doesn't need to copy it
29610b57cec5SDimitry Andric // into a local alloca for us.
29620b57cec5SDimitry Andric SmallVector<ParamValue, 16> ArgVals;
29630b57cec5SDimitry Andric ArgVals.reserve(Args.size());
29640b57cec5SDimitry Andric
29650b57cec5SDimitry Andric // Create a pointer value for every parameter declaration. This usually
29660b57cec5SDimitry Andric // entails copying one or more LLVM IR arguments into an alloca. Don't push
29670b57cec5SDimitry Andric // any cleanups or do anything that might unwind. We do that separately, so
29680b57cec5SDimitry Andric // we can push the cleanups in the correct order for the ABI.
29690b57cec5SDimitry Andric assert(FI.arg_size() == Args.size() &&
29700b57cec5SDimitry Andric "Mismatch between function signature & arguments.");
29710b57cec5SDimitry Andric unsigned ArgNo = 0;
29720b57cec5SDimitry Andric CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin();
29730b57cec5SDimitry Andric for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
29740b57cec5SDimitry Andric i != e; ++i, ++info_it, ++ArgNo) {
29750b57cec5SDimitry Andric const VarDecl *Arg = *i;
29760b57cec5SDimitry Andric const ABIArgInfo &ArgI = info_it->info;
29770b57cec5SDimitry Andric
29780b57cec5SDimitry Andric bool isPromoted =
29790b57cec5SDimitry Andric isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
29800b57cec5SDimitry Andric // We are converting from ABIArgInfo type to VarDecl type directly, unless
29810b57cec5SDimitry Andric // the parameter is promoted. In this case we convert to
29820b57cec5SDimitry Andric // CGFunctionInfo::ArgInfo type with subsequent argument demotion.
29830b57cec5SDimitry Andric QualType Ty = isPromoted ? info_it->type : Arg->getType();
29840b57cec5SDimitry Andric assert(hasScalarEvaluationKind(Ty) ==
29850b57cec5SDimitry Andric hasScalarEvaluationKind(Arg->getType()));
29860b57cec5SDimitry Andric
29870b57cec5SDimitry Andric unsigned FirstIRArg, NumIRArgs;
29880b57cec5SDimitry Andric std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
29890b57cec5SDimitry Andric
29900b57cec5SDimitry Andric switch (ArgI.getKind()) {
29910b57cec5SDimitry Andric case ABIArgInfo::InAlloca: {
29920b57cec5SDimitry Andric assert(NumIRArgs == 0);
29930b57cec5SDimitry Andric auto FieldIndex = ArgI.getInAllocaFieldIndex();
29940b57cec5SDimitry Andric Address V =
29950b57cec5SDimitry Andric Builder.CreateStructGEP(ArgStruct, FieldIndex, Arg->getName());
29965ffd83dbSDimitry Andric if (ArgI.getInAllocaIndirect())
299781ad6265SDimitry Andric V = Address(Builder.CreateLoad(V), ConvertTypeForMem(Ty),
29985ffd83dbSDimitry Andric getContext().getTypeAlignInChars(Ty));
29990b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forIndirect(V));
30000b57cec5SDimitry Andric break;
30010b57cec5SDimitry Andric }
30020b57cec5SDimitry Andric
3003e8d8bef9SDimitry Andric case ABIArgInfo::Indirect:
3004e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased: {
30050b57cec5SDimitry Andric assert(NumIRArgs == 1);
30060fca6ea1SDimitry Andric Address ParamAddr = makeNaturalAddressForPointer(
30070fca6ea1SDimitry Andric Fn->getArg(FirstIRArg), Ty, ArgI.getIndirectAlign(), false, nullptr,
30080fca6ea1SDimitry Andric nullptr, KnownNonNull);
30090b57cec5SDimitry Andric
30100b57cec5SDimitry Andric if (!hasScalarEvaluationKind(Ty)) {
30110b57cec5SDimitry Andric // Aggregates and complex variables are accessed by reference. All we
3012e8d8bef9SDimitry Andric // need to do is realign the value, if requested. Also, if the address
3013e8d8bef9SDimitry Andric // may be aliased, copy it to ensure that the parameter variable is
3014e8d8bef9SDimitry Andric // mutable and has a unique adress, as C requires.
3015e8d8bef9SDimitry Andric if (ArgI.getIndirectRealign() || ArgI.isIndirectAliased()) {
30160fca6ea1SDimitry Andric RawAddress AlignedTemp = CreateMemTemp(Ty, "coerce");
30170b57cec5SDimitry Andric
30180b57cec5SDimitry Andric // Copy from the incoming argument pointer to the temporary with the
30190b57cec5SDimitry Andric // appropriate alignment.
30200b57cec5SDimitry Andric //
30210b57cec5SDimitry Andric // FIXME: We should have a common utility for generating an aggregate
30220b57cec5SDimitry Andric // copy.
30230b57cec5SDimitry Andric CharUnits Size = getContext().getTypeSizeInChars(Ty);
30245ffd83dbSDimitry Andric Builder.CreateMemCpy(
30255ffd83dbSDimitry Andric AlignedTemp.getPointer(), AlignedTemp.getAlignment().getAsAlign(),
30260fca6ea1SDimitry Andric ParamAddr.emitRawPointer(*this),
30270fca6ea1SDimitry Andric ParamAddr.getAlignment().getAsAlign(),
30285ffd83dbSDimitry Andric llvm::ConstantInt::get(IntPtrTy, Size.getQuantity()));
30290fca6ea1SDimitry Andric ParamAddr = AlignedTemp;
30300b57cec5SDimitry Andric }
30310fca6ea1SDimitry Andric ArgVals.push_back(ParamValue::forIndirect(ParamAddr));
30320b57cec5SDimitry Andric } else {
30330b57cec5SDimitry Andric // Load scalar value from indirect argument.
30340b57cec5SDimitry Andric llvm::Value *V =
30350b57cec5SDimitry Andric EmitLoadOfScalar(ParamAddr, false, Ty, Arg->getBeginLoc());
30360b57cec5SDimitry Andric
30370b57cec5SDimitry Andric if (isPromoted)
30380b57cec5SDimitry Andric V = emitArgumentDemotion(*this, Arg, V);
30390b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forDirect(V));
30400b57cec5SDimitry Andric }
30410b57cec5SDimitry Andric break;
30420b57cec5SDimitry Andric }
30430b57cec5SDimitry Andric
30440b57cec5SDimitry Andric case ABIArgInfo::Extend:
30450b57cec5SDimitry Andric case ABIArgInfo::Direct: {
30465ffd83dbSDimitry Andric auto AI = Fn->getArg(FirstIRArg);
30475ffd83dbSDimitry Andric llvm::Type *LTy = ConvertType(Arg->getType());
30480b57cec5SDimitry Andric
30495ffd83dbSDimitry Andric // Prepare parameter attributes. So far, only attributes for pointer
30505ffd83dbSDimitry Andric // parameters are prepared. See
30515ffd83dbSDimitry Andric // http://llvm.org/docs/LangRef.html#paramattrs.
30525ffd83dbSDimitry Andric if (ArgI.getDirectOffset() == 0 && LTy->isPointerTy() &&
30535ffd83dbSDimitry Andric ArgI.getCoerceToType()->isPointerTy()) {
30540b57cec5SDimitry Andric assert(NumIRArgs == 1);
30550b57cec5SDimitry Andric
30560b57cec5SDimitry Andric if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
30575ffd83dbSDimitry Andric // Set `nonnull` attribute if any.
30580b57cec5SDimitry Andric if (getNonNullAttr(CurCodeDecl, PVD, PVD->getType(),
30590b57cec5SDimitry Andric PVD->getFunctionScopeIndex()) &&
30600b57cec5SDimitry Andric !CGM.getCodeGenOpts().NullPointerIsValid)
30610b57cec5SDimitry Andric AI->addAttr(llvm::Attribute::NonNull);
30620b57cec5SDimitry Andric
30630b57cec5SDimitry Andric QualType OTy = PVD->getOriginalType();
30640b57cec5SDimitry Andric if (const auto *ArrTy =
30650b57cec5SDimitry Andric getContext().getAsConstantArrayType(OTy)) {
30660b57cec5SDimitry Andric // A C99 array parameter declaration with the static keyword also
30670b57cec5SDimitry Andric // indicates dereferenceability, and if the size is constant we can
30680b57cec5SDimitry Andric // use the dereferenceable attribute (which requires the size in
30690b57cec5SDimitry Andric // bytes).
30705f757f3fSDimitry Andric if (ArrTy->getSizeModifier() == ArraySizeModifier::Static) {
30710b57cec5SDimitry Andric QualType ETy = ArrTy->getElementType();
3072e8d8bef9SDimitry Andric llvm::Align Alignment =
3073e8d8bef9SDimitry Andric CGM.getNaturalTypeAlignment(ETy).getAsAlign();
307404eeddc0SDimitry Andric AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment));
30750fca6ea1SDimitry Andric uint64_t ArrSize = ArrTy->getZExtSize();
30760b57cec5SDimitry Andric if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
30770b57cec5SDimitry Andric ArrSize) {
307804eeddc0SDimitry Andric llvm::AttrBuilder Attrs(getLLVMContext());
30790b57cec5SDimitry Andric Attrs.addDereferenceableAttr(
30805ffd83dbSDimitry Andric getContext().getTypeSizeInChars(ETy).getQuantity() *
30815ffd83dbSDimitry Andric ArrSize);
30820b57cec5SDimitry Andric AI->addAttrs(Attrs);
30835ffd83dbSDimitry Andric } else if (getContext().getTargetInfo().getNullPointerValue(
30845ffd83dbSDimitry Andric ETy.getAddressSpace()) == 0 &&
30850b57cec5SDimitry Andric !CGM.getCodeGenOpts().NullPointerIsValid) {
30860b57cec5SDimitry Andric AI->addAttr(llvm::Attribute::NonNull);
30870b57cec5SDimitry Andric }
30880b57cec5SDimitry Andric }
30890b57cec5SDimitry Andric } else if (const auto *ArrTy =
30900b57cec5SDimitry Andric getContext().getAsVariableArrayType(OTy)) {
30910b57cec5SDimitry Andric // For C99 VLAs with the static keyword, we don't know the size so
30920b57cec5SDimitry Andric // we can't use the dereferenceable attribute, but in addrspace(0)
30930b57cec5SDimitry Andric // we know that it must be nonnull.
30945f757f3fSDimitry Andric if (ArrTy->getSizeModifier() == ArraySizeModifier::Static) {
3095e8d8bef9SDimitry Andric QualType ETy = ArrTy->getElementType();
3096e8d8bef9SDimitry Andric llvm::Align Alignment =
3097e8d8bef9SDimitry Andric CGM.getNaturalTypeAlignment(ETy).getAsAlign();
309804eeddc0SDimitry Andric AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(Alignment));
3099bdd1243dSDimitry Andric if (!getTypes().getTargetAddressSpace(ETy) &&
31000b57cec5SDimitry Andric !CGM.getCodeGenOpts().NullPointerIsValid)
31010b57cec5SDimitry Andric AI->addAttr(llvm::Attribute::NonNull);
31020b57cec5SDimitry Andric }
3103e8d8bef9SDimitry Andric }
31040b57cec5SDimitry Andric
31055ffd83dbSDimitry Andric // Set `align` attribute if any.
31060b57cec5SDimitry Andric const auto *AVAttr = PVD->getAttr<AlignValueAttr>();
31070b57cec5SDimitry Andric if (!AVAttr)
3108bdd1243dSDimitry Andric if (const auto *TOTy = OTy->getAs<TypedefType>())
31090b57cec5SDimitry Andric AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>();
31100b57cec5SDimitry Andric if (AVAttr && !SanOpts.has(SanitizerKind::Alignment)) {
31110b57cec5SDimitry Andric // If alignment-assumption sanitizer is enabled, we do *not* add
31120b57cec5SDimitry Andric // alignment attribute here, but emit normal alignment assumption,
31130b57cec5SDimitry Andric // so the UBSAN check could function.
31140b57cec5SDimitry Andric llvm::ConstantInt *AlignmentCI =
31155ffd83dbSDimitry Andric cast<llvm::ConstantInt>(EmitScalarExpr(AVAttr->getAlignment()));
3116349cc55cSDimitry Andric uint64_t AlignmentInt =
31175ffd83dbSDimitry Andric AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment);
31185ffd83dbSDimitry Andric if (AI->getParamAlign().valueOrOne() < AlignmentInt) {
31195ffd83dbSDimitry Andric AI->removeAttr(llvm::Attribute::AttrKind::Alignment);
312004eeddc0SDimitry Andric AI->addAttrs(llvm::AttrBuilder(getLLVMContext()).addAlignmentAttr(
31215ffd83dbSDimitry Andric llvm::Align(AlignmentInt)));
31225ffd83dbSDimitry Andric }
31230b57cec5SDimitry Andric }
31240b57cec5SDimitry Andric }
31250b57cec5SDimitry Andric
31265ffd83dbSDimitry Andric // Set 'noalias' if an argument type has the `restrict` qualifier.
31270b57cec5SDimitry Andric if (Arg->getType().isRestrictQualified())
31280b57cec5SDimitry Andric AI->addAttr(llvm::Attribute::NoAlias);
31295ffd83dbSDimitry Andric }
31305ffd83dbSDimitry Andric
31315ffd83dbSDimitry Andric // Prepare the argument value. If we have the trivial case, handle it
31325ffd83dbSDimitry Andric // with no muss and fuss.
31335ffd83dbSDimitry Andric if (!isa<llvm::StructType>(ArgI.getCoerceToType()) &&
31345ffd83dbSDimitry Andric ArgI.getCoerceToType() == ConvertType(Ty) &&
31355ffd83dbSDimitry Andric ArgI.getDirectOffset() == 0) {
31365ffd83dbSDimitry Andric assert(NumIRArgs == 1);
31370b57cec5SDimitry Andric
31380b57cec5SDimitry Andric // LLVM expects swifterror parameters to be used in very restricted
31390b57cec5SDimitry Andric // ways. Copy the value into a less-restricted temporary.
31405ffd83dbSDimitry Andric llvm::Value *V = AI;
31410b57cec5SDimitry Andric if (FI.getExtParameterInfo(ArgNo).getABI()
31420b57cec5SDimitry Andric == ParameterABI::SwiftErrorResult) {
31430b57cec5SDimitry Andric QualType pointeeTy = Ty->getPointeeType();
31440b57cec5SDimitry Andric assert(pointeeTy->isPointerType());
31450fca6ea1SDimitry Andric RawAddress temp =
31460b57cec5SDimitry Andric CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
31470fca6ea1SDimitry Andric Address arg = makeNaturalAddressForPointer(
31480fca6ea1SDimitry Andric V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy));
31490b57cec5SDimitry Andric llvm::Value *incomingErrorValue = Builder.CreateLoad(arg);
31500b57cec5SDimitry Andric Builder.CreateStore(incomingErrorValue, temp);
31510b57cec5SDimitry Andric V = temp.getPointer();
31520b57cec5SDimitry Andric
31530b57cec5SDimitry Andric // Push a cleanup to copy the value back at the end of the function.
31540b57cec5SDimitry Andric // The convention does not guarantee that the value will be written
31550b57cec5SDimitry Andric // back if the function exits with an unwind exception.
31560b57cec5SDimitry Andric EHStack.pushCleanup<CopyBackSwiftError>(NormalCleanup, temp, arg);
31570b57cec5SDimitry Andric }
31580b57cec5SDimitry Andric
31590b57cec5SDimitry Andric // Ensure the argument is the correct type.
31600b57cec5SDimitry Andric if (V->getType() != ArgI.getCoerceToType())
31610b57cec5SDimitry Andric V = Builder.CreateBitCast(V, ArgI.getCoerceToType());
31620b57cec5SDimitry Andric
31630b57cec5SDimitry Andric if (isPromoted)
31640b57cec5SDimitry Andric V = emitArgumentDemotion(*this, Arg, V);
31650b57cec5SDimitry Andric
31660b57cec5SDimitry Andric // Because of merging of function types from multiple decls it is
31670b57cec5SDimitry Andric // possible for the type of an argument to not match the corresponding
31680b57cec5SDimitry Andric // type in the function type. Since we are codegening the callee
31690b57cec5SDimitry Andric // in here, add a cast to the argument type.
31700b57cec5SDimitry Andric llvm::Type *LTy = ConvertType(Arg->getType());
31710b57cec5SDimitry Andric if (V->getType() != LTy)
31720b57cec5SDimitry Andric V = Builder.CreateBitCast(V, LTy);
31730b57cec5SDimitry Andric
31740b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forDirect(V));
31750b57cec5SDimitry Andric break;
31760b57cec5SDimitry Andric }
31770b57cec5SDimitry Andric
3178e8d8bef9SDimitry Andric // VLST arguments are coerced to VLATs at the function boundary for
3179e8d8bef9SDimitry Andric // ABI consistency. If this is a VLST that was coerced to
3180e8d8bef9SDimitry Andric // a VLAT at the function boundary and the types match up, use
318181ad6265SDimitry Andric // llvm.vector.extract to convert back to the original VLST.
3182e8d8bef9SDimitry Andric if (auto *VecTyTo = dyn_cast<llvm::FixedVectorType>(ConvertType(Ty))) {
3183349cc55cSDimitry Andric llvm::Value *Coerced = Fn->getArg(FirstIRArg);
3184e8d8bef9SDimitry Andric if (auto *VecTyFrom =
3185e8d8bef9SDimitry Andric dyn_cast<llvm::ScalableVectorType>(Coerced->getType())) {
31860fca6ea1SDimitry Andric // If we are casting a scalable i1 predicate vector to a fixed i8
3187349cc55cSDimitry Andric // vector, bitcast the source and use a vector extract.
31880fca6ea1SDimitry Andric if (VecTyFrom->getElementType()->isIntegerTy(1) &&
31890fca6ea1SDimitry Andric VecTyFrom->getElementCount().isKnownMultipleOf(8) &&
3190349cc55cSDimitry Andric VecTyTo->getElementType() == Builder.getInt8Ty()) {
31910fca6ea1SDimitry Andric VecTyFrom = llvm::ScalableVectorType::get(
31920fca6ea1SDimitry Andric VecTyTo->getElementType(),
31930fca6ea1SDimitry Andric VecTyFrom->getElementCount().getKnownMinValue() / 8);
3194349cc55cSDimitry Andric Coerced = Builder.CreateBitCast(Coerced, VecTyFrom);
3195349cc55cSDimitry Andric }
3196e8d8bef9SDimitry Andric if (VecTyFrom->getElementType() == VecTyTo->getElementType()) {
3197e8d8bef9SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int64Ty);
3198e8d8bef9SDimitry Andric
3199e8d8bef9SDimitry Andric assert(NumIRArgs == 1);
3200e8d8bef9SDimitry Andric Coerced->setName(Arg->getName() + ".coerce");
3201e8d8bef9SDimitry Andric ArgVals.push_back(ParamValue::forDirect(Builder.CreateExtractVector(
320206c3fb27SDimitry Andric VecTyTo, Coerced, Zero, "cast.fixed")));
3203e8d8bef9SDimitry Andric break;
3204e8d8bef9SDimitry Andric }
3205e8d8bef9SDimitry Andric }
3206e8d8bef9SDimitry Andric }
3207e8d8bef9SDimitry Andric
32080fca6ea1SDimitry Andric llvm::StructType *STy =
32090fca6ea1SDimitry Andric dyn_cast<llvm::StructType>(ArgI.getCoerceToType());
32100fca6ea1SDimitry Andric if (ArgI.isDirect() && !ArgI.getCanBeFlattened() && STy &&
32110fca6ea1SDimitry Andric STy->getNumElements() > 1) {
32120fca6ea1SDimitry Andric [[maybe_unused]] llvm::TypeSize StructSize =
32130fca6ea1SDimitry Andric CGM.getDataLayout().getTypeAllocSize(STy);
32140fca6ea1SDimitry Andric [[maybe_unused]] llvm::TypeSize PtrElementSize =
32150fca6ea1SDimitry Andric CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(Ty));
32160fca6ea1SDimitry Andric if (STy->containsHomogeneousScalableVectorTypes()) {
32170fca6ea1SDimitry Andric assert(StructSize == PtrElementSize &&
32180fca6ea1SDimitry Andric "Only allow non-fractional movement of structure with"
32190fca6ea1SDimitry Andric "homogeneous scalable vector type");
32200fca6ea1SDimitry Andric
32210fca6ea1SDimitry Andric ArgVals.push_back(ParamValue::forDirect(AI));
32220fca6ea1SDimitry Andric break;
32230fca6ea1SDimitry Andric }
32240fca6ea1SDimitry Andric }
32250fca6ea1SDimitry Andric
32260b57cec5SDimitry Andric Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg),
32270b57cec5SDimitry Andric Arg->getName());
32280b57cec5SDimitry Andric
32290b57cec5SDimitry Andric // Pointer to store into.
32300b57cec5SDimitry Andric Address Ptr = emitAddressAtOffset(*this, Alloca, ArgI);
32310b57cec5SDimitry Andric
32320b57cec5SDimitry Andric // Fast-isel and the optimizer generally like scalar values better than
32330b57cec5SDimitry Andric // FCAs, so we flatten them if this is safe to do for this argument.
32340b57cec5SDimitry Andric if (ArgI.isDirect() && ArgI.getCanBeFlattened() && STy &&
32350b57cec5SDimitry Andric STy->getNumElements() > 1) {
323606c3fb27SDimitry Andric llvm::TypeSize StructSize = CGM.getDataLayout().getTypeAllocSize(STy);
323706c3fb27SDimitry Andric llvm::TypeSize PtrElementSize =
323806c3fb27SDimitry Andric CGM.getDataLayout().getTypeAllocSize(Ptr.getElementType());
323906c3fb27SDimitry Andric if (StructSize.isScalable()) {
324006c3fb27SDimitry Andric assert(STy->containsHomogeneousScalableVectorTypes() &&
324106c3fb27SDimitry Andric "ABI only supports structure with homogeneous scalable vector "
324206c3fb27SDimitry Andric "type");
324306c3fb27SDimitry Andric assert(StructSize == PtrElementSize &&
324406c3fb27SDimitry Andric "Only allow non-fractional movement of structure with"
324506c3fb27SDimitry Andric "homogeneous scalable vector type");
324606c3fb27SDimitry Andric assert(STy->getNumElements() == NumIRArgs);
324706c3fb27SDimitry Andric
324806c3fb27SDimitry Andric llvm::Value *LoadedStructValue = llvm::PoisonValue::get(STy);
324906c3fb27SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
325006c3fb27SDimitry Andric auto *AI = Fn->getArg(FirstIRArg + i);
325106c3fb27SDimitry Andric AI->setName(Arg->getName() + ".coerce" + Twine(i));
325206c3fb27SDimitry Andric LoadedStructValue =
325306c3fb27SDimitry Andric Builder.CreateInsertValue(LoadedStructValue, AI, i);
325406c3fb27SDimitry Andric }
325506c3fb27SDimitry Andric
325606c3fb27SDimitry Andric Builder.CreateStore(LoadedStructValue, Ptr);
325706c3fb27SDimitry Andric } else {
325806c3fb27SDimitry Andric uint64_t SrcSize = StructSize.getFixedValue();
325906c3fb27SDimitry Andric uint64_t DstSize = PtrElementSize.getFixedValue();
32600b57cec5SDimitry Andric
32610b57cec5SDimitry Andric Address AddrToStoreInto = Address::invalid();
32620b57cec5SDimitry Andric if (SrcSize <= DstSize) {
326306c3fb27SDimitry Andric AddrToStoreInto = Ptr.withElementType(STy);
32640b57cec5SDimitry Andric } else {
32650b57cec5SDimitry Andric AddrToStoreInto =
32660b57cec5SDimitry Andric CreateTempAlloca(STy, Alloca.getAlignment(), "coerce");
32670b57cec5SDimitry Andric }
32680b57cec5SDimitry Andric
32690b57cec5SDimitry Andric assert(STy->getNumElements() == NumIRArgs);
32700b57cec5SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
32715ffd83dbSDimitry Andric auto AI = Fn->getArg(FirstIRArg + i);
32720b57cec5SDimitry Andric AI->setName(Arg->getName() + ".coerce" + Twine(i));
32730b57cec5SDimitry Andric Address EltPtr = Builder.CreateStructGEP(AddrToStoreInto, i);
32740b57cec5SDimitry Andric Builder.CreateStore(AI, EltPtr);
32750b57cec5SDimitry Andric }
32760b57cec5SDimitry Andric
32770b57cec5SDimitry Andric if (SrcSize > DstSize) {
32780b57cec5SDimitry Andric Builder.CreateMemCpy(Ptr, AddrToStoreInto, DstSize);
32790b57cec5SDimitry Andric }
328006c3fb27SDimitry Andric }
32810b57cec5SDimitry Andric } else {
32820b57cec5SDimitry Andric // Simple case, just do a coerced store of the argument into the alloca.
32830b57cec5SDimitry Andric assert(NumIRArgs == 1);
32845ffd83dbSDimitry Andric auto AI = Fn->getArg(FirstIRArg);
32850b57cec5SDimitry Andric AI->setName(Arg->getName() + ".coerce");
3286c80e69b0SDimitry Andric CreateCoercedStore(
3287c80e69b0SDimitry Andric AI, Ptr,
3288c80e69b0SDimitry Andric llvm::TypeSize::getFixed(
3289c80e69b0SDimitry Andric getContext().getTypeSizeInChars(Ty).getQuantity() -
3290c80e69b0SDimitry Andric ArgI.getDirectOffset()),
3291c80e69b0SDimitry Andric /*DstIsVolatile=*/false);
32920b57cec5SDimitry Andric }
32930b57cec5SDimitry Andric
32940b57cec5SDimitry Andric // Match to what EmitParmDecl is expecting for this type.
32950b57cec5SDimitry Andric if (CodeGenFunction::hasScalarEvaluationKind(Ty)) {
32960b57cec5SDimitry Andric llvm::Value *V =
32970b57cec5SDimitry Andric EmitLoadOfScalar(Alloca, false, Ty, Arg->getBeginLoc());
32980b57cec5SDimitry Andric if (isPromoted)
32990b57cec5SDimitry Andric V = emitArgumentDemotion(*this, Arg, V);
33000b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forDirect(V));
33010b57cec5SDimitry Andric } else {
33020b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forIndirect(Alloca));
33030b57cec5SDimitry Andric }
33040b57cec5SDimitry Andric break;
33050b57cec5SDimitry Andric }
33060b57cec5SDimitry Andric
33070b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand: {
33080b57cec5SDimitry Andric // Reconstruct into a temporary.
33090b57cec5SDimitry Andric Address alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg));
33100b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forIndirect(alloca));
33110b57cec5SDimitry Andric
33120b57cec5SDimitry Andric auto coercionType = ArgI.getCoerceAndExpandType();
331306c3fb27SDimitry Andric alloca = alloca.withElementType(coercionType);
33140b57cec5SDimitry Andric
33150b57cec5SDimitry Andric unsigned argIndex = FirstIRArg;
33160b57cec5SDimitry Andric for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
33170b57cec5SDimitry Andric llvm::Type *eltType = coercionType->getElementType(i);
33180b57cec5SDimitry Andric if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType))
33190b57cec5SDimitry Andric continue;
33200b57cec5SDimitry Andric
33210b57cec5SDimitry Andric auto eltAddr = Builder.CreateStructGEP(alloca, i);
33225ffd83dbSDimitry Andric auto elt = Fn->getArg(argIndex++);
33230b57cec5SDimitry Andric Builder.CreateStore(elt, eltAddr);
33240b57cec5SDimitry Andric }
33250b57cec5SDimitry Andric assert(argIndex == FirstIRArg + NumIRArgs);
33260b57cec5SDimitry Andric break;
33270b57cec5SDimitry Andric }
33280b57cec5SDimitry Andric
33290b57cec5SDimitry Andric case ABIArgInfo::Expand: {
33300b57cec5SDimitry Andric // If this structure was expanded into multiple arguments then
33310b57cec5SDimitry Andric // we need to create a temporary and reconstruct it from the
33320b57cec5SDimitry Andric // arguments.
33330b57cec5SDimitry Andric Address Alloca = CreateMemTemp(Ty, getContext().getDeclAlign(Arg));
33340b57cec5SDimitry Andric LValue LV = MakeAddrLValue(Alloca, Ty);
33350b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forIndirect(Alloca));
33360b57cec5SDimitry Andric
33375ffd83dbSDimitry Andric auto FnArgIter = Fn->arg_begin() + FirstIRArg;
33380b57cec5SDimitry Andric ExpandTypeFromArgs(Ty, LV, FnArgIter);
33395ffd83dbSDimitry Andric assert(FnArgIter == Fn->arg_begin() + FirstIRArg + NumIRArgs);
33400b57cec5SDimitry Andric for (unsigned i = 0, e = NumIRArgs; i != e; ++i) {
33415ffd83dbSDimitry Andric auto AI = Fn->getArg(FirstIRArg + i);
33420b57cec5SDimitry Andric AI->setName(Arg->getName() + "." + Twine(i));
33430b57cec5SDimitry Andric }
33440b57cec5SDimitry Andric break;
33450b57cec5SDimitry Andric }
33460b57cec5SDimitry Andric
33470b57cec5SDimitry Andric case ABIArgInfo::Ignore:
33480b57cec5SDimitry Andric assert(NumIRArgs == 0);
33490b57cec5SDimitry Andric // Initialize the local variable appropriately.
33500b57cec5SDimitry Andric if (!hasScalarEvaluationKind(Ty)) {
33510b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forIndirect(CreateMemTemp(Ty)));
33520b57cec5SDimitry Andric } else {
33530b57cec5SDimitry Andric llvm::Value *U = llvm::UndefValue::get(ConvertType(Arg->getType()));
33540b57cec5SDimitry Andric ArgVals.push_back(ParamValue::forDirect(U));
33550b57cec5SDimitry Andric }
33560b57cec5SDimitry Andric break;
33570b57cec5SDimitry Andric }
33580b57cec5SDimitry Andric }
33590b57cec5SDimitry Andric
33600b57cec5SDimitry Andric if (getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
33610b57cec5SDimitry Andric for (int I = Args.size() - 1; I >= 0; --I)
33620b57cec5SDimitry Andric EmitParmDecl(*Args[I], ArgVals[I], I + 1);
33630b57cec5SDimitry Andric } else {
33640b57cec5SDimitry Andric for (unsigned I = 0, E = Args.size(); I != E; ++I)
33650b57cec5SDimitry Andric EmitParmDecl(*Args[I], ArgVals[I], I + 1);
33660b57cec5SDimitry Andric }
33670b57cec5SDimitry Andric }
33680b57cec5SDimitry Andric
eraseUnusedBitCasts(llvm::Instruction * insn)33690b57cec5SDimitry Andric static void eraseUnusedBitCasts(llvm::Instruction *insn) {
33700b57cec5SDimitry Andric while (insn->use_empty()) {
33710b57cec5SDimitry Andric llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(insn);
33720b57cec5SDimitry Andric if (!bitcast) return;
33730b57cec5SDimitry Andric
33740b57cec5SDimitry Andric // This is "safe" because we would have used a ConstantExpr otherwise.
33750b57cec5SDimitry Andric insn = cast<llvm::Instruction>(bitcast->getOperand(0));
33760b57cec5SDimitry Andric bitcast->eraseFromParent();
33770b57cec5SDimitry Andric }
33780b57cec5SDimitry Andric }
33790b57cec5SDimitry Andric
33800b57cec5SDimitry Andric /// Try to emit a fused autorelease of a return result.
tryEmitFusedAutoreleaseOfResult(CodeGenFunction & CGF,llvm::Value * result)33810b57cec5SDimitry Andric static llvm::Value *tryEmitFusedAutoreleaseOfResult(CodeGenFunction &CGF,
33820b57cec5SDimitry Andric llvm::Value *result) {
33830b57cec5SDimitry Andric // We must be immediately followed the cast.
33840b57cec5SDimitry Andric llvm::BasicBlock *BB = CGF.Builder.GetInsertBlock();
33850b57cec5SDimitry Andric if (BB->empty()) return nullptr;
33860b57cec5SDimitry Andric if (&BB->back() != result) return nullptr;
33870b57cec5SDimitry Andric
33880b57cec5SDimitry Andric llvm::Type *resultType = result->getType();
33890b57cec5SDimitry Andric
33900b57cec5SDimitry Andric // result is in a BasicBlock and is therefore an Instruction.
33910b57cec5SDimitry Andric llvm::Instruction *generator = cast<llvm::Instruction>(result);
33920b57cec5SDimitry Andric
33930b57cec5SDimitry Andric SmallVector<llvm::Instruction *, 4> InstsToKill;
33940b57cec5SDimitry Andric
33950b57cec5SDimitry Andric // Look for:
33960b57cec5SDimitry Andric // %generator = bitcast %type1* %generator2 to %type2*
33970b57cec5SDimitry Andric while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(generator)) {
33980b57cec5SDimitry Andric // We would have emitted this as a constant if the operand weren't
33990b57cec5SDimitry Andric // an Instruction.
34000b57cec5SDimitry Andric generator = cast<llvm::Instruction>(bitcast->getOperand(0));
34010b57cec5SDimitry Andric
34020b57cec5SDimitry Andric // Require the generator to be immediately followed by the cast.
34030b57cec5SDimitry Andric if (generator->getNextNode() != bitcast)
34040b57cec5SDimitry Andric return nullptr;
34050b57cec5SDimitry Andric
34060b57cec5SDimitry Andric InstsToKill.push_back(bitcast);
34070b57cec5SDimitry Andric }
34080b57cec5SDimitry Andric
34090b57cec5SDimitry Andric // Look for:
34100b57cec5SDimitry Andric // %generator = call i8* @objc_retain(i8* %originalResult)
34110b57cec5SDimitry Andric // or
34120b57cec5SDimitry Andric // %generator = call i8* @objc_retainAutoreleasedReturnValue(i8* %originalResult)
34130b57cec5SDimitry Andric llvm::CallInst *call = dyn_cast<llvm::CallInst>(generator);
34140b57cec5SDimitry Andric if (!call) return nullptr;
34150b57cec5SDimitry Andric
34160b57cec5SDimitry Andric bool doRetainAutorelease;
34170b57cec5SDimitry Andric
34185ffd83dbSDimitry Andric if (call->getCalledOperand() == CGF.CGM.getObjCEntrypoints().objc_retain) {
34190b57cec5SDimitry Andric doRetainAutorelease = true;
34205ffd83dbSDimitry Andric } else if (call->getCalledOperand() ==
34215ffd83dbSDimitry Andric CGF.CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue) {
34220b57cec5SDimitry Andric doRetainAutorelease = false;
34230b57cec5SDimitry Andric
34240b57cec5SDimitry Andric // If we emitted an assembly marker for this call (and the
34250b57cec5SDimitry Andric // ARCEntrypoints field should have been set if so), go looking
34260b57cec5SDimitry Andric // for that call. If we can't find it, we can't do this
34270b57cec5SDimitry Andric // optimization. But it should always be the immediately previous
34280b57cec5SDimitry Andric // instruction, unless we needed bitcasts around the call.
34290b57cec5SDimitry Andric if (CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker) {
34300b57cec5SDimitry Andric llvm::Instruction *prev = call->getPrevNode();
34310b57cec5SDimitry Andric assert(prev);
34320b57cec5SDimitry Andric if (isa<llvm::BitCastInst>(prev)) {
34330b57cec5SDimitry Andric prev = prev->getPrevNode();
34340b57cec5SDimitry Andric assert(prev);
34350b57cec5SDimitry Andric }
34360b57cec5SDimitry Andric assert(isa<llvm::CallInst>(prev));
34375ffd83dbSDimitry Andric assert(cast<llvm::CallInst>(prev)->getCalledOperand() ==
34380b57cec5SDimitry Andric CGF.CGM.getObjCEntrypoints().retainAutoreleasedReturnValueMarker);
34390b57cec5SDimitry Andric InstsToKill.push_back(prev);
34400b57cec5SDimitry Andric }
34410b57cec5SDimitry Andric } else {
34420b57cec5SDimitry Andric return nullptr;
34430b57cec5SDimitry Andric }
34440b57cec5SDimitry Andric
34450b57cec5SDimitry Andric result = call->getArgOperand(0);
34460b57cec5SDimitry Andric InstsToKill.push_back(call);
34470b57cec5SDimitry Andric
34480b57cec5SDimitry Andric // Keep killing bitcasts, for sanity. Note that we no longer care
34490b57cec5SDimitry Andric // about precise ordering as long as there's exactly one use.
34500b57cec5SDimitry Andric while (llvm::BitCastInst *bitcast = dyn_cast<llvm::BitCastInst>(result)) {
34510b57cec5SDimitry Andric if (!bitcast->hasOneUse()) break;
34520b57cec5SDimitry Andric InstsToKill.push_back(bitcast);
34530b57cec5SDimitry Andric result = bitcast->getOperand(0);
34540b57cec5SDimitry Andric }
34550b57cec5SDimitry Andric
34560b57cec5SDimitry Andric // Delete all the unnecessary instructions, from latest to earliest.
34570b57cec5SDimitry Andric for (auto *I : InstsToKill)
34580b57cec5SDimitry Andric I->eraseFromParent();
34590b57cec5SDimitry Andric
34600b57cec5SDimitry Andric // Do the fused retain/autorelease if we were asked to.
34610b57cec5SDimitry Andric if (doRetainAutorelease)
34620b57cec5SDimitry Andric result = CGF.EmitARCRetainAutoreleaseReturnValue(result);
34630b57cec5SDimitry Andric
34640b57cec5SDimitry Andric // Cast back to the result type.
34650b57cec5SDimitry Andric return CGF.Builder.CreateBitCast(result, resultType);
34660b57cec5SDimitry Andric }
34670b57cec5SDimitry Andric
34680b57cec5SDimitry Andric /// If this is a +1 of the value of an immutable 'self', remove it.
tryRemoveRetainOfSelf(CodeGenFunction & CGF,llvm::Value * result)34690b57cec5SDimitry Andric static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
34700b57cec5SDimitry Andric llvm::Value *result) {
34710b57cec5SDimitry Andric // This is only applicable to a method with an immutable 'self'.
34720b57cec5SDimitry Andric const ObjCMethodDecl *method =
34730b57cec5SDimitry Andric dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl);
34740b57cec5SDimitry Andric if (!method) return nullptr;
34750b57cec5SDimitry Andric const VarDecl *self = method->getSelfDecl();
34760b57cec5SDimitry Andric if (!self->getType().isConstQualified()) return nullptr;
34770b57cec5SDimitry Andric
34785f757f3fSDimitry Andric // Look for a retain call. Note: stripPointerCasts looks through returned arg
34795f757f3fSDimitry Andric // functions, which would cause us to miss the retain.
34805f757f3fSDimitry Andric llvm::CallInst *retainCall = dyn_cast<llvm::CallInst>(result);
34815ffd83dbSDimitry Andric if (!retainCall || retainCall->getCalledOperand() !=
34825ffd83dbSDimitry Andric CGF.CGM.getObjCEntrypoints().objc_retain)
34830b57cec5SDimitry Andric return nullptr;
34840b57cec5SDimitry Andric
34850b57cec5SDimitry Andric // Look for an ordinary load of 'self'.
34860b57cec5SDimitry Andric llvm::Value *retainedValue = retainCall->getArgOperand(0);
34870b57cec5SDimitry Andric llvm::LoadInst *load =
34880b57cec5SDimitry Andric dyn_cast<llvm::LoadInst>(retainedValue->stripPointerCasts());
34890b57cec5SDimitry Andric if (!load || load->isAtomic() || load->isVolatile() ||
34900fca6ea1SDimitry Andric load->getPointerOperand() != CGF.GetAddrOfLocalVar(self).getBasePointer())
34910b57cec5SDimitry Andric return nullptr;
34920b57cec5SDimitry Andric
34930b57cec5SDimitry Andric // Okay! Burn it all down. This relies for correctness on the
34940b57cec5SDimitry Andric // assumption that the retain is emitted as part of the return and
34950b57cec5SDimitry Andric // that thereafter everything is used "linearly".
34960b57cec5SDimitry Andric llvm::Type *resultType = result->getType();
34970b57cec5SDimitry Andric eraseUnusedBitCasts(cast<llvm::Instruction>(result));
34980b57cec5SDimitry Andric assert(retainCall->use_empty());
34990b57cec5SDimitry Andric retainCall->eraseFromParent();
35000b57cec5SDimitry Andric eraseUnusedBitCasts(cast<llvm::Instruction>(retainedValue));
35010b57cec5SDimitry Andric
35020b57cec5SDimitry Andric return CGF.Builder.CreateBitCast(load, resultType);
35030b57cec5SDimitry Andric }
35040b57cec5SDimitry Andric
35050b57cec5SDimitry Andric /// Emit an ARC autorelease of the result of a function.
35060b57cec5SDimitry Andric ///
35070b57cec5SDimitry Andric /// \return the value to actually return from the function
emitAutoreleaseOfResult(CodeGenFunction & CGF,llvm::Value * result)35080b57cec5SDimitry Andric static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
35090b57cec5SDimitry Andric llvm::Value *result) {
35100b57cec5SDimitry Andric // If we're returning 'self', kill the initial retain. This is a
35110b57cec5SDimitry Andric // heuristic attempt to "encourage correctness" in the really unfortunate
35120b57cec5SDimitry Andric // case where we have a return of self during a dealloc and we desperately
35130b57cec5SDimitry Andric // need to avoid the possible autorelease.
35140b57cec5SDimitry Andric if (llvm::Value *self = tryRemoveRetainOfSelf(CGF, result))
35150b57cec5SDimitry Andric return self;
35160b57cec5SDimitry Andric
35170b57cec5SDimitry Andric // At -O0, try to emit a fused retain/autorelease.
35180b57cec5SDimitry Andric if (CGF.shouldUseFusedARCCalls())
35190b57cec5SDimitry Andric if (llvm::Value *fused = tryEmitFusedAutoreleaseOfResult(CGF, result))
35200b57cec5SDimitry Andric return fused;
35210b57cec5SDimitry Andric
35220b57cec5SDimitry Andric return CGF.EmitARCAutoreleaseReturnValue(result);
35230b57cec5SDimitry Andric }
35240b57cec5SDimitry Andric
35250b57cec5SDimitry Andric /// Heuristically search for a dominating store to the return-value slot.
findDominatingStoreToReturnValue(CodeGenFunction & CGF)35260b57cec5SDimitry Andric static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
35270fca6ea1SDimitry Andric llvm::Value *ReturnValuePtr = CGF.ReturnValue.getBasePointer();
35280fca6ea1SDimitry Andric
35290b57cec5SDimitry Andric // Check if a User is a store which pointerOperand is the ReturnValue.
35300b57cec5SDimitry Andric // We are looking for stores to the ReturnValue, not for stores of the
35310b57cec5SDimitry Andric // ReturnValue to some other location.
35320fca6ea1SDimitry Andric auto GetStoreIfValid = [&CGF,
35330fca6ea1SDimitry Andric ReturnValuePtr](llvm::User *U) -> llvm::StoreInst * {
35340b57cec5SDimitry Andric auto *SI = dyn_cast<llvm::StoreInst>(U);
35350fca6ea1SDimitry Andric if (!SI || SI->getPointerOperand() != ReturnValuePtr ||
353681ad6265SDimitry Andric SI->getValueOperand()->getType() != CGF.ReturnValue.getElementType())
35370b57cec5SDimitry Andric return nullptr;
35380b57cec5SDimitry Andric // These aren't actually possible for non-coerced returns, and we
35390b57cec5SDimitry Andric // only care about non-coerced returns on this code path.
35405f757f3fSDimitry Andric // All memory instructions inside __try block are volatile.
35415f757f3fSDimitry Andric assert(!SI->isAtomic() &&
35425f757f3fSDimitry Andric (!SI->isVolatile() || CGF.currentFunctionUsesSEHTry()));
35430b57cec5SDimitry Andric return SI;
35440b57cec5SDimitry Andric };
35450b57cec5SDimitry Andric // If there are multiple uses of the return-value slot, just check
35460b57cec5SDimitry Andric // for something immediately preceding the IP. Sometimes this can
35470b57cec5SDimitry Andric // happen with how we generate implicit-returns; it can also happen
35480b57cec5SDimitry Andric // with noreturn cleanups.
35490fca6ea1SDimitry Andric if (!ReturnValuePtr->hasOneUse()) {
35500b57cec5SDimitry Andric llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
35510b57cec5SDimitry Andric if (IP->empty()) return nullptr;
35520b57cec5SDimitry Andric
355381ad6265SDimitry Andric // Look at directly preceding instruction, skipping bitcasts and lifetime
355481ad6265SDimitry Andric // markers.
355581ad6265SDimitry Andric for (llvm::Instruction &I : make_range(IP->rbegin(), IP->rend())) {
355681ad6265SDimitry Andric if (isa<llvm::BitCastInst>(&I))
35570b57cec5SDimitry Andric continue;
355881ad6265SDimitry Andric if (auto *II = dyn_cast<llvm::IntrinsicInst>(&I))
355981ad6265SDimitry Andric if (II->getIntrinsicID() == llvm::Intrinsic::lifetime_end)
356081ad6265SDimitry Andric continue;
35610b57cec5SDimitry Andric
356281ad6265SDimitry Andric return GetStoreIfValid(&I);
356381ad6265SDimitry Andric }
356481ad6265SDimitry Andric return nullptr;
35650b57cec5SDimitry Andric }
35660b57cec5SDimitry Andric
35670fca6ea1SDimitry Andric llvm::StoreInst *store = GetStoreIfValid(ReturnValuePtr->user_back());
35680b57cec5SDimitry Andric if (!store) return nullptr;
35690b57cec5SDimitry Andric
35700b57cec5SDimitry Andric // Now do a first-and-dirty dominance check: just walk up the
35710b57cec5SDimitry Andric // single-predecessors chain from the current insertion point.
35720b57cec5SDimitry Andric llvm::BasicBlock *StoreBB = store->getParent();
35730b57cec5SDimitry Andric llvm::BasicBlock *IP = CGF.Builder.GetInsertBlock();
357406c3fb27SDimitry Andric llvm::SmallPtrSet<llvm::BasicBlock *, 4> SeenBBs;
35750b57cec5SDimitry Andric while (IP != StoreBB) {
357606c3fb27SDimitry Andric if (!SeenBBs.insert(IP).second || !(IP = IP->getSinglePredecessor()))
35770b57cec5SDimitry Andric return nullptr;
35780b57cec5SDimitry Andric }
35790b57cec5SDimitry Andric
35800b57cec5SDimitry Andric // Okay, the store's basic block dominates the insertion point; we
35810b57cec5SDimitry Andric // can do our thing.
35820b57cec5SDimitry Andric return store;
35830b57cec5SDimitry Andric }
35840b57cec5SDimitry Andric
35855ffd83dbSDimitry Andric // Helper functions for EmitCMSEClearRecord
35865ffd83dbSDimitry Andric
35875ffd83dbSDimitry Andric // Set the bits corresponding to a field having width `BitWidth` and located at
35885ffd83dbSDimitry Andric // offset `BitOffset` (from the least significant bit) within a storage unit of
35895ffd83dbSDimitry Andric // `Bits.size()` bytes. Each element of `Bits` corresponds to one target byte.
35905ffd83dbSDimitry Andric // Use little-endian layout, i.e.`Bits[0]` is the LSB.
setBitRange(SmallVectorImpl<uint64_t> & Bits,int BitOffset,int BitWidth,int CharWidth)35915ffd83dbSDimitry Andric static void setBitRange(SmallVectorImpl<uint64_t> &Bits, int BitOffset,
35925ffd83dbSDimitry Andric int BitWidth, int CharWidth) {
35935ffd83dbSDimitry Andric assert(CharWidth <= 64);
35945ffd83dbSDimitry Andric assert(static_cast<unsigned>(BitWidth) <= Bits.size() * CharWidth);
35955ffd83dbSDimitry Andric
35965ffd83dbSDimitry Andric int Pos = 0;
35975ffd83dbSDimitry Andric if (BitOffset >= CharWidth) {
35985ffd83dbSDimitry Andric Pos += BitOffset / CharWidth;
35995ffd83dbSDimitry Andric BitOffset = BitOffset % CharWidth;
36005ffd83dbSDimitry Andric }
36015ffd83dbSDimitry Andric
36025ffd83dbSDimitry Andric const uint64_t Used = (uint64_t(1) << CharWidth) - 1;
36035ffd83dbSDimitry Andric if (BitOffset + BitWidth >= CharWidth) {
36045ffd83dbSDimitry Andric Bits[Pos++] |= (Used << BitOffset) & Used;
36055ffd83dbSDimitry Andric BitWidth -= CharWidth - BitOffset;
36065ffd83dbSDimitry Andric BitOffset = 0;
36075ffd83dbSDimitry Andric }
36085ffd83dbSDimitry Andric
36095ffd83dbSDimitry Andric while (BitWidth >= CharWidth) {
36105ffd83dbSDimitry Andric Bits[Pos++] = Used;
36115ffd83dbSDimitry Andric BitWidth -= CharWidth;
36125ffd83dbSDimitry Andric }
36135ffd83dbSDimitry Andric
36145ffd83dbSDimitry Andric if (BitWidth > 0)
36155ffd83dbSDimitry Andric Bits[Pos++] |= (Used >> (CharWidth - BitWidth)) << BitOffset;
36165ffd83dbSDimitry Andric }
36175ffd83dbSDimitry Andric
36185ffd83dbSDimitry Andric // Set the bits corresponding to a field having width `BitWidth` and located at
36195ffd83dbSDimitry Andric // offset `BitOffset` (from the least significant bit) within a storage unit of
36205ffd83dbSDimitry Andric // `StorageSize` bytes, located at `StorageOffset` in `Bits`. Each element of
36215ffd83dbSDimitry 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)36225ffd83dbSDimitry Andric static void setBitRange(SmallVectorImpl<uint64_t> &Bits, int StorageOffset,
36235ffd83dbSDimitry Andric int StorageSize, int BitOffset, int BitWidth,
36245ffd83dbSDimitry Andric int CharWidth, bool BigEndian) {
36255ffd83dbSDimitry Andric
36265ffd83dbSDimitry Andric SmallVector<uint64_t, 8> TmpBits(StorageSize);
36275ffd83dbSDimitry Andric setBitRange(TmpBits, BitOffset, BitWidth, CharWidth);
36285ffd83dbSDimitry Andric
36295ffd83dbSDimitry Andric if (BigEndian)
36305ffd83dbSDimitry Andric std::reverse(TmpBits.begin(), TmpBits.end());
36315ffd83dbSDimitry Andric
36325ffd83dbSDimitry Andric for (uint64_t V : TmpBits)
36335ffd83dbSDimitry Andric Bits[StorageOffset++] |= V;
36345ffd83dbSDimitry Andric }
36355ffd83dbSDimitry Andric
36365ffd83dbSDimitry Andric static void setUsedBits(CodeGenModule &, QualType, int,
36375ffd83dbSDimitry Andric SmallVectorImpl<uint64_t> &);
36385ffd83dbSDimitry Andric
36395ffd83dbSDimitry Andric // Set the bits in `Bits`, which correspond to the value representations of
36405ffd83dbSDimitry Andric // the actual members of the record type `RTy`. Note that this function does
36415ffd83dbSDimitry Andric // not handle base classes, virtual tables, etc, since they cannot happen in
36425ffd83dbSDimitry Andric // CMSE function arguments or return. The bit mask corresponds to the target
36435ffd83dbSDimitry Andric // memory layout, i.e. it's endian dependent.
setUsedBits(CodeGenModule & CGM,const RecordType * RTy,int Offset,SmallVectorImpl<uint64_t> & Bits)36445ffd83dbSDimitry Andric static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset,
36455ffd83dbSDimitry Andric SmallVectorImpl<uint64_t> &Bits) {
36465ffd83dbSDimitry Andric ASTContext &Context = CGM.getContext();
36475ffd83dbSDimitry Andric int CharWidth = Context.getCharWidth();
36485ffd83dbSDimitry Andric const RecordDecl *RD = RTy->getDecl()->getDefinition();
36495ffd83dbSDimitry Andric const ASTRecordLayout &ASTLayout = Context.getASTRecordLayout(RD);
36505ffd83dbSDimitry Andric const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD);
36515ffd83dbSDimitry Andric
36525ffd83dbSDimitry Andric int Idx = 0;
36535ffd83dbSDimitry Andric for (auto I = RD->field_begin(), E = RD->field_end(); I != E; ++I, ++Idx) {
36545ffd83dbSDimitry Andric const FieldDecl *F = *I;
36555ffd83dbSDimitry Andric
36560fca6ea1SDimitry Andric if (F->isUnnamedBitField() || F->isZeroLengthBitField(Context) ||
36575ffd83dbSDimitry Andric F->getType()->isIncompleteArrayType())
36585ffd83dbSDimitry Andric continue;
36595ffd83dbSDimitry Andric
36605ffd83dbSDimitry Andric if (F->isBitField()) {
36615ffd83dbSDimitry Andric const CGBitFieldInfo &BFI = Layout.getBitFieldInfo(F);
36625ffd83dbSDimitry Andric setBitRange(Bits, Offset + BFI.StorageOffset.getQuantity(),
36635ffd83dbSDimitry Andric BFI.StorageSize / CharWidth, BFI.Offset,
36645ffd83dbSDimitry Andric BFI.Size, CharWidth,
36655ffd83dbSDimitry Andric CGM.getDataLayout().isBigEndian());
36665ffd83dbSDimitry Andric continue;
36675ffd83dbSDimitry Andric }
36685ffd83dbSDimitry Andric
36695ffd83dbSDimitry Andric setUsedBits(CGM, F->getType(),
36705ffd83dbSDimitry Andric Offset + ASTLayout.getFieldOffset(Idx) / CharWidth, Bits);
36715ffd83dbSDimitry Andric }
36725ffd83dbSDimitry Andric }
36735ffd83dbSDimitry Andric
36745ffd83dbSDimitry Andric // Set the bits in `Bits`, which correspond to the value representations of
36755ffd83dbSDimitry Andric // the elements of an array type `ATy`.
setUsedBits(CodeGenModule & CGM,const ConstantArrayType * ATy,int Offset,SmallVectorImpl<uint64_t> & Bits)36765ffd83dbSDimitry Andric static void setUsedBits(CodeGenModule &CGM, const ConstantArrayType *ATy,
36775ffd83dbSDimitry Andric int Offset, SmallVectorImpl<uint64_t> &Bits) {
36785ffd83dbSDimitry Andric const ASTContext &Context = CGM.getContext();
36795ffd83dbSDimitry Andric
36805ffd83dbSDimitry Andric QualType ETy = Context.getBaseElementType(ATy);
36815ffd83dbSDimitry Andric int Size = Context.getTypeSizeInChars(ETy).getQuantity();
36825ffd83dbSDimitry Andric SmallVector<uint64_t, 4> TmpBits(Size);
36835ffd83dbSDimitry Andric setUsedBits(CGM, ETy, 0, TmpBits);
36845ffd83dbSDimitry Andric
36855ffd83dbSDimitry Andric for (int I = 0, N = Context.getConstantArrayElementCount(ATy); I < N; ++I) {
36865ffd83dbSDimitry Andric auto Src = TmpBits.begin();
36875ffd83dbSDimitry Andric auto Dst = Bits.begin() + Offset + I * Size;
36885ffd83dbSDimitry Andric for (int J = 0; J < Size; ++J)
36895ffd83dbSDimitry Andric *Dst++ |= *Src++;
36905ffd83dbSDimitry Andric }
36915ffd83dbSDimitry Andric }
36925ffd83dbSDimitry Andric
36935ffd83dbSDimitry Andric // Set the bits in `Bits`, which correspond to the value representations of
36945ffd83dbSDimitry Andric // the type `QTy`.
setUsedBits(CodeGenModule & CGM,QualType QTy,int Offset,SmallVectorImpl<uint64_t> & Bits)36955ffd83dbSDimitry Andric static void setUsedBits(CodeGenModule &CGM, QualType QTy, int Offset,
36965ffd83dbSDimitry Andric SmallVectorImpl<uint64_t> &Bits) {
36975ffd83dbSDimitry Andric if (const auto *RTy = QTy->getAs<RecordType>())
36985ffd83dbSDimitry Andric return setUsedBits(CGM, RTy, Offset, Bits);
36995ffd83dbSDimitry Andric
37005ffd83dbSDimitry Andric ASTContext &Context = CGM.getContext();
37015ffd83dbSDimitry Andric if (const auto *ATy = Context.getAsConstantArrayType(QTy))
37025ffd83dbSDimitry Andric return setUsedBits(CGM, ATy, Offset, Bits);
37035ffd83dbSDimitry Andric
37045ffd83dbSDimitry Andric int Size = Context.getTypeSizeInChars(QTy).getQuantity();
37055ffd83dbSDimitry Andric if (Size <= 0)
37065ffd83dbSDimitry Andric return;
37075ffd83dbSDimitry Andric
37085ffd83dbSDimitry Andric std::fill_n(Bits.begin() + Offset, Size,
37095ffd83dbSDimitry Andric (uint64_t(1) << Context.getCharWidth()) - 1);
37105ffd83dbSDimitry Andric }
37115ffd83dbSDimitry Andric
buildMultiCharMask(const SmallVectorImpl<uint64_t> & Bits,int Pos,int Size,int CharWidth,bool BigEndian)37125ffd83dbSDimitry Andric static uint64_t buildMultiCharMask(const SmallVectorImpl<uint64_t> &Bits,
37135ffd83dbSDimitry Andric int Pos, int Size, int CharWidth,
37145ffd83dbSDimitry Andric bool BigEndian) {
37155ffd83dbSDimitry Andric assert(Size > 0);
37165ffd83dbSDimitry Andric uint64_t Mask = 0;
37175ffd83dbSDimitry Andric if (BigEndian) {
37185ffd83dbSDimitry Andric for (auto P = Bits.begin() + Pos, E = Bits.begin() + Pos + Size; P != E;
37195ffd83dbSDimitry Andric ++P)
37205ffd83dbSDimitry Andric Mask = (Mask << CharWidth) | *P;
37215ffd83dbSDimitry Andric } else {
37225ffd83dbSDimitry Andric auto P = Bits.begin() + Pos + Size, End = Bits.begin() + Pos;
37235ffd83dbSDimitry Andric do
37245ffd83dbSDimitry Andric Mask = (Mask << CharWidth) | *--P;
37255ffd83dbSDimitry Andric while (P != End);
37265ffd83dbSDimitry Andric }
37275ffd83dbSDimitry Andric return Mask;
37285ffd83dbSDimitry Andric }
37295ffd83dbSDimitry Andric
37305ffd83dbSDimitry Andric // Emit code to clear the bits in a record, which aren't a part of any user
37315ffd83dbSDimitry Andric // declared member, when the record is a function return.
EmitCMSEClearRecord(llvm::Value * Src,llvm::IntegerType * ITy,QualType QTy)37325ffd83dbSDimitry Andric llvm::Value *CodeGenFunction::EmitCMSEClearRecord(llvm::Value *Src,
37335ffd83dbSDimitry Andric llvm::IntegerType *ITy,
37345ffd83dbSDimitry Andric QualType QTy) {
37355ffd83dbSDimitry Andric assert(Src->getType() == ITy);
37365ffd83dbSDimitry Andric assert(ITy->getScalarSizeInBits() <= 64);
37375ffd83dbSDimitry Andric
37385ffd83dbSDimitry Andric const llvm::DataLayout &DataLayout = CGM.getDataLayout();
37395ffd83dbSDimitry Andric int Size = DataLayout.getTypeStoreSize(ITy);
37405ffd83dbSDimitry Andric SmallVector<uint64_t, 4> Bits(Size);
3741e8d8bef9SDimitry Andric setUsedBits(CGM, QTy->castAs<RecordType>(), 0, Bits);
37425ffd83dbSDimitry Andric
37435ffd83dbSDimitry Andric int CharWidth = CGM.getContext().getCharWidth();
37445ffd83dbSDimitry Andric uint64_t Mask =
37455ffd83dbSDimitry Andric buildMultiCharMask(Bits, 0, Size, CharWidth, DataLayout.isBigEndian());
37465ffd83dbSDimitry Andric
37475ffd83dbSDimitry Andric return Builder.CreateAnd(Src, Mask, "cmse.clear");
37485ffd83dbSDimitry Andric }
37495ffd83dbSDimitry Andric
37505ffd83dbSDimitry Andric // Emit code to clear the bits in a record, which aren't a part of any user
37515ffd83dbSDimitry Andric // declared member, when the record is a function argument.
EmitCMSEClearRecord(llvm::Value * Src,llvm::ArrayType * ATy,QualType QTy)37525ffd83dbSDimitry Andric llvm::Value *CodeGenFunction::EmitCMSEClearRecord(llvm::Value *Src,
37535ffd83dbSDimitry Andric llvm::ArrayType *ATy,
37545ffd83dbSDimitry Andric QualType QTy) {
37555ffd83dbSDimitry Andric const llvm::DataLayout &DataLayout = CGM.getDataLayout();
37565ffd83dbSDimitry Andric int Size = DataLayout.getTypeStoreSize(ATy);
37575ffd83dbSDimitry Andric SmallVector<uint64_t, 16> Bits(Size);
3758e8d8bef9SDimitry Andric setUsedBits(CGM, QTy->castAs<RecordType>(), 0, Bits);
37595ffd83dbSDimitry Andric
37605ffd83dbSDimitry Andric // Clear each element of the LLVM array.
37615ffd83dbSDimitry Andric int CharWidth = CGM.getContext().getCharWidth();
37625ffd83dbSDimitry Andric int CharsPerElt =
37635ffd83dbSDimitry Andric ATy->getArrayElementType()->getScalarSizeInBits() / CharWidth;
37645ffd83dbSDimitry Andric int MaskIndex = 0;
376581ad6265SDimitry Andric llvm::Value *R = llvm::PoisonValue::get(ATy);
37665ffd83dbSDimitry Andric for (int I = 0, N = ATy->getArrayNumElements(); I != N; ++I) {
37675ffd83dbSDimitry Andric uint64_t Mask = buildMultiCharMask(Bits, MaskIndex, CharsPerElt, CharWidth,
37685ffd83dbSDimitry Andric DataLayout.isBigEndian());
37695ffd83dbSDimitry Andric MaskIndex += CharsPerElt;
37705ffd83dbSDimitry Andric llvm::Value *T0 = Builder.CreateExtractValue(Src, I);
37715ffd83dbSDimitry Andric llvm::Value *T1 = Builder.CreateAnd(T0, Mask, "cmse.clear");
37725ffd83dbSDimitry Andric R = Builder.CreateInsertValue(R, T1, I);
37735ffd83dbSDimitry Andric }
37745ffd83dbSDimitry Andric
37755ffd83dbSDimitry Andric return R;
37765ffd83dbSDimitry Andric }
37775ffd83dbSDimitry Andric
EmitFunctionEpilog(const CGFunctionInfo & FI,bool EmitRetDbgLoc,SourceLocation EndLoc)37780b57cec5SDimitry Andric void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI,
37790b57cec5SDimitry Andric bool EmitRetDbgLoc,
37800b57cec5SDimitry Andric SourceLocation EndLoc) {
37810b57cec5SDimitry Andric if (FI.isNoReturn()) {
37820b57cec5SDimitry Andric // Noreturn functions don't return.
37830b57cec5SDimitry Andric EmitUnreachable(EndLoc);
37840b57cec5SDimitry Andric return;
37850b57cec5SDimitry Andric }
37860b57cec5SDimitry Andric
37870b57cec5SDimitry Andric if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>()) {
37880b57cec5SDimitry Andric // Naked functions don't have epilogues.
37890b57cec5SDimitry Andric Builder.CreateUnreachable();
37900b57cec5SDimitry Andric return;
37910b57cec5SDimitry Andric }
37920b57cec5SDimitry Andric
37930b57cec5SDimitry Andric // Functions with no result always return void.
37940b57cec5SDimitry Andric if (!ReturnValue.isValid()) {
37950b57cec5SDimitry Andric Builder.CreateRetVoid();
37960b57cec5SDimitry Andric return;
37970b57cec5SDimitry Andric }
37980b57cec5SDimitry Andric
37990b57cec5SDimitry Andric llvm::DebugLoc RetDbgLoc;
38000b57cec5SDimitry Andric llvm::Value *RV = nullptr;
38010b57cec5SDimitry Andric QualType RetTy = FI.getReturnType();
38020b57cec5SDimitry Andric const ABIArgInfo &RetAI = FI.getReturnInfo();
38030b57cec5SDimitry Andric
38040b57cec5SDimitry Andric switch (RetAI.getKind()) {
38050b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
3806bdd1243dSDimitry Andric // Aggregates get evaluated directly into the destination. Sometimes we
38070b57cec5SDimitry Andric // need to return the sret value in a register, though.
38080b57cec5SDimitry Andric assert(hasAggregateEvaluationKind(RetTy));
38090b57cec5SDimitry Andric if (RetAI.getInAllocaSRet()) {
38100b57cec5SDimitry Andric llvm::Function::arg_iterator EI = CurFn->arg_end();
38110b57cec5SDimitry Andric --EI;
38120b57cec5SDimitry Andric llvm::Value *ArgStruct = &*EI;
38130b57cec5SDimitry Andric llvm::Value *SRet = Builder.CreateStructGEP(
381481ad6265SDimitry Andric FI.getArgStruct(), ArgStruct, RetAI.getInAllocaFieldIndex());
3815fe6060f1SDimitry Andric llvm::Type *Ty =
3816fe6060f1SDimitry Andric cast<llvm::GetElementPtrInst>(SRet)->getResultElementType();
3817fe6060f1SDimitry Andric RV = Builder.CreateAlignedLoad(Ty, SRet, getPointerAlign(), "sret");
38180b57cec5SDimitry Andric }
38190b57cec5SDimitry Andric break;
38200b57cec5SDimitry Andric
38210b57cec5SDimitry Andric case ABIArgInfo::Indirect: {
38220b57cec5SDimitry Andric auto AI = CurFn->arg_begin();
38230b57cec5SDimitry Andric if (RetAI.isSRetAfterThis())
38240b57cec5SDimitry Andric ++AI;
38250b57cec5SDimitry Andric switch (getEvaluationKind(RetTy)) {
38260b57cec5SDimitry Andric case TEK_Complex: {
38270b57cec5SDimitry Andric ComplexPairTy RT =
38280b57cec5SDimitry Andric EmitLoadOfComplex(MakeAddrLValue(ReturnValue, RetTy), EndLoc);
38290b57cec5SDimitry Andric EmitStoreOfComplex(RT, MakeNaturalAlignAddrLValue(&*AI, RetTy),
38300b57cec5SDimitry Andric /*isInit*/ true);
38310b57cec5SDimitry Andric break;
38320b57cec5SDimitry Andric }
38330b57cec5SDimitry Andric case TEK_Aggregate:
3834bdd1243dSDimitry Andric // Do nothing; aggregates get evaluated directly into the destination.
38350b57cec5SDimitry Andric break;
38360eae32dcSDimitry Andric case TEK_Scalar: {
38370eae32dcSDimitry Andric LValueBaseInfo BaseInfo;
38380eae32dcSDimitry Andric TBAAAccessInfo TBAAInfo;
38390eae32dcSDimitry Andric CharUnits Alignment =
38400eae32dcSDimitry Andric CGM.getNaturalTypeAlignment(RetTy, &BaseInfo, &TBAAInfo);
38410eae32dcSDimitry Andric Address ArgAddr(&*AI, ConvertType(RetTy), Alignment);
38420eae32dcSDimitry Andric LValue ArgVal =
38430eae32dcSDimitry Andric LValue::MakeAddr(ArgAddr, RetTy, getContext(), BaseInfo, TBAAInfo);
38440eae32dcSDimitry Andric EmitStoreOfScalar(
38450fca6ea1SDimitry Andric EmitLoadOfScalar(MakeAddrLValue(ReturnValue, RetTy), EndLoc), ArgVal,
38460fca6ea1SDimitry Andric /*isInit*/ true);
38470b57cec5SDimitry Andric break;
38480b57cec5SDimitry Andric }
38490eae32dcSDimitry Andric }
38500b57cec5SDimitry Andric break;
38510b57cec5SDimitry Andric }
38520b57cec5SDimitry Andric
38530b57cec5SDimitry Andric case ABIArgInfo::Extend:
38540b57cec5SDimitry Andric case ABIArgInfo::Direct:
38550b57cec5SDimitry Andric if (RetAI.getCoerceToType() == ConvertType(RetTy) &&
38560b57cec5SDimitry Andric RetAI.getDirectOffset() == 0) {
38570b57cec5SDimitry Andric // The internal return value temp always will have pointer-to-return-type
38580b57cec5SDimitry Andric // type, just do a load.
38590b57cec5SDimitry Andric
38600b57cec5SDimitry Andric // If there is a dominating store to ReturnValue, we can elide
38610b57cec5SDimitry Andric // the load, zap the store, and usually zap the alloca.
38620b57cec5SDimitry Andric if (llvm::StoreInst *SI =
38630b57cec5SDimitry Andric findDominatingStoreToReturnValue(*this)) {
38640b57cec5SDimitry Andric // Reuse the debug location from the store unless there is
38650b57cec5SDimitry Andric // cleanup code to be emitted between the store and return
38660b57cec5SDimitry Andric // instruction.
38670b57cec5SDimitry Andric if (EmitRetDbgLoc && !AutoreleaseResult)
38680b57cec5SDimitry Andric RetDbgLoc = SI->getDebugLoc();
38690b57cec5SDimitry Andric // Get the stored value and nuke the now-dead store.
38700b57cec5SDimitry Andric RV = SI->getValueOperand();
38710b57cec5SDimitry Andric SI->eraseFromParent();
38720b57cec5SDimitry Andric
38730b57cec5SDimitry Andric // Otherwise, we have to do a simple load.
38740b57cec5SDimitry Andric } else {
38750b57cec5SDimitry Andric RV = Builder.CreateLoad(ReturnValue);
38760b57cec5SDimitry Andric }
38770b57cec5SDimitry Andric } else {
38780b57cec5SDimitry Andric // If the value is offset in memory, apply the offset now.
38790b57cec5SDimitry Andric Address V = emitAddressAtOffset(*this, ReturnValue, RetAI);
38800b57cec5SDimitry Andric
38810b57cec5SDimitry Andric RV = CreateCoercedLoad(V, RetAI.getCoerceToType(), *this);
38820b57cec5SDimitry Andric }
38830b57cec5SDimitry Andric
38840b57cec5SDimitry Andric // In ARC, end functions that return a retainable type with a call
38850b57cec5SDimitry Andric // to objc_autoreleaseReturnValue.
38860b57cec5SDimitry Andric if (AutoreleaseResult) {
38870b57cec5SDimitry Andric #ifndef NDEBUG
38880b57cec5SDimitry Andric // Type::isObjCRetainabletype has to be called on a QualType that hasn't
38890b57cec5SDimitry Andric // been stripped of the typedefs, so we cannot use RetTy here. Get the
38900b57cec5SDimitry Andric // original return type of FunctionDecl, CurCodeDecl, and BlockDecl from
38910b57cec5SDimitry Andric // CurCodeDecl or BlockInfo.
38920b57cec5SDimitry Andric QualType RT;
38930b57cec5SDimitry Andric
38940b57cec5SDimitry Andric if (auto *FD = dyn_cast<FunctionDecl>(CurCodeDecl))
38950b57cec5SDimitry Andric RT = FD->getReturnType();
38960b57cec5SDimitry Andric else if (auto *MD = dyn_cast<ObjCMethodDecl>(CurCodeDecl))
38970b57cec5SDimitry Andric RT = MD->getReturnType();
38980b57cec5SDimitry Andric else if (isa<BlockDecl>(CurCodeDecl))
38990b57cec5SDimitry Andric RT = BlockInfo->BlockExpression->getFunctionType()->getReturnType();
39000b57cec5SDimitry Andric else
39010b57cec5SDimitry Andric llvm_unreachable("Unexpected function/method type");
39020b57cec5SDimitry Andric
39030b57cec5SDimitry Andric assert(getLangOpts().ObjCAutoRefCount &&
39040b57cec5SDimitry Andric !FI.isReturnsRetained() &&
39050b57cec5SDimitry Andric RT->isObjCRetainableType());
39060b57cec5SDimitry Andric #endif
39070b57cec5SDimitry Andric RV = emitAutoreleaseOfResult(*this, RV);
39080b57cec5SDimitry Andric }
39090b57cec5SDimitry Andric
39100b57cec5SDimitry Andric break;
39110b57cec5SDimitry Andric
39120b57cec5SDimitry Andric case ABIArgInfo::Ignore:
39130b57cec5SDimitry Andric break;
39140b57cec5SDimitry Andric
39150b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand: {
39160b57cec5SDimitry Andric auto coercionType = RetAI.getCoerceAndExpandType();
39170b57cec5SDimitry Andric
39180b57cec5SDimitry Andric // Load all of the coerced elements out into results.
39190b57cec5SDimitry Andric llvm::SmallVector<llvm::Value*, 4> results;
392006c3fb27SDimitry Andric Address addr = ReturnValue.withElementType(coercionType);
39210b57cec5SDimitry Andric for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
39220b57cec5SDimitry Andric auto coercedEltType = coercionType->getElementType(i);
39230b57cec5SDimitry Andric if (ABIArgInfo::isPaddingForCoerceAndExpand(coercedEltType))
39240b57cec5SDimitry Andric continue;
39250b57cec5SDimitry Andric
39260b57cec5SDimitry Andric auto eltAddr = Builder.CreateStructGEP(addr, i);
39270b57cec5SDimitry Andric auto elt = Builder.CreateLoad(eltAddr);
39280b57cec5SDimitry Andric results.push_back(elt);
39290b57cec5SDimitry Andric }
39300b57cec5SDimitry Andric
39310b57cec5SDimitry Andric // If we have one result, it's the single direct result type.
39320b57cec5SDimitry Andric if (results.size() == 1) {
39330b57cec5SDimitry Andric RV = results[0];
39340b57cec5SDimitry Andric
39350b57cec5SDimitry Andric // Otherwise, we need to make a first-class aggregate.
39360b57cec5SDimitry Andric } else {
39370b57cec5SDimitry Andric // Construct a return type that lacks padding elements.
39380b57cec5SDimitry Andric llvm::Type *returnType = RetAI.getUnpaddedCoerceAndExpandType();
39390b57cec5SDimitry Andric
394081ad6265SDimitry Andric RV = llvm::PoisonValue::get(returnType);
39410b57cec5SDimitry Andric for (unsigned i = 0, e = results.size(); i != e; ++i) {
39420b57cec5SDimitry Andric RV = Builder.CreateInsertValue(RV, results[i], i);
39430b57cec5SDimitry Andric }
39440b57cec5SDimitry Andric }
39450b57cec5SDimitry Andric break;
39460b57cec5SDimitry Andric }
39470b57cec5SDimitry Andric case ABIArgInfo::Expand:
3948e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased:
39490b57cec5SDimitry Andric llvm_unreachable("Invalid ABI kind for return argument");
39500b57cec5SDimitry Andric }
39510b57cec5SDimitry Andric
39520b57cec5SDimitry Andric llvm::Instruction *Ret;
39530b57cec5SDimitry Andric if (RV) {
39545ffd83dbSDimitry Andric if (CurFuncDecl && CurFuncDecl->hasAttr<CmseNSEntryAttr>()) {
39555ffd83dbSDimitry Andric // For certain return types, clear padding bits, as they may reveal
39565ffd83dbSDimitry Andric // sensitive information.
39575ffd83dbSDimitry Andric // Small struct/union types are passed as integers.
39585ffd83dbSDimitry Andric auto *ITy = dyn_cast<llvm::IntegerType>(RV->getType());
39595ffd83dbSDimitry Andric if (ITy != nullptr && isa<RecordType>(RetTy.getCanonicalType()))
39605ffd83dbSDimitry Andric RV = EmitCMSEClearRecord(RV, ITy, RetTy);
39615ffd83dbSDimitry Andric }
39620b57cec5SDimitry Andric EmitReturnValueCheck(RV);
39630b57cec5SDimitry Andric Ret = Builder.CreateRet(RV);
39640b57cec5SDimitry Andric } else {
39650b57cec5SDimitry Andric Ret = Builder.CreateRetVoid();
39660b57cec5SDimitry Andric }
39670b57cec5SDimitry Andric
39680b57cec5SDimitry Andric if (RetDbgLoc)
39690b57cec5SDimitry Andric Ret->setDebugLoc(std::move(RetDbgLoc));
39700b57cec5SDimitry Andric }
39710b57cec5SDimitry Andric
EmitReturnValueCheck(llvm::Value * RV)39720b57cec5SDimitry Andric void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV) {
39730b57cec5SDimitry Andric // A current decl may not be available when emitting vtable thunks.
39740b57cec5SDimitry Andric if (!CurCodeDecl)
39750b57cec5SDimitry Andric return;
39760b57cec5SDimitry Andric
39775ffd83dbSDimitry Andric // If the return block isn't reachable, neither is this check, so don't emit
39785ffd83dbSDimitry Andric // it.
39795ffd83dbSDimitry Andric if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty())
39805ffd83dbSDimitry Andric return;
39815ffd83dbSDimitry Andric
39820b57cec5SDimitry Andric ReturnsNonNullAttr *RetNNAttr = nullptr;
39830b57cec5SDimitry Andric if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
39840b57cec5SDimitry Andric RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>();
39850b57cec5SDimitry Andric
39860b57cec5SDimitry Andric if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
39870b57cec5SDimitry Andric return;
39880b57cec5SDimitry Andric
39890b57cec5SDimitry Andric // Prefer the returns_nonnull attribute if it's present.
39900b57cec5SDimitry Andric SourceLocation AttrLoc;
39910b57cec5SDimitry Andric SanitizerMask CheckKind;
39920b57cec5SDimitry Andric SanitizerHandler Handler;
39930b57cec5SDimitry Andric if (RetNNAttr) {
39940b57cec5SDimitry Andric assert(!requiresReturnValueNullabilityCheck() &&
39950b57cec5SDimitry Andric "Cannot check nullability and the nonnull attribute");
39960b57cec5SDimitry Andric AttrLoc = RetNNAttr->getLocation();
39970b57cec5SDimitry Andric CheckKind = SanitizerKind::ReturnsNonnullAttribute;
39980b57cec5SDimitry Andric Handler = SanitizerHandler::NonnullReturn;
39990b57cec5SDimitry Andric } else {
40000b57cec5SDimitry Andric if (auto *DD = dyn_cast<DeclaratorDecl>(CurCodeDecl))
40010b57cec5SDimitry Andric if (auto *TSI = DD->getTypeSourceInfo())
40025ffd83dbSDimitry Andric if (auto FTL = TSI->getTypeLoc().getAsAdjusted<FunctionTypeLoc>())
40030b57cec5SDimitry Andric AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
40040b57cec5SDimitry Andric CheckKind = SanitizerKind::NullabilityReturn;
40050b57cec5SDimitry Andric Handler = SanitizerHandler::NullabilityReturn;
40060b57cec5SDimitry Andric }
40070b57cec5SDimitry Andric
40080b57cec5SDimitry Andric SanitizerScope SanScope(this);
40090b57cec5SDimitry Andric
40100b57cec5SDimitry Andric // Make sure the "return" source location is valid. If we're checking a
40110b57cec5SDimitry Andric // nullability annotation, make sure the preconditions for the check are met.
40120b57cec5SDimitry Andric llvm::BasicBlock *Check = createBasicBlock("nullcheck");
40130b57cec5SDimitry Andric llvm::BasicBlock *NoCheck = createBasicBlock("no.nullcheck");
40140b57cec5SDimitry Andric llvm::Value *SLocPtr = Builder.CreateLoad(ReturnLocation, "return.sloc.load");
40150b57cec5SDimitry Andric llvm::Value *CanNullCheck = Builder.CreateIsNotNull(SLocPtr);
40160b57cec5SDimitry Andric if (requiresReturnValueNullabilityCheck())
40170b57cec5SDimitry Andric CanNullCheck =
40180b57cec5SDimitry Andric Builder.CreateAnd(CanNullCheck, RetValNullabilityPrecondition);
40190b57cec5SDimitry Andric Builder.CreateCondBr(CanNullCheck, Check, NoCheck);
40200b57cec5SDimitry Andric EmitBlock(Check);
40210b57cec5SDimitry Andric
40220b57cec5SDimitry Andric // Now do the null check.
40230b57cec5SDimitry Andric llvm::Value *Cond = Builder.CreateIsNotNull(RV);
40240b57cec5SDimitry Andric llvm::Constant *StaticData[] = {EmitCheckSourceLocation(AttrLoc)};
40250b57cec5SDimitry Andric llvm::Value *DynamicData[] = {SLocPtr};
40260b57cec5SDimitry Andric EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, DynamicData);
40270b57cec5SDimitry Andric
40280b57cec5SDimitry Andric EmitBlock(NoCheck);
40290b57cec5SDimitry Andric
40300b57cec5SDimitry Andric #ifndef NDEBUG
40310b57cec5SDimitry Andric // The return location should not be used after the check has been emitted.
40320b57cec5SDimitry Andric ReturnLocation = Address::invalid();
40330b57cec5SDimitry Andric #endif
40340b57cec5SDimitry Andric }
40350b57cec5SDimitry Andric
isInAllocaArgument(CGCXXABI & ABI,QualType type)40360b57cec5SDimitry Andric static bool isInAllocaArgument(CGCXXABI &ABI, QualType type) {
40370b57cec5SDimitry Andric const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
40380b57cec5SDimitry Andric return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
40390b57cec5SDimitry Andric }
40400b57cec5SDimitry Andric
createPlaceholderSlot(CodeGenFunction & CGF,QualType Ty)40410b57cec5SDimitry Andric static AggValueSlot createPlaceholderSlot(CodeGenFunction &CGF,
40420b57cec5SDimitry Andric QualType Ty) {
40430b57cec5SDimitry Andric // FIXME: Generate IR in one pass, rather than going back and fixing up these
40440b57cec5SDimitry Andric // placeholders.
40450b57cec5SDimitry Andric llvm::Type *IRTy = CGF.ConvertTypeForMem(Ty);
404606c3fb27SDimitry Andric llvm::Type *IRPtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
404706c3fb27SDimitry Andric llvm::Value *Placeholder = llvm::PoisonValue::get(IRPtrTy);
40480b57cec5SDimitry Andric
40490b57cec5SDimitry Andric // FIXME: When we generate this IR in one pass, we shouldn't need
40500b57cec5SDimitry Andric // this win32-specific alignment hack.
40510b57cec5SDimitry Andric CharUnits Align = CharUnits::fromQuantity(4);
40520b57cec5SDimitry Andric Placeholder = CGF.Builder.CreateAlignedLoad(IRPtrTy, Placeholder, Align);
40530b57cec5SDimitry Andric
405481ad6265SDimitry Andric return AggValueSlot::forAddr(Address(Placeholder, IRTy, Align),
40550b57cec5SDimitry Andric Ty.getQualifiers(),
40560b57cec5SDimitry Andric AggValueSlot::IsNotDestructed,
40570b57cec5SDimitry Andric AggValueSlot::DoesNotNeedGCBarriers,
40580b57cec5SDimitry Andric AggValueSlot::IsNotAliased,
40590b57cec5SDimitry Andric AggValueSlot::DoesNotOverlap);
40600b57cec5SDimitry Andric }
40610b57cec5SDimitry Andric
EmitDelegateCallArg(CallArgList & args,const VarDecl * param,SourceLocation loc)40620b57cec5SDimitry Andric void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
40630b57cec5SDimitry Andric const VarDecl *param,
40640b57cec5SDimitry Andric SourceLocation loc) {
40650b57cec5SDimitry Andric // StartFunction converted the ABI-lowered parameter(s) into a
40660b57cec5SDimitry Andric // local alloca. We need to turn that into an r-value suitable
40670b57cec5SDimitry Andric // for EmitCall.
40680b57cec5SDimitry Andric Address local = GetAddrOfLocalVar(param);
40690b57cec5SDimitry Andric
40700b57cec5SDimitry Andric QualType type = param->getType();
40710b57cec5SDimitry Andric
40720b57cec5SDimitry Andric // GetAddrOfLocalVar returns a pointer-to-pointer for references,
40730b57cec5SDimitry Andric // but the argument needs to be the original pointer.
40740b57cec5SDimitry Andric if (type->isReferenceType()) {
40750b57cec5SDimitry Andric args.add(RValue::get(Builder.CreateLoad(local)), type);
40760b57cec5SDimitry Andric
40770b57cec5SDimitry Andric // In ARC, move out of consumed arguments so that the release cleanup
40780b57cec5SDimitry Andric // entered by StartFunction doesn't cause an over-release. This isn't
40790b57cec5SDimitry Andric // optimal -O0 code generation, but it should get cleaned up when
40800b57cec5SDimitry Andric // optimization is enabled. This also assumes that delegate calls are
40810b57cec5SDimitry Andric // performed exactly once for a set of arguments, but that should be safe.
40820b57cec5SDimitry Andric } else if (getLangOpts().ObjCAutoRefCount &&
40830b57cec5SDimitry Andric param->hasAttr<NSConsumedAttr>() &&
40840b57cec5SDimitry Andric type->isObjCRetainableType()) {
40850b57cec5SDimitry Andric llvm::Value *ptr = Builder.CreateLoad(local);
40860b57cec5SDimitry Andric auto null =
40870b57cec5SDimitry Andric llvm::ConstantPointerNull::get(cast<llvm::PointerType>(ptr->getType()));
40880b57cec5SDimitry Andric Builder.CreateStore(null, local);
40890b57cec5SDimitry Andric args.add(RValue::get(ptr), type);
40900b57cec5SDimitry Andric
40910b57cec5SDimitry Andric // For the most part, we just need to load the alloca, except that
40920b57cec5SDimitry Andric // aggregate r-values are actually pointers to temporaries.
40930b57cec5SDimitry Andric } else {
40940b57cec5SDimitry Andric args.add(convertTempToRValue(local, type, loc), type);
40950b57cec5SDimitry Andric }
40960b57cec5SDimitry Andric
40970b57cec5SDimitry Andric // Deactivate the cleanup for the callee-destructed param that was pushed.
4098fe6060f1SDimitry Andric if (type->isRecordType() && !CurFuncIsThunk &&
4099a7dea167SDimitry Andric type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee() &&
4100a7dea167SDimitry Andric param->needsDestruction(getContext())) {
41010b57cec5SDimitry Andric EHScopeStack::stable_iterator cleanup =
41020b57cec5SDimitry Andric CalleeDestructedParamCleanups.lookup(cast<ParmVarDecl>(param));
41030b57cec5SDimitry Andric assert(cleanup.isValid() &&
41040b57cec5SDimitry Andric "cleanup for callee-destructed param not recorded");
41050b57cec5SDimitry Andric // This unreachable is a temporary marker which will be removed later.
41060b57cec5SDimitry Andric llvm::Instruction *isActive = Builder.CreateUnreachable();
41070b57cec5SDimitry Andric args.addArgCleanupDeactivation(cleanup, isActive);
41080b57cec5SDimitry Andric }
41090b57cec5SDimitry Andric }
41100b57cec5SDimitry Andric
isProvablyNull(llvm::Value * addr)41110b57cec5SDimitry Andric static bool isProvablyNull(llvm::Value *addr) {
41120fca6ea1SDimitry Andric return llvm::isa_and_nonnull<llvm::ConstantPointerNull>(addr);
41130fca6ea1SDimitry Andric }
41140fca6ea1SDimitry Andric
isProvablyNonNull(Address Addr,CodeGenFunction & CGF)41150fca6ea1SDimitry Andric static bool isProvablyNonNull(Address Addr, CodeGenFunction &CGF) {
41160fca6ea1SDimitry Andric return llvm::isKnownNonZero(Addr.getBasePointer(), CGF.CGM.getDataLayout());
41170b57cec5SDimitry Andric }
41180b57cec5SDimitry Andric
41190b57cec5SDimitry Andric /// Emit the actual writing-back of a writeback.
emitWriteback(CodeGenFunction & CGF,const CallArgList::Writeback & writeback)41200b57cec5SDimitry Andric static void emitWriteback(CodeGenFunction &CGF,
41210b57cec5SDimitry Andric const CallArgList::Writeback &writeback) {
41220b57cec5SDimitry Andric const LValue &srcLV = writeback.Source;
41230fca6ea1SDimitry Andric Address srcAddr = srcLV.getAddress();
41240fca6ea1SDimitry Andric assert(!isProvablyNull(srcAddr.getBasePointer()) &&
41250b57cec5SDimitry Andric "shouldn't have writeback for provably null argument");
41260b57cec5SDimitry Andric
41270b57cec5SDimitry Andric llvm::BasicBlock *contBB = nullptr;
41280b57cec5SDimitry Andric
41290b57cec5SDimitry Andric // If the argument wasn't provably non-null, we need to null check
41300b57cec5SDimitry Andric // before doing the store.
41310fca6ea1SDimitry Andric bool provablyNonNull = isProvablyNonNull(srcAddr, CGF);
41320fca6ea1SDimitry Andric
41330b57cec5SDimitry Andric if (!provablyNonNull) {
41340b57cec5SDimitry Andric llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback");
41350b57cec5SDimitry Andric contBB = CGF.createBasicBlock("icr.done");
41360b57cec5SDimitry Andric
41370fca6ea1SDimitry Andric llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull");
41380b57cec5SDimitry Andric CGF.Builder.CreateCondBr(isNull, contBB, writebackBB);
41390b57cec5SDimitry Andric CGF.EmitBlock(writebackBB);
41400b57cec5SDimitry Andric }
41410b57cec5SDimitry Andric
41420b57cec5SDimitry Andric // Load the value to writeback.
41430b57cec5SDimitry Andric llvm::Value *value = CGF.Builder.CreateLoad(writeback.Temporary);
41440b57cec5SDimitry Andric
41450b57cec5SDimitry Andric // Cast it back, in case we're writing an id to a Foo* or something.
41460b57cec5SDimitry Andric value = CGF.Builder.CreateBitCast(value, srcAddr.getElementType(),
41470b57cec5SDimitry Andric "icr.writeback-cast");
41480b57cec5SDimitry Andric
41490b57cec5SDimitry Andric // Perform the writeback.
41500b57cec5SDimitry Andric
41510b57cec5SDimitry Andric // If we have a "to use" value, it's something we need to emit a use
41520b57cec5SDimitry Andric // of. This has to be carefully threaded in: if it's done after the
41530b57cec5SDimitry Andric // release it's potentially undefined behavior (and the optimizer
41540b57cec5SDimitry Andric // will ignore it), and if it happens before the retain then the
41550b57cec5SDimitry Andric // optimizer could move the release there.
41560b57cec5SDimitry Andric if (writeback.ToUse) {
41570b57cec5SDimitry Andric assert(srcLV.getObjCLifetime() == Qualifiers::OCL_Strong);
41580b57cec5SDimitry Andric
41590b57cec5SDimitry Andric // Retain the new value. No need to block-copy here: the block's
41600b57cec5SDimitry Andric // being passed up the stack.
41610b57cec5SDimitry Andric value = CGF.EmitARCRetainNonBlock(value);
41620b57cec5SDimitry Andric
41630b57cec5SDimitry Andric // Emit the intrinsic use here.
41640b57cec5SDimitry Andric CGF.EmitARCIntrinsicUse(writeback.ToUse);
41650b57cec5SDimitry Andric
41660b57cec5SDimitry Andric // Load the old value (primitively).
41670b57cec5SDimitry Andric llvm::Value *oldValue = CGF.EmitLoadOfScalar(srcLV, SourceLocation());
41680b57cec5SDimitry Andric
41690b57cec5SDimitry Andric // Put the new value in place (primitively).
41700b57cec5SDimitry Andric CGF.EmitStoreOfScalar(value, srcLV, /*init*/ false);
41710b57cec5SDimitry Andric
41720b57cec5SDimitry Andric // Release the old value.
41730b57cec5SDimitry Andric CGF.EmitARCRelease(oldValue, srcLV.isARCPreciseLifetime());
41740b57cec5SDimitry Andric
41750b57cec5SDimitry Andric // Otherwise, we can just do a normal lvalue store.
41760b57cec5SDimitry Andric } else {
41770b57cec5SDimitry Andric CGF.EmitStoreThroughLValue(RValue::get(value), srcLV);
41780b57cec5SDimitry Andric }
41790b57cec5SDimitry Andric
41800b57cec5SDimitry Andric // Jump to the continuation block.
41810b57cec5SDimitry Andric if (!provablyNonNull)
41820b57cec5SDimitry Andric CGF.EmitBlock(contBB);
41830b57cec5SDimitry Andric }
41840b57cec5SDimitry Andric
emitWritebacks(CodeGenFunction & CGF,const CallArgList & args)41850b57cec5SDimitry Andric static void emitWritebacks(CodeGenFunction &CGF,
41860b57cec5SDimitry Andric const CallArgList &args) {
41870b57cec5SDimitry Andric for (const auto &I : args.writebacks())
41880b57cec5SDimitry Andric emitWriteback(CGF, I);
41890b57cec5SDimitry Andric }
41900b57cec5SDimitry Andric
deactivateArgCleanupsBeforeCall(CodeGenFunction & CGF,const CallArgList & CallArgs)41910b57cec5SDimitry Andric static void deactivateArgCleanupsBeforeCall(CodeGenFunction &CGF,
41920b57cec5SDimitry Andric const CallArgList &CallArgs) {
41930b57cec5SDimitry Andric ArrayRef<CallArgList::CallArgCleanup> Cleanups =
41940b57cec5SDimitry Andric CallArgs.getCleanupsToDeactivate();
41950b57cec5SDimitry Andric // Iterate in reverse to increase the likelihood of popping the cleanup.
41960b57cec5SDimitry Andric for (const auto &I : llvm::reverse(Cleanups)) {
41970b57cec5SDimitry Andric CGF.DeactivateCleanupBlock(I.Cleanup, I.IsActiveIP);
41980b57cec5SDimitry Andric I.IsActiveIP->eraseFromParent();
41990b57cec5SDimitry Andric }
42000b57cec5SDimitry Andric }
42010b57cec5SDimitry Andric
maybeGetUnaryAddrOfOperand(const Expr * E)42020b57cec5SDimitry Andric static const Expr *maybeGetUnaryAddrOfOperand(const Expr *E) {
42030b57cec5SDimitry Andric if (const UnaryOperator *uop = dyn_cast<UnaryOperator>(E->IgnoreParens()))
42040b57cec5SDimitry Andric if (uop->getOpcode() == UO_AddrOf)
42050b57cec5SDimitry Andric return uop->getSubExpr();
42060b57cec5SDimitry Andric return nullptr;
42070b57cec5SDimitry Andric }
42080b57cec5SDimitry Andric
42090b57cec5SDimitry Andric /// Emit an argument that's being passed call-by-writeback. That is,
42100b57cec5SDimitry Andric /// we are passing the address of an __autoreleased temporary; it
42110b57cec5SDimitry Andric /// might be copy-initialized with the current value of the given
42120b57cec5SDimitry Andric /// address, but it will definitely be copied out of after the call.
emitWritebackArg(CodeGenFunction & CGF,CallArgList & args,const ObjCIndirectCopyRestoreExpr * CRE)42130b57cec5SDimitry Andric static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args,
42140b57cec5SDimitry Andric const ObjCIndirectCopyRestoreExpr *CRE) {
42150b57cec5SDimitry Andric LValue srcLV;
42160b57cec5SDimitry Andric
42170b57cec5SDimitry Andric // Make an optimistic effort to emit the address as an l-value.
42180b57cec5SDimitry Andric // This can fail if the argument expression is more complicated.
42190b57cec5SDimitry Andric if (const Expr *lvExpr = maybeGetUnaryAddrOfOperand(CRE->getSubExpr())) {
42200b57cec5SDimitry Andric srcLV = CGF.EmitLValue(lvExpr);
42210b57cec5SDimitry Andric
42220b57cec5SDimitry Andric // Otherwise, just emit it as a scalar.
42230b57cec5SDimitry Andric } else {
42240b57cec5SDimitry Andric Address srcAddr = CGF.EmitPointerWithAlignment(CRE->getSubExpr());
42250b57cec5SDimitry Andric
42260b57cec5SDimitry Andric QualType srcAddrType =
42270b57cec5SDimitry Andric CRE->getSubExpr()->getType()->castAs<PointerType>()->getPointeeType();
42280b57cec5SDimitry Andric srcLV = CGF.MakeAddrLValue(srcAddr, srcAddrType);
42290b57cec5SDimitry Andric }
42300fca6ea1SDimitry Andric Address srcAddr = srcLV.getAddress();
42310b57cec5SDimitry Andric
42320b57cec5SDimitry Andric // The dest and src types don't necessarily match in LLVM terms
42330b57cec5SDimitry Andric // because of the crazy ObjC compatibility rules.
42340b57cec5SDimitry Andric
42350b57cec5SDimitry Andric llvm::PointerType *destType =
42360b57cec5SDimitry Andric cast<llvm::PointerType>(CGF.ConvertType(CRE->getType()));
423781ad6265SDimitry Andric llvm::Type *destElemType =
423881ad6265SDimitry Andric CGF.ConvertTypeForMem(CRE->getType()->getPointeeType());
42390b57cec5SDimitry Andric
42400b57cec5SDimitry Andric // If the address is a constant null, just pass the appropriate null.
42410fca6ea1SDimitry Andric if (isProvablyNull(srcAddr.getBasePointer())) {
42420b57cec5SDimitry Andric args.add(RValue::get(llvm::ConstantPointerNull::get(destType)),
42430b57cec5SDimitry Andric CRE->getType());
42440b57cec5SDimitry Andric return;
42450b57cec5SDimitry Andric }
42460b57cec5SDimitry Andric
42470b57cec5SDimitry Andric // Create the temporary.
424881ad6265SDimitry Andric Address temp =
424981ad6265SDimitry Andric CGF.CreateTempAlloca(destElemType, CGF.getPointerAlign(), "icr.temp");
42500b57cec5SDimitry Andric // Loading an l-value can introduce a cleanup if the l-value is __weak,
42510b57cec5SDimitry Andric // and that cleanup will be conditional if we can't prove that the l-value
42520b57cec5SDimitry Andric // isn't null, so we need to register a dominating point so that the cleanups
42530b57cec5SDimitry Andric // system will make valid IR.
42540b57cec5SDimitry Andric CodeGenFunction::ConditionalEvaluation condEval(CGF);
42550b57cec5SDimitry Andric
42560b57cec5SDimitry Andric // Zero-initialize it if we're not doing a copy-initialization.
42570b57cec5SDimitry Andric bool shouldCopy = CRE->shouldCopy();
42580b57cec5SDimitry Andric if (!shouldCopy) {
425981ad6265SDimitry Andric llvm::Value *null =
426081ad6265SDimitry Andric llvm::ConstantPointerNull::get(cast<llvm::PointerType>(destElemType));
42610b57cec5SDimitry Andric CGF.Builder.CreateStore(null, temp);
42620b57cec5SDimitry Andric }
42630b57cec5SDimitry Andric
42640b57cec5SDimitry Andric llvm::BasicBlock *contBB = nullptr;
42650b57cec5SDimitry Andric llvm::BasicBlock *originBB = nullptr;
42660b57cec5SDimitry Andric
42670b57cec5SDimitry Andric // If the address is *not* known to be non-null, we need to switch.
42680b57cec5SDimitry Andric llvm::Value *finalArgument;
42690b57cec5SDimitry Andric
42700fca6ea1SDimitry Andric bool provablyNonNull = isProvablyNonNull(srcAddr, CGF);
42710b57cec5SDimitry Andric
42720fca6ea1SDimitry Andric if (provablyNonNull) {
42730fca6ea1SDimitry Andric finalArgument = temp.emitRawPointer(CGF);
42740fca6ea1SDimitry Andric } else {
42750fca6ea1SDimitry Andric llvm::Value *isNull = CGF.Builder.CreateIsNull(srcAddr, "icr.isnull");
42760fca6ea1SDimitry Andric
42770fca6ea1SDimitry Andric finalArgument = CGF.Builder.CreateSelect(
42780fca6ea1SDimitry Andric isNull, llvm::ConstantPointerNull::get(destType),
42790fca6ea1SDimitry Andric temp.emitRawPointer(CGF), "icr.argument");
42800b57cec5SDimitry Andric
42810b57cec5SDimitry Andric // If we need to copy, then the load has to be conditional, which
42820b57cec5SDimitry Andric // means we need control flow.
42830b57cec5SDimitry Andric if (shouldCopy) {
42840b57cec5SDimitry Andric originBB = CGF.Builder.GetInsertBlock();
42850b57cec5SDimitry Andric contBB = CGF.createBasicBlock("icr.cont");
42860b57cec5SDimitry Andric llvm::BasicBlock *copyBB = CGF.createBasicBlock("icr.copy");
42870b57cec5SDimitry Andric CGF.Builder.CreateCondBr(isNull, contBB, copyBB);
42880b57cec5SDimitry Andric CGF.EmitBlock(copyBB);
42890b57cec5SDimitry Andric condEval.begin(CGF);
42900b57cec5SDimitry Andric }
42910b57cec5SDimitry Andric }
42920b57cec5SDimitry Andric
42930b57cec5SDimitry Andric llvm::Value *valueToUse = nullptr;
42940b57cec5SDimitry Andric
42950b57cec5SDimitry Andric // Perform a copy if necessary.
42960b57cec5SDimitry Andric if (shouldCopy) {
42970b57cec5SDimitry Andric RValue srcRV = CGF.EmitLoadOfLValue(srcLV, SourceLocation());
42980b57cec5SDimitry Andric assert(srcRV.isScalar());
42990b57cec5SDimitry Andric
43000b57cec5SDimitry Andric llvm::Value *src = srcRV.getScalarVal();
430181ad6265SDimitry Andric src = CGF.Builder.CreateBitCast(src, destElemType, "icr.cast");
43020b57cec5SDimitry Andric
43030b57cec5SDimitry Andric // Use an ordinary store, not a store-to-lvalue.
43040b57cec5SDimitry Andric CGF.Builder.CreateStore(src, temp);
43050b57cec5SDimitry Andric
43060b57cec5SDimitry Andric // If optimization is enabled, and the value was held in a
43070b57cec5SDimitry Andric // __strong variable, we need to tell the optimizer that this
43080b57cec5SDimitry Andric // value has to stay alive until we're doing the store back.
43090b57cec5SDimitry Andric // This is because the temporary is effectively unretained,
43100b57cec5SDimitry Andric // and so otherwise we can violate the high-level semantics.
43110b57cec5SDimitry Andric if (CGF.CGM.getCodeGenOpts().OptimizationLevel != 0 &&
43120b57cec5SDimitry Andric srcLV.getObjCLifetime() == Qualifiers::OCL_Strong) {
43130b57cec5SDimitry Andric valueToUse = src;
43140b57cec5SDimitry Andric }
43150b57cec5SDimitry Andric }
43160b57cec5SDimitry Andric
43170b57cec5SDimitry Andric // Finish the control flow if we needed it.
43180b57cec5SDimitry Andric if (shouldCopy && !provablyNonNull) {
43190b57cec5SDimitry Andric llvm::BasicBlock *copyBB = CGF.Builder.GetInsertBlock();
43200b57cec5SDimitry Andric CGF.EmitBlock(contBB);
43210b57cec5SDimitry Andric
43220b57cec5SDimitry Andric // Make a phi for the value to intrinsically use.
43230b57cec5SDimitry Andric if (valueToUse) {
43240b57cec5SDimitry Andric llvm::PHINode *phiToUse = CGF.Builder.CreatePHI(valueToUse->getType(), 2,
43250b57cec5SDimitry Andric "icr.to-use");
43260b57cec5SDimitry Andric phiToUse->addIncoming(valueToUse, copyBB);
43270b57cec5SDimitry Andric phiToUse->addIncoming(llvm::UndefValue::get(valueToUse->getType()),
43280b57cec5SDimitry Andric originBB);
43290b57cec5SDimitry Andric valueToUse = phiToUse;
43300b57cec5SDimitry Andric }
43310b57cec5SDimitry Andric
43320b57cec5SDimitry Andric condEval.end(CGF);
43330b57cec5SDimitry Andric }
43340b57cec5SDimitry Andric
43350b57cec5SDimitry Andric args.addWriteback(srcLV, temp, valueToUse);
43360b57cec5SDimitry Andric args.add(RValue::get(finalArgument), CRE->getType());
43370b57cec5SDimitry Andric }
43380b57cec5SDimitry Andric
allocateArgumentMemory(CodeGenFunction & CGF)43390b57cec5SDimitry Andric void CallArgList::allocateArgumentMemory(CodeGenFunction &CGF) {
43400b57cec5SDimitry Andric assert(!StackBase);
43410b57cec5SDimitry Andric
43420b57cec5SDimitry Andric // Save the stack.
43435f757f3fSDimitry Andric StackBase = CGF.Builder.CreateStackSave("inalloca.save");
43440b57cec5SDimitry Andric }
43450b57cec5SDimitry Andric
freeArgumentMemory(CodeGenFunction & CGF) const43460b57cec5SDimitry Andric void CallArgList::freeArgumentMemory(CodeGenFunction &CGF) const {
43470b57cec5SDimitry Andric if (StackBase) {
43480b57cec5SDimitry Andric // Restore the stack after the call.
43495f757f3fSDimitry Andric CGF.Builder.CreateStackRestore(StackBase);
43500b57cec5SDimitry Andric }
43510b57cec5SDimitry Andric }
43520b57cec5SDimitry Andric
EmitNonNullArgCheck(RValue RV,QualType ArgType,SourceLocation ArgLoc,AbstractCallee AC,unsigned ParmNum)43530b57cec5SDimitry Andric void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
43540b57cec5SDimitry Andric SourceLocation ArgLoc,
43550b57cec5SDimitry Andric AbstractCallee AC,
43560b57cec5SDimitry Andric unsigned ParmNum) {
43570b57cec5SDimitry Andric if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
43580b57cec5SDimitry Andric SanOpts.has(SanitizerKind::NullabilityArg)))
43590b57cec5SDimitry Andric return;
43600b57cec5SDimitry Andric
43610b57cec5SDimitry Andric // The param decl may be missing in a variadic function.
43620b57cec5SDimitry Andric auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) : nullptr;
43630b57cec5SDimitry Andric unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
43640b57cec5SDimitry Andric
43650b57cec5SDimitry Andric // Prefer the nonnull attribute if it's present.
43660b57cec5SDimitry Andric const NonNullAttr *NNAttr = nullptr;
43670b57cec5SDimitry Andric if (SanOpts.has(SanitizerKind::NonnullAttribute))
43680b57cec5SDimitry Andric NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo);
43690b57cec5SDimitry Andric
43700b57cec5SDimitry Andric bool CanCheckNullability = false;
43710fca6ea1SDimitry Andric if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD &&
43720fca6ea1SDimitry Andric !PVD->getType()->isRecordType()) {
4373bdd1243dSDimitry Andric auto Nullability = PVD->getType()->getNullability();
43740b57cec5SDimitry Andric CanCheckNullability = Nullability &&
43750b57cec5SDimitry Andric *Nullability == NullabilityKind::NonNull &&
43760b57cec5SDimitry Andric PVD->getTypeSourceInfo();
43770b57cec5SDimitry Andric }
43780b57cec5SDimitry Andric
43790b57cec5SDimitry Andric if (!NNAttr && !CanCheckNullability)
43800b57cec5SDimitry Andric return;
43810b57cec5SDimitry Andric
43820b57cec5SDimitry Andric SourceLocation AttrLoc;
43830b57cec5SDimitry Andric SanitizerMask CheckKind;
43840b57cec5SDimitry Andric SanitizerHandler Handler;
43850b57cec5SDimitry Andric if (NNAttr) {
43860b57cec5SDimitry Andric AttrLoc = NNAttr->getLocation();
43870b57cec5SDimitry Andric CheckKind = SanitizerKind::NonnullAttribute;
43880b57cec5SDimitry Andric Handler = SanitizerHandler::NonnullArg;
43890b57cec5SDimitry Andric } else {
43900b57cec5SDimitry Andric AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
43910b57cec5SDimitry Andric CheckKind = SanitizerKind::NullabilityArg;
43920b57cec5SDimitry Andric Handler = SanitizerHandler::NullabilityArg;
43930b57cec5SDimitry Andric }
43940b57cec5SDimitry Andric
43950b57cec5SDimitry Andric SanitizerScope SanScope(this);
4396e8d8bef9SDimitry Andric llvm::Value *Cond = EmitNonNullRValueCheck(RV, ArgType);
43970b57cec5SDimitry Andric llvm::Constant *StaticData[] = {
43980b57cec5SDimitry Andric EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc),
43990b57cec5SDimitry Andric llvm::ConstantInt::get(Int32Ty, ArgNo + 1),
44000b57cec5SDimitry Andric };
4401bdd1243dSDimitry Andric EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, std::nullopt);
44020b57cec5SDimitry Andric }
44030b57cec5SDimitry Andric
EmitNonNullArgCheck(Address Addr,QualType ArgType,SourceLocation ArgLoc,AbstractCallee AC,unsigned ParmNum)44040fca6ea1SDimitry Andric void CodeGenFunction::EmitNonNullArgCheck(Address Addr, QualType ArgType,
44050fca6ea1SDimitry Andric SourceLocation ArgLoc,
44060fca6ea1SDimitry Andric AbstractCallee AC, unsigned ParmNum) {
44070fca6ea1SDimitry Andric if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
44080fca6ea1SDimitry Andric SanOpts.has(SanitizerKind::NullabilityArg)))
44090fca6ea1SDimitry Andric return;
44100fca6ea1SDimitry Andric
44110fca6ea1SDimitry Andric EmitNonNullArgCheck(RValue::get(Addr, *this), ArgType, ArgLoc, AC, ParmNum);
44120fca6ea1SDimitry Andric }
44130fca6ea1SDimitry Andric
4414e8d8bef9SDimitry Andric // Check if the call is going to use the inalloca convention. This needs to
4415e8d8bef9SDimitry Andric // agree with CGFunctionInfo::usesInAlloca. The CGFunctionInfo is arranged
4416e8d8bef9SDimitry Andric // later, so we can't check it directly.
hasInAllocaArgs(CodeGenModule & CGM,CallingConv ExplicitCC,ArrayRef<QualType> ArgTypes)4417e8d8bef9SDimitry Andric static bool hasInAllocaArgs(CodeGenModule &CGM, CallingConv ExplicitCC,
4418e8d8bef9SDimitry Andric ArrayRef<QualType> ArgTypes) {
4419fe6060f1SDimitry Andric // The Swift calling conventions don't go through the target-specific
4420fe6060f1SDimitry Andric // argument classification, they never use inalloca.
4421e8d8bef9SDimitry Andric // TODO: Consider limiting inalloca use to only calling conventions supported
4422e8d8bef9SDimitry Andric // by MSVC.
4423fe6060f1SDimitry Andric if (ExplicitCC == CC_Swift || ExplicitCC == CC_SwiftAsync)
4424e8d8bef9SDimitry Andric return false;
4425e8d8bef9SDimitry Andric if (!CGM.getTarget().getCXXABI().isMicrosoft())
4426e8d8bef9SDimitry Andric return false;
4427e8d8bef9SDimitry Andric return llvm::any_of(ArgTypes, [&](QualType Ty) {
4428e8d8bef9SDimitry Andric return isInAllocaArgument(CGM.getCXXABI(), Ty);
4429e8d8bef9SDimitry Andric });
4430e8d8bef9SDimitry Andric }
4431e8d8bef9SDimitry Andric
4432e8d8bef9SDimitry Andric #ifndef NDEBUG
4433e8d8bef9SDimitry Andric // Determine whether the given argument is an Objective-C method
4434e8d8bef9SDimitry Andric // that may have type parameters in its signature.
isObjCMethodWithTypeParams(const ObjCMethodDecl * method)4435e8d8bef9SDimitry Andric static bool isObjCMethodWithTypeParams(const ObjCMethodDecl *method) {
4436e8d8bef9SDimitry Andric const DeclContext *dc = method->getDeclContext();
4437e8d8bef9SDimitry Andric if (const ObjCInterfaceDecl *classDecl = dyn_cast<ObjCInterfaceDecl>(dc)) {
4438e8d8bef9SDimitry Andric return classDecl->getTypeParamListAsWritten();
4439e8d8bef9SDimitry Andric }
4440e8d8bef9SDimitry Andric
4441e8d8bef9SDimitry Andric if (const ObjCCategoryDecl *catDecl = dyn_cast<ObjCCategoryDecl>(dc)) {
4442e8d8bef9SDimitry Andric return catDecl->getTypeParamList();
4443e8d8bef9SDimitry Andric }
4444e8d8bef9SDimitry Andric
4445e8d8bef9SDimitry Andric return false;
4446e8d8bef9SDimitry Andric }
4447e8d8bef9SDimitry Andric #endif
4448e8d8bef9SDimitry Andric
4449e8d8bef9SDimitry 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)44500b57cec5SDimitry Andric void CodeGenFunction::EmitCallArgs(
4451e8d8bef9SDimitry Andric CallArgList &Args, PrototypeWrapper Prototype,
44520b57cec5SDimitry Andric llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
44530b57cec5SDimitry Andric AbstractCallee AC, unsigned ParamsToSkip, EvaluationOrder Order) {
4454e8d8bef9SDimitry Andric SmallVector<QualType, 16> ArgTypes;
4455e8d8bef9SDimitry Andric
4456e8d8bef9SDimitry Andric assert((ParamsToSkip == 0 || Prototype.P) &&
4457e8d8bef9SDimitry Andric "Can't skip parameters if type info is not provided");
4458e8d8bef9SDimitry Andric
4459e8d8bef9SDimitry Andric // This variable only captures *explicitly* written conventions, not those
4460e8d8bef9SDimitry Andric // applied by default via command line flags or target defaults, such as
4461e8d8bef9SDimitry Andric // thiscall, aapcs, stdcall via -mrtd, etc. Computing that correctly would
4462e8d8bef9SDimitry Andric // require knowing if this is a C++ instance method or being able to see
4463e8d8bef9SDimitry Andric // unprototyped FunctionTypes.
4464e8d8bef9SDimitry Andric CallingConv ExplicitCC = CC_C;
4465e8d8bef9SDimitry Andric
4466e8d8bef9SDimitry Andric // First, if a prototype was provided, use those argument types.
4467e8d8bef9SDimitry Andric bool IsVariadic = false;
4468e8d8bef9SDimitry Andric if (Prototype.P) {
4469e8d8bef9SDimitry Andric const auto *MD = Prototype.P.dyn_cast<const ObjCMethodDecl *>();
4470e8d8bef9SDimitry Andric if (MD) {
4471e8d8bef9SDimitry Andric IsVariadic = MD->isVariadic();
4472e8d8bef9SDimitry Andric ExplicitCC = getCallingConventionForDecl(
4473e8d8bef9SDimitry Andric MD, CGM.getTarget().getTriple().isOSWindows());
4474e8d8bef9SDimitry Andric ArgTypes.assign(MD->param_type_begin() + ParamsToSkip,
4475e8d8bef9SDimitry Andric MD->param_type_end());
4476e8d8bef9SDimitry Andric } else {
4477e8d8bef9SDimitry Andric const auto *FPT = Prototype.P.get<const FunctionProtoType *>();
4478e8d8bef9SDimitry Andric IsVariadic = FPT->isVariadic();
4479e8d8bef9SDimitry Andric ExplicitCC = FPT->getExtInfo().getCC();
4480e8d8bef9SDimitry Andric ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip,
4481e8d8bef9SDimitry Andric FPT->param_type_end());
4482e8d8bef9SDimitry Andric }
4483e8d8bef9SDimitry Andric
4484e8d8bef9SDimitry Andric #ifndef NDEBUG
4485e8d8bef9SDimitry Andric // Check that the prototyped types match the argument expression types.
4486e8d8bef9SDimitry Andric bool isGenericMethod = MD && isObjCMethodWithTypeParams(MD);
4487e8d8bef9SDimitry Andric CallExpr::const_arg_iterator Arg = ArgRange.begin();
4488e8d8bef9SDimitry Andric for (QualType Ty : ArgTypes) {
4489e8d8bef9SDimitry Andric assert(Arg != ArgRange.end() && "Running over edge of argument list!");
4490e8d8bef9SDimitry Andric assert(
4491e8d8bef9SDimitry Andric (isGenericMethod || Ty->isVariablyModifiedType() ||
4492e8d8bef9SDimitry Andric Ty.getNonReferenceType()->isObjCRetainableType() ||
4493e8d8bef9SDimitry Andric getContext()
4494e8d8bef9SDimitry Andric .getCanonicalType(Ty.getNonReferenceType())
4495e8d8bef9SDimitry Andric .getTypePtr() ==
4496e8d8bef9SDimitry Andric getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) &&
4497e8d8bef9SDimitry Andric "type mismatch in call argument!");
4498e8d8bef9SDimitry Andric ++Arg;
4499e8d8bef9SDimitry Andric }
4500e8d8bef9SDimitry Andric
4501e8d8bef9SDimitry Andric // Either we've emitted all the call args, or we have a call to variadic
4502e8d8bef9SDimitry Andric // function.
4503e8d8bef9SDimitry Andric assert((Arg == ArgRange.end() || IsVariadic) &&
4504e8d8bef9SDimitry Andric "Extra arguments in non-variadic function!");
4505e8d8bef9SDimitry Andric #endif
4506e8d8bef9SDimitry Andric }
4507e8d8bef9SDimitry Andric
4508e8d8bef9SDimitry Andric // If we still have any arguments, emit them using the type of the argument.
45090eae32dcSDimitry Andric for (auto *A : llvm::drop_begin(ArgRange, ArgTypes.size()))
4510e8d8bef9SDimitry Andric ArgTypes.push_back(IsVariadic ? getVarArgType(A) : A->getType());
45110b57cec5SDimitry Andric assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
45120b57cec5SDimitry Andric
4513e8d8bef9SDimitry Andric // We must evaluate arguments from right to left in the MS C++ ABI,
45140b57cec5SDimitry Andric // because arguments are destroyed left to right in the callee. As a special
45150b57cec5SDimitry Andric // case, there are certain language constructs that require left-to-right
45160b57cec5SDimitry Andric // evaluation, and in those cases we consider the evaluation order requirement
45170b57cec5SDimitry Andric // to trump the "destruction order is reverse construction order" guarantee.
45180b57cec5SDimitry Andric bool LeftToRight =
45190b57cec5SDimitry Andric CGM.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()
45200b57cec5SDimitry Andric ? Order == EvaluationOrder::ForceLeftToRight
45210b57cec5SDimitry Andric : Order != EvaluationOrder::ForceRightToLeft;
45220b57cec5SDimitry Andric
45230b57cec5SDimitry Andric auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg,
45240b57cec5SDimitry Andric RValue EmittedArg) {
45250b57cec5SDimitry Andric if (!AC.hasFunctionDecl() || I >= AC.getNumParams())
45260b57cec5SDimitry Andric return;
45270b57cec5SDimitry Andric auto *PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>();
45280b57cec5SDimitry Andric if (PS == nullptr)
45290b57cec5SDimitry Andric return;
45300b57cec5SDimitry Andric
45310b57cec5SDimitry Andric const auto &Context = getContext();
45320b57cec5SDimitry Andric auto SizeTy = Context.getSizeType();
45330b57cec5SDimitry Andric auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
45340b57cec5SDimitry Andric assert(EmittedArg.getScalarVal() && "We emitted nothing for the arg?");
45350b57cec5SDimitry Andric llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T,
45360b57cec5SDimitry Andric EmittedArg.getScalarVal(),
45370b57cec5SDimitry Andric PS->isDynamic());
45380b57cec5SDimitry Andric Args.add(RValue::get(V), SizeTy);
45390b57cec5SDimitry Andric // If we're emitting args in reverse, be sure to do so with
45400b57cec5SDimitry Andric // pass_object_size, as well.
45410b57cec5SDimitry Andric if (!LeftToRight)
45420b57cec5SDimitry Andric std::swap(Args.back(), *(&Args.back() - 1));
45430b57cec5SDimitry Andric };
45440b57cec5SDimitry Andric
45450b57cec5SDimitry Andric // Insert a stack save if we're going to need any inalloca args.
4546e8d8bef9SDimitry Andric if (hasInAllocaArgs(CGM, ExplicitCC, ArgTypes)) {
4547e8d8bef9SDimitry Andric assert(getTarget().getTriple().getArch() == llvm::Triple::x86 &&
4548e8d8bef9SDimitry Andric "inalloca only supported on x86");
45490b57cec5SDimitry Andric Args.allocateArgumentMemory(*this);
45500b57cec5SDimitry Andric }
45510b57cec5SDimitry Andric
45520b57cec5SDimitry Andric // Evaluate each argument in the appropriate order.
45530b57cec5SDimitry Andric size_t CallArgsStart = Args.size();
45540b57cec5SDimitry Andric for (unsigned I = 0, E = ArgTypes.size(); I != E; ++I) {
45550b57cec5SDimitry Andric unsigned Idx = LeftToRight ? I : E - I - 1;
45560b57cec5SDimitry Andric CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
45570b57cec5SDimitry Andric unsigned InitialArgSize = Args.size();
45580b57cec5SDimitry Andric // If *Arg is an ObjCIndirectCopyRestoreExpr, check that either the types of
45590b57cec5SDimitry Andric // the argument and parameter match or the objc method is parameterized.
45600b57cec5SDimitry Andric assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
45610b57cec5SDimitry Andric getContext().hasSameUnqualifiedType((*Arg)->getType(),
45620b57cec5SDimitry Andric ArgTypes[Idx]) ||
45630b57cec5SDimitry Andric (isa<ObjCMethodDecl>(AC.getDecl()) &&
45640b57cec5SDimitry Andric isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(AC.getDecl())))) &&
45650b57cec5SDimitry Andric "Argument and parameter types don't match");
45660b57cec5SDimitry Andric EmitCallArg(Args, *Arg, ArgTypes[Idx]);
45670b57cec5SDimitry Andric // In particular, we depend on it being the last arg in Args, and the
45680b57cec5SDimitry Andric // objectsize bits depend on there only being one arg if !LeftToRight.
45690b57cec5SDimitry Andric assert(InitialArgSize + 1 == Args.size() &&
45700b57cec5SDimitry Andric "The code below depends on only adding one arg per EmitCallArg");
45710b57cec5SDimitry Andric (void)InitialArgSize;
45720b57cec5SDimitry Andric // Since pointer argument are never emitted as LValue, it is safe to emit
45730b57cec5SDimitry Andric // non-null argument check for r-value only.
45740b57cec5SDimitry Andric if (!Args.back().hasLValue()) {
45750b57cec5SDimitry Andric RValue RVArg = Args.back().getKnownRValue();
45760b57cec5SDimitry Andric EmitNonNullArgCheck(RVArg, ArgTypes[Idx], (*Arg)->getExprLoc(), AC,
45770b57cec5SDimitry Andric ParamsToSkip + Idx);
45780b57cec5SDimitry Andric // @llvm.objectsize should never have side-effects and shouldn't need
45790b57cec5SDimitry Andric // destruction/cleanups, so we can safely "emit" it after its arg,
45800b57cec5SDimitry Andric // regardless of right-to-leftness
45810b57cec5SDimitry Andric MaybeEmitImplicitObjectSize(Idx, *Arg, RVArg);
45820b57cec5SDimitry Andric }
45830b57cec5SDimitry Andric }
45840b57cec5SDimitry Andric
45850b57cec5SDimitry Andric if (!LeftToRight) {
45860b57cec5SDimitry Andric // Un-reverse the arguments we just evaluated so they match up with the LLVM
45870b57cec5SDimitry Andric // IR function.
45880b57cec5SDimitry Andric std::reverse(Args.begin() + CallArgsStart, Args.end());
45890b57cec5SDimitry Andric }
45900b57cec5SDimitry Andric }
45910b57cec5SDimitry Andric
45920b57cec5SDimitry Andric namespace {
45930b57cec5SDimitry Andric
45940b57cec5SDimitry Andric struct DestroyUnpassedArg final : EHScopeStack::Cleanup {
DestroyUnpassedArg__anonf4c048640f11::DestroyUnpassedArg45950b57cec5SDimitry Andric DestroyUnpassedArg(Address Addr, QualType Ty)
45960b57cec5SDimitry Andric : Addr(Addr), Ty(Ty) {}
45970b57cec5SDimitry Andric
45980b57cec5SDimitry Andric Address Addr;
45990b57cec5SDimitry Andric QualType Ty;
46000b57cec5SDimitry Andric
Emit__anonf4c048640f11::DestroyUnpassedArg46010b57cec5SDimitry Andric void Emit(CodeGenFunction &CGF, Flags flags) override {
46020b57cec5SDimitry Andric QualType::DestructionKind DtorKind = Ty.isDestructedType();
46030b57cec5SDimitry Andric if (DtorKind == QualType::DK_cxx_destructor) {
46040b57cec5SDimitry Andric const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor();
46050b57cec5SDimitry Andric assert(!Dtor->isTrivial());
46060b57cec5SDimitry Andric CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*for vbase*/ false,
46070b57cec5SDimitry Andric /*Delegating=*/false, Addr, Ty);
46080b57cec5SDimitry Andric } else {
46090b57cec5SDimitry Andric CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Ty));
46100b57cec5SDimitry Andric }
46110b57cec5SDimitry Andric }
46120b57cec5SDimitry Andric };
46130b57cec5SDimitry Andric
46140b57cec5SDimitry Andric struct DisableDebugLocationUpdates {
46150b57cec5SDimitry Andric CodeGenFunction &CGF;
46160b57cec5SDimitry Andric bool disabledDebugInfo;
DisableDebugLocationUpdates__anonf4c048640f11::DisableDebugLocationUpdates46170b57cec5SDimitry Andric DisableDebugLocationUpdates(CodeGenFunction &CGF, const Expr *E) : CGF(CGF) {
46180b57cec5SDimitry Andric if ((disabledDebugInfo = isa<CXXDefaultArgExpr>(E) && CGF.getDebugInfo()))
46190b57cec5SDimitry Andric CGF.disableDebugInfo();
46200b57cec5SDimitry Andric }
~DisableDebugLocationUpdates__anonf4c048640f11::DisableDebugLocationUpdates46210b57cec5SDimitry Andric ~DisableDebugLocationUpdates() {
46220b57cec5SDimitry Andric if (disabledDebugInfo)
46230b57cec5SDimitry Andric CGF.enableDebugInfo();
46240b57cec5SDimitry Andric }
46250b57cec5SDimitry Andric };
46260b57cec5SDimitry Andric
46270b57cec5SDimitry Andric } // end anonymous namespace
46280b57cec5SDimitry Andric
getRValue(CodeGenFunction & CGF) const46290b57cec5SDimitry Andric RValue CallArg::getRValue(CodeGenFunction &CGF) const {
46300b57cec5SDimitry Andric if (!HasLV)
46310b57cec5SDimitry Andric return RV;
46320b57cec5SDimitry Andric LValue Copy = CGF.MakeAddrLValue(CGF.CreateMemTemp(Ty), Ty);
46330b57cec5SDimitry Andric CGF.EmitAggregateCopy(Copy, LV, Ty, AggValueSlot::DoesNotOverlap,
46340b57cec5SDimitry Andric LV.isVolatile());
46350b57cec5SDimitry Andric IsUsed = true;
46360fca6ea1SDimitry Andric return RValue::getAggregate(Copy.getAddress());
46370b57cec5SDimitry Andric }
46380b57cec5SDimitry Andric
copyInto(CodeGenFunction & CGF,Address Addr) const46390b57cec5SDimitry Andric void CallArg::copyInto(CodeGenFunction &CGF, Address Addr) const {
46400b57cec5SDimitry Andric LValue Dst = CGF.MakeAddrLValue(Addr, Ty);
46410b57cec5SDimitry Andric if (!HasLV && RV.isScalar())
46420b57cec5SDimitry Andric CGF.EmitStoreOfScalar(RV.getScalarVal(), Dst, /*isInit=*/true);
46430b57cec5SDimitry Andric else if (!HasLV && RV.isComplex())
46440b57cec5SDimitry Andric CGF.EmitStoreOfComplex(RV.getComplexVal(), Dst, /*init=*/true);
46450b57cec5SDimitry Andric else {
46460fca6ea1SDimitry Andric auto Addr = HasLV ? LV.getAddress() : RV.getAggregateAddress();
46470b57cec5SDimitry Andric LValue SrcLV = CGF.MakeAddrLValue(Addr, Ty);
46480b57cec5SDimitry Andric // We assume that call args are never copied into subobjects.
46490b57cec5SDimitry Andric CGF.EmitAggregateCopy(Dst, SrcLV, Ty, AggValueSlot::DoesNotOverlap,
46500b57cec5SDimitry Andric HasLV ? LV.isVolatileQualified()
46510b57cec5SDimitry Andric : RV.isVolatileQualified());
46520b57cec5SDimitry Andric }
46530b57cec5SDimitry Andric IsUsed = true;
46540b57cec5SDimitry Andric }
46550b57cec5SDimitry Andric
EmitCallArg(CallArgList & args,const Expr * E,QualType type)46560b57cec5SDimitry Andric void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
46570b57cec5SDimitry Andric QualType type) {
46580b57cec5SDimitry Andric DisableDebugLocationUpdates Dis(*this, E);
46590b57cec5SDimitry Andric if (const ObjCIndirectCopyRestoreExpr *CRE
46600b57cec5SDimitry Andric = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
46610b57cec5SDimitry Andric assert(getLangOpts().ObjCAutoRefCount);
46620b57cec5SDimitry Andric return emitWritebackArg(*this, args, CRE);
46630b57cec5SDimitry Andric }
46640b57cec5SDimitry Andric
46650b57cec5SDimitry Andric assert(type->isReferenceType() == E->isGLValue() &&
46660b57cec5SDimitry Andric "reference binding to unmaterialized r-value!");
46670b57cec5SDimitry Andric
46680b57cec5SDimitry Andric if (E->isGLValue()) {
46690b57cec5SDimitry Andric assert(E->getObjectKind() == OK_Ordinary);
46700b57cec5SDimitry Andric return args.add(EmitReferenceBindingToExpr(E), type);
46710b57cec5SDimitry Andric }
46720b57cec5SDimitry Andric
46730b57cec5SDimitry Andric bool HasAggregateEvalKind = hasAggregateEvaluationKind(type);
46740b57cec5SDimitry Andric
46750b57cec5SDimitry Andric // In the Microsoft C++ ABI, aggregate arguments are destructed by the callee.
46760b57cec5SDimitry Andric // However, we still have to push an EH-only cleanup in case we unwind before
46770b57cec5SDimitry Andric // we make it to the call.
4678fe6060f1SDimitry Andric if (type->isRecordType() &&
4679a7dea167SDimitry Andric type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
46800b57cec5SDimitry Andric // If we're using inalloca, use the argument memory. Otherwise, use a
46810b57cec5SDimitry Andric // temporary.
46820eae32dcSDimitry Andric AggValueSlot Slot = args.isUsingInAlloca()
46830eae32dcSDimitry Andric ? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp");
46840b57cec5SDimitry Andric
46850fca6ea1SDimitry Andric bool DestroyedInCallee = true, NeedsCleanup = true;
46860b57cec5SDimitry Andric if (const auto *RD = type->getAsCXXRecordDecl())
46870b57cec5SDimitry Andric DestroyedInCallee = RD->hasNonTrivialDestructor();
46880b57cec5SDimitry Andric else
46890fca6ea1SDimitry Andric NeedsCleanup = type.isDestructedType();
46900b57cec5SDimitry Andric
46910b57cec5SDimitry Andric if (DestroyedInCallee)
46920b57cec5SDimitry Andric Slot.setExternallyDestructed();
46930b57cec5SDimitry Andric
46940b57cec5SDimitry Andric EmitAggExpr(E, Slot);
46950b57cec5SDimitry Andric RValue RV = Slot.asRValue();
46960b57cec5SDimitry Andric args.add(RV, type);
46970b57cec5SDimitry Andric
46980fca6ea1SDimitry Andric if (DestroyedInCallee && NeedsCleanup) {
46990b57cec5SDimitry Andric // Create a no-op GEP between the placeholder and the cleanup so we can
47000b57cec5SDimitry Andric // RAUW it successfully. It also serves as a marker of the first
47010b57cec5SDimitry Andric // instruction where the cleanup is active.
47020fca6ea1SDimitry Andric pushFullExprCleanup<DestroyUnpassedArg>(NormalAndEHCleanup,
47030fca6ea1SDimitry Andric Slot.getAddress(), type);
47040b57cec5SDimitry Andric // This unreachable is a temporary marker which will be removed later.
47050fca6ea1SDimitry Andric llvm::Instruction *IsActive =
47060fca6ea1SDimitry Andric Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy));
470781ad6265SDimitry Andric args.addArgCleanupDeactivation(EHStack.stable_begin(), IsActive);
47080b57cec5SDimitry Andric }
47090b57cec5SDimitry Andric return;
47100b57cec5SDimitry Andric }
47110b57cec5SDimitry Andric
47120b57cec5SDimitry Andric if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) &&
47130fca6ea1SDimitry Andric cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue &&
47140fca6ea1SDimitry Andric !type->isArrayParameterType()) {
47150b57cec5SDimitry Andric LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr());
47160b57cec5SDimitry Andric assert(L.isSimple());
47170b57cec5SDimitry Andric args.addUncopiedAggregate(L, type);
47180b57cec5SDimitry Andric return;
47190b57cec5SDimitry Andric }
47200b57cec5SDimitry Andric
47210b57cec5SDimitry Andric args.add(EmitAnyExprToTemp(E), type);
47220b57cec5SDimitry Andric }
47230b57cec5SDimitry Andric
getVarArgType(const Expr * Arg)47240b57cec5SDimitry Andric QualType CodeGenFunction::getVarArgType(const Expr *Arg) {
47250b57cec5SDimitry Andric // System headers on Windows define NULL to 0 instead of 0LL on Win64. MSVC
47260b57cec5SDimitry Andric // implicitly widens null pointer constants that are arguments to varargs
47270b57cec5SDimitry Andric // functions to pointer-sized ints.
47280b57cec5SDimitry Andric if (!getTarget().getTriple().isOSWindows())
47290b57cec5SDimitry Andric return Arg->getType();
47300b57cec5SDimitry Andric
47310b57cec5SDimitry Andric if (Arg->getType()->isIntegerType() &&
47320b57cec5SDimitry Andric getContext().getTypeSize(Arg->getType()) <
4733bdd1243dSDimitry Andric getContext().getTargetInfo().getPointerWidth(LangAS::Default) &&
47340b57cec5SDimitry Andric Arg->isNullPointerConstant(getContext(),
47350b57cec5SDimitry Andric Expr::NPC_ValueDependentIsNotNull)) {
47360b57cec5SDimitry Andric return getContext().getIntPtrType();
47370b57cec5SDimitry Andric }
47380b57cec5SDimitry Andric
47390b57cec5SDimitry Andric return Arg->getType();
47400b57cec5SDimitry Andric }
47410b57cec5SDimitry Andric
47420b57cec5SDimitry Andric // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
47430b57cec5SDimitry Andric // optimizer it can aggressively ignore unwind edges.
47440b57cec5SDimitry Andric void
AddObjCARCExceptionMetadata(llvm::Instruction * Inst)47450b57cec5SDimitry Andric CodeGenFunction::AddObjCARCExceptionMetadata(llvm::Instruction *Inst) {
47460b57cec5SDimitry Andric if (CGM.getCodeGenOpts().OptimizationLevel != 0 &&
47470b57cec5SDimitry Andric !CGM.getCodeGenOpts().ObjCAutoRefCountExceptions)
47480b57cec5SDimitry Andric Inst->setMetadata("clang.arc.no_objc_arc_exceptions",
47490b57cec5SDimitry Andric CGM.getNoObjCARCExceptionsMetadata());
47500b57cec5SDimitry Andric }
47510b57cec5SDimitry Andric
47520b57cec5SDimitry Andric /// Emits a call to the given no-arguments nounwind runtime function.
47530b57cec5SDimitry Andric llvm::CallInst *
EmitNounwindRuntimeCall(llvm::FunctionCallee callee,const llvm::Twine & name)47540b57cec5SDimitry Andric CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
47550b57cec5SDimitry Andric const llvm::Twine &name) {
47560fca6ea1SDimitry Andric return EmitNounwindRuntimeCall(callee, ArrayRef<llvm::Value *>(), name);
47570b57cec5SDimitry Andric }
47580b57cec5SDimitry Andric
47590b57cec5SDimitry Andric /// Emits a call to the given nounwind runtime function.
47600b57cec5SDimitry Andric llvm::CallInst *
EmitNounwindRuntimeCall(llvm::FunctionCallee callee,ArrayRef<Address> args,const llvm::Twine & name)47610b57cec5SDimitry Andric CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
47620fca6ea1SDimitry Andric ArrayRef<Address> args,
47630fca6ea1SDimitry Andric const llvm::Twine &name) {
47640fca6ea1SDimitry Andric SmallVector<llvm::Value *, 3> values;
47650fca6ea1SDimitry Andric for (auto arg : args)
47660fca6ea1SDimitry Andric values.push_back(arg.emitRawPointer(*this));
47670fca6ea1SDimitry Andric return EmitNounwindRuntimeCall(callee, values, name);
47680fca6ea1SDimitry Andric }
47690fca6ea1SDimitry Andric
47700fca6ea1SDimitry Andric llvm::CallInst *
EmitNounwindRuntimeCall(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args,const llvm::Twine & name)47710fca6ea1SDimitry Andric CodeGenFunction::EmitNounwindRuntimeCall(llvm::FunctionCallee callee,
47720b57cec5SDimitry Andric ArrayRef<llvm::Value *> args,
47730b57cec5SDimitry Andric const llvm::Twine &name) {
47740b57cec5SDimitry Andric llvm::CallInst *call = EmitRuntimeCall(callee, args, name);
47750b57cec5SDimitry Andric call->setDoesNotThrow();
47760b57cec5SDimitry Andric return call;
47770b57cec5SDimitry Andric }
47780b57cec5SDimitry Andric
47790b57cec5SDimitry Andric /// Emits a simple call (never an invoke) to the given no-arguments
47800b57cec5SDimitry Andric /// runtime function.
EmitRuntimeCall(llvm::FunctionCallee callee,const llvm::Twine & name)47810b57cec5SDimitry Andric llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
47820b57cec5SDimitry Andric const llvm::Twine &name) {
4783bdd1243dSDimitry Andric return EmitRuntimeCall(callee, std::nullopt, name);
47840b57cec5SDimitry Andric }
47850b57cec5SDimitry Andric
47860b57cec5SDimitry Andric // Calls which may throw must have operand bundles indicating which funclet
47870b57cec5SDimitry Andric // they are nested within.
47880b57cec5SDimitry Andric SmallVector<llvm::OperandBundleDef, 1>
getBundlesForFunclet(llvm::Value * Callee)47890b57cec5SDimitry Andric CodeGenFunction::getBundlesForFunclet(llvm::Value *Callee) {
47900b57cec5SDimitry Andric // There is no need for a funclet operand bundle if we aren't inside a
47910b57cec5SDimitry Andric // funclet.
47920b57cec5SDimitry Andric if (!CurrentFuncletPad)
4793972a253aSDimitry Andric return (SmallVector<llvm::OperandBundleDef, 1>());
47940b57cec5SDimitry Andric
4795972a253aSDimitry Andric // Skip intrinsics which cannot throw (as long as they don't lower into
4796972a253aSDimitry Andric // regular function calls in the course of IR transformations).
4797972a253aSDimitry Andric if (auto *CalleeFn = dyn_cast<llvm::Function>(Callee->stripPointerCasts())) {
4798972a253aSDimitry Andric if (CalleeFn->isIntrinsic() && CalleeFn->doesNotThrow()) {
4799972a253aSDimitry Andric auto IID = CalleeFn->getIntrinsicID();
4800972a253aSDimitry Andric if (!llvm::IntrinsicInst::mayLowerToFunctionCall(IID))
4801972a253aSDimitry Andric return (SmallVector<llvm::OperandBundleDef, 1>());
4802972a253aSDimitry Andric }
4803972a253aSDimitry Andric }
48040b57cec5SDimitry Andric
4805972a253aSDimitry Andric SmallVector<llvm::OperandBundleDef, 1> BundleList;
48060b57cec5SDimitry Andric BundleList.emplace_back("funclet", CurrentFuncletPad);
48070b57cec5SDimitry Andric return BundleList;
48080b57cec5SDimitry Andric }
48090b57cec5SDimitry Andric
48100b57cec5SDimitry 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)48110b57cec5SDimitry Andric llvm::CallInst *CodeGenFunction::EmitRuntimeCall(llvm::FunctionCallee callee,
48120b57cec5SDimitry Andric ArrayRef<llvm::Value *> args,
48130b57cec5SDimitry Andric const llvm::Twine &name) {
48140b57cec5SDimitry Andric llvm::CallInst *call = Builder.CreateCall(
48150b57cec5SDimitry Andric callee, args, getBundlesForFunclet(callee.getCallee()), name);
48160b57cec5SDimitry Andric call->setCallingConv(getRuntimeCC());
48170fca6ea1SDimitry Andric
48180fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens() && call->isConvergent())
48190fca6ea1SDimitry Andric return addControlledConvergenceToken(call);
48200b57cec5SDimitry Andric return call;
48210b57cec5SDimitry Andric }
48220b57cec5SDimitry Andric
48230b57cec5SDimitry Andric /// Emits a call or invoke to the given noreturn runtime function.
EmitNoreturnRuntimeCallOrInvoke(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args)48240b57cec5SDimitry Andric void CodeGenFunction::EmitNoreturnRuntimeCallOrInvoke(
48250b57cec5SDimitry Andric llvm::FunctionCallee callee, ArrayRef<llvm::Value *> args) {
48260b57cec5SDimitry Andric SmallVector<llvm::OperandBundleDef, 1> BundleList =
48270b57cec5SDimitry Andric getBundlesForFunclet(callee.getCallee());
48280b57cec5SDimitry Andric
48290b57cec5SDimitry Andric if (getInvokeDest()) {
48300b57cec5SDimitry Andric llvm::InvokeInst *invoke =
48310b57cec5SDimitry Andric Builder.CreateInvoke(callee,
48320b57cec5SDimitry Andric getUnreachableBlock(),
48330b57cec5SDimitry Andric getInvokeDest(),
48340b57cec5SDimitry Andric args,
48350b57cec5SDimitry Andric BundleList);
48360b57cec5SDimitry Andric invoke->setDoesNotReturn();
48370b57cec5SDimitry Andric invoke->setCallingConv(getRuntimeCC());
48380b57cec5SDimitry Andric } else {
48390b57cec5SDimitry Andric llvm::CallInst *call = Builder.CreateCall(callee, args, BundleList);
48400b57cec5SDimitry Andric call->setDoesNotReturn();
48410b57cec5SDimitry Andric call->setCallingConv(getRuntimeCC());
48420b57cec5SDimitry Andric Builder.CreateUnreachable();
48430b57cec5SDimitry Andric }
48440b57cec5SDimitry Andric }
48450b57cec5SDimitry Andric
48460b57cec5SDimitry Andric /// Emits a call or invoke instruction to the given nullary runtime function.
48470b57cec5SDimitry Andric llvm::CallBase *
EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,const Twine & name)48480b57cec5SDimitry Andric CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
48490b57cec5SDimitry Andric const Twine &name) {
4850bdd1243dSDimitry Andric return EmitRuntimeCallOrInvoke(callee, std::nullopt, name);
48510b57cec5SDimitry Andric }
48520b57cec5SDimitry Andric
48530b57cec5SDimitry Andric /// Emits a call or invoke instruction to the given runtime function.
48540b57cec5SDimitry Andric llvm::CallBase *
EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,ArrayRef<llvm::Value * > args,const Twine & name)48550b57cec5SDimitry Andric CodeGenFunction::EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee,
48560b57cec5SDimitry Andric ArrayRef<llvm::Value *> args,
48570b57cec5SDimitry Andric const Twine &name) {
48580b57cec5SDimitry Andric llvm::CallBase *call = EmitCallOrInvoke(callee, args, name);
48590b57cec5SDimitry Andric call->setCallingConv(getRuntimeCC());
48600b57cec5SDimitry Andric return call;
48610b57cec5SDimitry Andric }
48620b57cec5SDimitry Andric
48630b57cec5SDimitry Andric /// Emits a call or invoke instruction to the given function, depending
48640b57cec5SDimitry Andric /// on the current state of the EH stack.
EmitCallOrInvoke(llvm::FunctionCallee Callee,ArrayRef<llvm::Value * > Args,const Twine & Name)48650b57cec5SDimitry Andric llvm::CallBase *CodeGenFunction::EmitCallOrInvoke(llvm::FunctionCallee Callee,
48660b57cec5SDimitry Andric ArrayRef<llvm::Value *> Args,
48670b57cec5SDimitry Andric const Twine &Name) {
48680b57cec5SDimitry Andric llvm::BasicBlock *InvokeDest = getInvokeDest();
48690b57cec5SDimitry Andric SmallVector<llvm::OperandBundleDef, 1> BundleList =
48700b57cec5SDimitry Andric getBundlesForFunclet(Callee.getCallee());
48710b57cec5SDimitry Andric
48720b57cec5SDimitry Andric llvm::CallBase *Inst;
48730b57cec5SDimitry Andric if (!InvokeDest)
48740b57cec5SDimitry Andric Inst = Builder.CreateCall(Callee, Args, BundleList, Name);
48750b57cec5SDimitry Andric else {
48760b57cec5SDimitry Andric llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
48770b57cec5SDimitry Andric Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
48780b57cec5SDimitry Andric Name);
48790b57cec5SDimitry Andric EmitBlock(ContBB);
48800b57cec5SDimitry Andric }
48810b57cec5SDimitry Andric
48820b57cec5SDimitry Andric // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
48830b57cec5SDimitry Andric // optimizer it can aggressively ignore unwind edges.
48840b57cec5SDimitry Andric if (CGM.getLangOpts().ObjCAutoRefCount)
48850b57cec5SDimitry Andric AddObjCARCExceptionMetadata(Inst);
48860b57cec5SDimitry Andric
48870b57cec5SDimitry Andric return Inst;
48880b57cec5SDimitry Andric }
48890b57cec5SDimitry Andric
deferPlaceholderReplacement(llvm::Instruction * Old,llvm::Value * New)48900b57cec5SDimitry Andric void CodeGenFunction::deferPlaceholderReplacement(llvm::Instruction *Old,
48910b57cec5SDimitry Andric llvm::Value *New) {
4892fe6060f1SDimitry Andric DeferredReplacements.push_back(
4893fe6060f1SDimitry Andric std::make_pair(llvm::WeakTrackingVH(Old), New));
48940b57cec5SDimitry Andric }
48950b57cec5SDimitry Andric
48965ffd83dbSDimitry Andric namespace {
48975ffd83dbSDimitry Andric
48985ffd83dbSDimitry Andric /// Specify given \p NewAlign as the alignment of return value attribute. If
48995ffd83dbSDimitry Andric /// such attribute already exists, re-set it to the maximal one of two options.
4900bdd1243dSDimitry Andric [[nodiscard]] llvm::AttributeList
maybeRaiseRetAlignmentAttribute(llvm::LLVMContext & Ctx,const llvm::AttributeList & Attrs,llvm::Align NewAlign)49015ffd83dbSDimitry Andric maybeRaiseRetAlignmentAttribute(llvm::LLVMContext &Ctx,
49025ffd83dbSDimitry Andric const llvm::AttributeList &Attrs,
49035ffd83dbSDimitry Andric llvm::Align NewAlign) {
49045ffd83dbSDimitry Andric llvm::Align CurAlign = Attrs.getRetAlignment().valueOrOne();
49055ffd83dbSDimitry Andric if (CurAlign >= NewAlign)
49065ffd83dbSDimitry Andric return Attrs;
49075ffd83dbSDimitry Andric llvm::Attribute AlignAttr = llvm::Attribute::getWithAlignment(Ctx, NewAlign);
4908349cc55cSDimitry Andric return Attrs.removeRetAttribute(Ctx, llvm::Attribute::AttrKind::Alignment)
4909349cc55cSDimitry Andric .addRetAttribute(Ctx, AlignAttr);
49105ffd83dbSDimitry Andric }
49115ffd83dbSDimitry Andric
49125ffd83dbSDimitry Andric template <typename AlignedAttrTy> class AbstractAssumeAlignedAttrEmitter {
49135ffd83dbSDimitry Andric protected:
49145ffd83dbSDimitry Andric CodeGenFunction &CGF;
49155ffd83dbSDimitry Andric
49165ffd83dbSDimitry Andric /// We do nothing if this is, or becomes, nullptr.
49175ffd83dbSDimitry Andric const AlignedAttrTy *AA = nullptr;
49185ffd83dbSDimitry Andric
49195ffd83dbSDimitry Andric llvm::Value *Alignment = nullptr; // May or may not be a constant.
49205ffd83dbSDimitry Andric llvm::ConstantInt *OffsetCI = nullptr; // Constant, hopefully zero.
49215ffd83dbSDimitry Andric
AbstractAssumeAlignedAttrEmitter(CodeGenFunction & CGF_,const Decl * FuncDecl)49225ffd83dbSDimitry Andric AbstractAssumeAlignedAttrEmitter(CodeGenFunction &CGF_, const Decl *FuncDecl)
49235ffd83dbSDimitry Andric : CGF(CGF_) {
49245ffd83dbSDimitry Andric if (!FuncDecl)
49255ffd83dbSDimitry Andric return;
49265ffd83dbSDimitry Andric AA = FuncDecl->getAttr<AlignedAttrTy>();
49275ffd83dbSDimitry Andric }
49285ffd83dbSDimitry Andric
49295ffd83dbSDimitry Andric public:
49305ffd83dbSDimitry Andric /// If we can, materialize the alignment as an attribute on return value.
4931bdd1243dSDimitry Andric [[nodiscard]] llvm::AttributeList
TryEmitAsCallSiteAttribute(const llvm::AttributeList & Attrs)49325ffd83dbSDimitry Andric TryEmitAsCallSiteAttribute(const llvm::AttributeList &Attrs) {
49335ffd83dbSDimitry Andric if (!AA || OffsetCI || CGF.SanOpts.has(SanitizerKind::Alignment))
49345ffd83dbSDimitry Andric return Attrs;
49355ffd83dbSDimitry Andric const auto *AlignmentCI = dyn_cast<llvm::ConstantInt>(Alignment);
49365ffd83dbSDimitry Andric if (!AlignmentCI)
49375ffd83dbSDimitry Andric return Attrs;
49385ffd83dbSDimitry Andric // We may legitimately have non-power-of-2 alignment here.
49395ffd83dbSDimitry Andric // If so, this is UB land, emit it via `@llvm.assume` instead.
49405ffd83dbSDimitry Andric if (!AlignmentCI->getValue().isPowerOf2())
49415ffd83dbSDimitry Andric return Attrs;
49425ffd83dbSDimitry Andric llvm::AttributeList NewAttrs = maybeRaiseRetAlignmentAttribute(
49435ffd83dbSDimitry Andric CGF.getLLVMContext(), Attrs,
49445ffd83dbSDimitry Andric llvm::Align(
49455ffd83dbSDimitry Andric AlignmentCI->getLimitedValue(llvm::Value::MaximumAlignment)));
49465ffd83dbSDimitry Andric AA = nullptr; // We're done. Disallow doing anything else.
49475ffd83dbSDimitry Andric return NewAttrs;
49485ffd83dbSDimitry Andric }
49495ffd83dbSDimitry Andric
49505ffd83dbSDimitry Andric /// Emit alignment assumption.
49515ffd83dbSDimitry Andric /// This is a general fallback that we take if either there is an offset,
49525ffd83dbSDimitry Andric /// or the alignment is variable or we are sanitizing for alignment.
EmitAsAnAssumption(SourceLocation Loc,QualType RetTy,RValue & Ret)49535ffd83dbSDimitry Andric void EmitAsAnAssumption(SourceLocation Loc, QualType RetTy, RValue &Ret) {
49545ffd83dbSDimitry Andric if (!AA)
49555ffd83dbSDimitry Andric return;
49565ffd83dbSDimitry Andric CGF.emitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc,
49575ffd83dbSDimitry Andric AA->getLocation(), Alignment, OffsetCI);
49585ffd83dbSDimitry Andric AA = nullptr; // We're done. Disallow doing anything else.
49595ffd83dbSDimitry Andric }
49605ffd83dbSDimitry Andric };
49615ffd83dbSDimitry Andric
49625ffd83dbSDimitry Andric /// Helper data structure to emit `AssumeAlignedAttr`.
49635ffd83dbSDimitry Andric class AssumeAlignedAttrEmitter final
49645ffd83dbSDimitry Andric : public AbstractAssumeAlignedAttrEmitter<AssumeAlignedAttr> {
49655ffd83dbSDimitry Andric public:
AssumeAlignedAttrEmitter(CodeGenFunction & CGF_,const Decl * FuncDecl)49665ffd83dbSDimitry Andric AssumeAlignedAttrEmitter(CodeGenFunction &CGF_, const Decl *FuncDecl)
49675ffd83dbSDimitry Andric : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
49685ffd83dbSDimitry Andric if (!AA)
49695ffd83dbSDimitry Andric return;
49705ffd83dbSDimitry Andric // It is guaranteed that the alignment/offset are constants.
49715ffd83dbSDimitry Andric Alignment = cast<llvm::ConstantInt>(CGF.EmitScalarExpr(AA->getAlignment()));
49725ffd83dbSDimitry Andric if (Expr *Offset = AA->getOffset()) {
49735ffd83dbSDimitry Andric OffsetCI = cast<llvm::ConstantInt>(CGF.EmitScalarExpr(Offset));
49745ffd83dbSDimitry Andric if (OffsetCI->isNullValue()) // Canonicalize zero offset to no offset.
49755ffd83dbSDimitry Andric OffsetCI = nullptr;
49765ffd83dbSDimitry Andric }
49775ffd83dbSDimitry Andric }
49785ffd83dbSDimitry Andric };
49795ffd83dbSDimitry Andric
49805ffd83dbSDimitry Andric /// Helper data structure to emit `AllocAlignAttr`.
49815ffd83dbSDimitry Andric class AllocAlignAttrEmitter final
49825ffd83dbSDimitry Andric : public AbstractAssumeAlignedAttrEmitter<AllocAlignAttr> {
49835ffd83dbSDimitry Andric public:
AllocAlignAttrEmitter(CodeGenFunction & CGF_,const Decl * FuncDecl,const CallArgList & CallArgs)49845ffd83dbSDimitry Andric AllocAlignAttrEmitter(CodeGenFunction &CGF_, const Decl *FuncDecl,
49855ffd83dbSDimitry Andric const CallArgList &CallArgs)
49865ffd83dbSDimitry Andric : AbstractAssumeAlignedAttrEmitter(CGF_, FuncDecl) {
49875ffd83dbSDimitry Andric if (!AA)
49885ffd83dbSDimitry Andric return;
49895ffd83dbSDimitry Andric // Alignment may or may not be a constant, and that is okay.
49905ffd83dbSDimitry Andric Alignment = CallArgs[AA->getParamIndex().getLLVMIndex()]
49915ffd83dbSDimitry Andric .getRValue(CGF)
49925ffd83dbSDimitry Andric .getScalarVal();
49935ffd83dbSDimitry Andric }
49945ffd83dbSDimitry Andric };
49955ffd83dbSDimitry Andric
49965ffd83dbSDimitry Andric } // namespace
49975ffd83dbSDimitry Andric
getMaxVectorWidth(const llvm::Type * Ty)499881ad6265SDimitry Andric static unsigned getMaxVectorWidth(const llvm::Type *Ty) {
499981ad6265SDimitry Andric if (auto *VT = dyn_cast<llvm::VectorType>(Ty))
5000bdd1243dSDimitry Andric return VT->getPrimitiveSizeInBits().getKnownMinValue();
500181ad6265SDimitry Andric if (auto *AT = dyn_cast<llvm::ArrayType>(Ty))
500281ad6265SDimitry Andric return getMaxVectorWidth(AT->getElementType());
500381ad6265SDimitry Andric
500481ad6265SDimitry Andric unsigned MaxVectorWidth = 0;
500581ad6265SDimitry Andric if (auto *ST = dyn_cast<llvm::StructType>(Ty))
500681ad6265SDimitry Andric for (auto *I : ST->elements())
500781ad6265SDimitry Andric MaxVectorWidth = std::max(MaxVectorWidth, getMaxVectorWidth(I));
500881ad6265SDimitry Andric return MaxVectorWidth;
500981ad6265SDimitry Andric }
501081ad6265SDimitry Andric
EmitCall(const CGFunctionInfo & CallInfo,const CGCallee & Callee,ReturnValueSlot ReturnValue,const CallArgList & CallArgs,llvm::CallBase ** callOrInvoke,bool IsMustTail,SourceLocation Loc,bool IsVirtualFunctionPointerThunk)50110b57cec5SDimitry Andric RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
50120b57cec5SDimitry Andric const CGCallee &Callee,
50130b57cec5SDimitry Andric ReturnValueSlot ReturnValue,
50140b57cec5SDimitry Andric const CallArgList &CallArgs,
5015fe6060f1SDimitry Andric llvm::CallBase **callOrInvoke, bool IsMustTail,
50160fca6ea1SDimitry Andric SourceLocation Loc,
50170fca6ea1SDimitry Andric bool IsVirtualFunctionPointerThunk) {
50180b57cec5SDimitry Andric // FIXME: We no longer need the types from CallArgs; lift up and simplify.
50190b57cec5SDimitry Andric
50200b57cec5SDimitry Andric assert(Callee.isOrdinary() || Callee.isVirtual());
50210b57cec5SDimitry Andric
50220b57cec5SDimitry Andric // Handle struct-return functions by passing a pointer to the
50230b57cec5SDimitry Andric // location that we would like to return into.
50240b57cec5SDimitry Andric QualType RetTy = CallInfo.getReturnType();
50250b57cec5SDimitry Andric const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
50260b57cec5SDimitry Andric
50270b57cec5SDimitry Andric llvm::FunctionType *IRFuncTy = getTypes().GetFunctionType(CallInfo);
50280b57cec5SDimitry Andric
50290b57cec5SDimitry Andric const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl();
50305ffd83dbSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
50310b57cec5SDimitry Andric // We can only guarantee that a function is called from the correct
50320b57cec5SDimitry Andric // context/function based on the appropriate target attributes,
50330b57cec5SDimitry Andric // so only check in the case where we have both always_inline and target
50340b57cec5SDimitry Andric // since otherwise we could be making a conditional call after a check for
50350b57cec5SDimitry Andric // the proper cpu features (and it won't cause code generation issues due to
50360b57cec5SDimitry Andric // function based code generation).
50370b57cec5SDimitry Andric if (TargetDecl->hasAttr<AlwaysInlineAttr>() &&
503806c3fb27SDimitry Andric (TargetDecl->hasAttr<TargetAttr>() ||
503906c3fb27SDimitry Andric (CurFuncDecl && CurFuncDecl->hasAttr<TargetAttr>())))
50400b57cec5SDimitry Andric checkTargetFeatures(Loc, FD);
50410fca6ea1SDimitry Andric }
50420b57cec5SDimitry Andric
50435ffd83dbSDimitry Andric // Some architectures (such as x86-64) have the ABI changed based on
50445ffd83dbSDimitry Andric // attribute-target/features. Give them a chance to diagnose.
50455ffd83dbSDimitry Andric CGM.getTargetCodeGenInfo().checkFunctionCallABI(
50460fca6ea1SDimitry Andric CGM, Loc, dyn_cast_or_null<FunctionDecl>(CurCodeDecl),
50470fca6ea1SDimitry Andric dyn_cast_or_null<FunctionDecl>(TargetDecl), CallArgs, RetTy);
50485ffd83dbSDimitry Andric
50490b57cec5SDimitry Andric // 1. Set up the arguments.
50500b57cec5SDimitry Andric
50510b57cec5SDimitry Andric // If we're using inalloca, insert the allocation after the stack save.
50520b57cec5SDimitry Andric // FIXME: Do this earlier rather than hacking it in here!
50530fca6ea1SDimitry Andric RawAddress ArgMemory = RawAddress::invalid();
50540b57cec5SDimitry Andric if (llvm::StructType *ArgStruct = CallInfo.getArgStruct()) {
50550b57cec5SDimitry Andric const llvm::DataLayout &DL = CGM.getDataLayout();
50560b57cec5SDimitry Andric llvm::Instruction *IP = CallArgs.getStackBase();
50570b57cec5SDimitry Andric llvm::AllocaInst *AI;
50580b57cec5SDimitry Andric if (IP) {
50590b57cec5SDimitry Andric IP = IP->getNextNode();
50600b57cec5SDimitry Andric AI = new llvm::AllocaInst(ArgStruct, DL.getAllocaAddrSpace(),
50610b57cec5SDimitry Andric "argmem", IP);
50620b57cec5SDimitry Andric } else {
50630b57cec5SDimitry Andric AI = CreateTempAlloca(ArgStruct, "argmem");
50640b57cec5SDimitry Andric }
50650b57cec5SDimitry Andric auto Align = CallInfo.getArgStructAlignment();
5066a7dea167SDimitry Andric AI->setAlignment(Align.getAsAlign());
50670b57cec5SDimitry Andric AI->setUsedWithInAlloca(true);
50680b57cec5SDimitry Andric assert(AI->isUsedWithInAlloca() && !AI->isStaticAlloca());
50690fca6ea1SDimitry Andric ArgMemory = RawAddress(AI, ArgStruct, Align);
50700b57cec5SDimitry Andric }
50710b57cec5SDimitry Andric
50720b57cec5SDimitry Andric ClangToLLVMArgMapping IRFunctionArgs(CGM.getContext(), CallInfo);
50730b57cec5SDimitry Andric SmallVector<llvm::Value *, 16> IRCallArgs(IRFunctionArgs.totalIRArgs());
50740b57cec5SDimitry Andric
50750b57cec5SDimitry Andric // If the call returns a temporary with struct return, create a temporary
50760b57cec5SDimitry Andric // alloca to hold the result, unless one is given to us.
50770b57cec5SDimitry Andric Address SRetPtr = Address::invalid();
50780fca6ea1SDimitry Andric RawAddress SRetAlloca = RawAddress::invalid();
50790b57cec5SDimitry Andric llvm::Value *UnusedReturnSizePtr = nullptr;
50800b57cec5SDimitry Andric if (RetAI.isIndirect() || RetAI.isInAlloca() || RetAI.isCoerceAndExpand()) {
50810fca6ea1SDimitry Andric if (IsVirtualFunctionPointerThunk && RetAI.isIndirect()) {
50820fca6ea1SDimitry Andric SRetPtr = makeNaturalAddressForPointer(CurFn->arg_begin() +
50830fca6ea1SDimitry Andric IRFunctionArgs.getSRetArgNo(),
50840fca6ea1SDimitry Andric RetTy, CharUnits::fromQuantity(1));
50850fca6ea1SDimitry Andric } else if (!ReturnValue.isNull()) {
50860fca6ea1SDimitry Andric SRetPtr = ReturnValue.getAddress();
50870b57cec5SDimitry Andric } else {
50880b57cec5SDimitry Andric SRetPtr = CreateMemTemp(RetTy, "tmp", &SRetAlloca);
50890b57cec5SDimitry Andric if (HaveInsertPoint() && ReturnValue.isUnused()) {
5090fe6060f1SDimitry Andric llvm::TypeSize size =
50910b57cec5SDimitry Andric CGM.getDataLayout().getTypeAllocSize(ConvertTypeForMem(RetTy));
50920b57cec5SDimitry Andric UnusedReturnSizePtr = EmitLifetimeStart(size, SRetAlloca.getPointer());
50930b57cec5SDimitry Andric }
50940b57cec5SDimitry Andric }
50950b57cec5SDimitry Andric if (IRFunctionArgs.hasSRetArg()) {
50960fca6ea1SDimitry Andric IRCallArgs[IRFunctionArgs.getSRetArgNo()] =
50970fca6ea1SDimitry Andric getAsNaturalPointerTo(SRetPtr, RetTy);
50980b57cec5SDimitry Andric } else if (RetAI.isInAlloca()) {
50990b57cec5SDimitry Andric Address Addr =
51000b57cec5SDimitry Andric Builder.CreateStructGEP(ArgMemory, RetAI.getInAllocaFieldIndex());
51010fca6ea1SDimitry Andric Builder.CreateStore(getAsNaturalPointerTo(SRetPtr, RetTy), Addr);
51020b57cec5SDimitry Andric }
51030b57cec5SDimitry Andric }
51040b57cec5SDimitry Andric
51050fca6ea1SDimitry Andric RawAddress swiftErrorTemp = RawAddress::invalid();
51060b57cec5SDimitry Andric Address swiftErrorArg = Address::invalid();
51070b57cec5SDimitry Andric
5108a7dea167SDimitry Andric // When passing arguments using temporary allocas, we need to add the
5109a7dea167SDimitry Andric // appropriate lifetime markers. This vector keeps track of all the lifetime
5110a7dea167SDimitry Andric // markers that need to be ended right after the call.
5111a7dea167SDimitry Andric SmallVector<CallLifetimeEnd, 2> CallLifetimeEndAfterCall;
5112a7dea167SDimitry Andric
51130b57cec5SDimitry Andric // Translate all of the arguments as necessary to match the IR lowering.
51140b57cec5SDimitry Andric assert(CallInfo.arg_size() == CallArgs.size() &&
51150b57cec5SDimitry Andric "Mismatch between function signature & arguments.");
51160b57cec5SDimitry Andric unsigned ArgNo = 0;
51170b57cec5SDimitry Andric CGFunctionInfo::const_arg_iterator info_it = CallInfo.arg_begin();
51180b57cec5SDimitry Andric for (CallArgList::const_iterator I = CallArgs.begin(), E = CallArgs.end();
51190b57cec5SDimitry Andric I != E; ++I, ++info_it, ++ArgNo) {
51200b57cec5SDimitry Andric const ABIArgInfo &ArgInfo = info_it->info;
51210b57cec5SDimitry Andric
51220b57cec5SDimitry Andric // Insert a padding argument to ensure proper alignment.
51230b57cec5SDimitry Andric if (IRFunctionArgs.hasPaddingArg(ArgNo))
51240b57cec5SDimitry Andric IRCallArgs[IRFunctionArgs.getPaddingArgNo(ArgNo)] =
51250b57cec5SDimitry Andric llvm::UndefValue::get(ArgInfo.getPaddingType());
51260b57cec5SDimitry Andric
51270b57cec5SDimitry Andric unsigned FirstIRArg, NumIRArgs;
51280b57cec5SDimitry Andric std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
51290b57cec5SDimitry Andric
5130bdd1243dSDimitry Andric bool ArgHasMaybeUndefAttr =
5131bdd1243dSDimitry Andric IsArgumentMaybeUndef(TargetDecl, CallInfo.getNumRequiredArgs(), ArgNo);
5132bdd1243dSDimitry Andric
51330b57cec5SDimitry Andric switch (ArgInfo.getKind()) {
51340b57cec5SDimitry Andric case ABIArgInfo::InAlloca: {
51350b57cec5SDimitry Andric assert(NumIRArgs == 0);
51360b57cec5SDimitry Andric assert(getTarget().getTriple().getArch() == llvm::Triple::x86);
51370b57cec5SDimitry Andric if (I->isAggregate()) {
51380fca6ea1SDimitry Andric RawAddress Addr = I->hasLValue()
51390fca6ea1SDimitry Andric ? I->getKnownLValue().getAddress()
51400b57cec5SDimitry Andric : I->getKnownRValue().getAggregateAddress();
51410b57cec5SDimitry Andric llvm::Instruction *Placeholder =
51420b57cec5SDimitry Andric cast<llvm::Instruction>(Addr.getPointer());
51435ffd83dbSDimitry Andric
51445ffd83dbSDimitry Andric if (!ArgInfo.getInAllocaIndirect()) {
51455ffd83dbSDimitry Andric // Replace the placeholder with the appropriate argument slot GEP.
51460b57cec5SDimitry Andric CGBuilderTy::InsertPoint IP = Builder.saveIP();
51470b57cec5SDimitry Andric Builder.SetInsertPoint(Placeholder);
51485ffd83dbSDimitry Andric Addr = Builder.CreateStructGEP(ArgMemory,
51495ffd83dbSDimitry Andric ArgInfo.getInAllocaFieldIndex());
51500b57cec5SDimitry Andric Builder.restoreIP(IP);
51515ffd83dbSDimitry Andric } else {
51525ffd83dbSDimitry Andric // For indirect things such as overaligned structs, replace the
51535ffd83dbSDimitry Andric // placeholder with a regular aggregate temporary alloca. Store the
51545ffd83dbSDimitry Andric // address of this alloca into the struct.
51555ffd83dbSDimitry Andric Addr = CreateMemTemp(info_it->type, "inalloca.indirect.tmp");
51565ffd83dbSDimitry Andric Address ArgSlot = Builder.CreateStructGEP(
51575ffd83dbSDimitry Andric ArgMemory, ArgInfo.getInAllocaFieldIndex());
51585ffd83dbSDimitry Andric Builder.CreateStore(Addr.getPointer(), ArgSlot);
51595ffd83dbSDimitry Andric }
51600b57cec5SDimitry Andric deferPlaceholderReplacement(Placeholder, Addr.getPointer());
51615ffd83dbSDimitry Andric } else if (ArgInfo.getInAllocaIndirect()) {
51625ffd83dbSDimitry Andric // Make a temporary alloca and store the address of it into the argument
51635ffd83dbSDimitry Andric // struct.
51640fca6ea1SDimitry Andric RawAddress Addr = CreateMemTempWithoutCast(
51655ffd83dbSDimitry Andric I->Ty, getContext().getTypeAlignInChars(I->Ty),
51665ffd83dbSDimitry Andric "indirect-arg-temp");
51675ffd83dbSDimitry Andric I->copyInto(*this, Addr);
51685ffd83dbSDimitry Andric Address ArgSlot =
51695ffd83dbSDimitry Andric Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
51705ffd83dbSDimitry Andric Builder.CreateStore(Addr.getPointer(), ArgSlot);
51710b57cec5SDimitry Andric } else {
51720b57cec5SDimitry Andric // Store the RValue into the argument struct.
51730b57cec5SDimitry Andric Address Addr =
51740b57cec5SDimitry Andric Builder.CreateStructGEP(ArgMemory, ArgInfo.getInAllocaFieldIndex());
517506c3fb27SDimitry Andric Addr = Addr.withElementType(ConvertTypeForMem(I->Ty));
51760b57cec5SDimitry Andric I->copyInto(*this, Addr);
51770b57cec5SDimitry Andric }
51780b57cec5SDimitry Andric break;
51790b57cec5SDimitry Andric }
51800b57cec5SDimitry Andric
5181e8d8bef9SDimitry Andric case ABIArgInfo::Indirect:
5182e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased: {
51830b57cec5SDimitry Andric assert(NumIRArgs == 1);
51840fca6ea1SDimitry Andric if (I->isAggregate()) {
51850b57cec5SDimitry Andric // We want to avoid creating an unnecessary temporary+copy here;
51860b57cec5SDimitry Andric // however, we need one in three cases:
51870b57cec5SDimitry Andric // 1. If the argument is not byval, and we are required to copy the
51880b57cec5SDimitry Andric // source. (This case doesn't occur on any common architecture.)
51890b57cec5SDimitry Andric // 2. If the argument is byval, RV is not sufficiently aligned, and
51900b57cec5SDimitry Andric // we cannot force it to be sufficiently aligned.
51910b57cec5SDimitry Andric // 3. If the argument is byval, but RV is not located in default
51920b57cec5SDimitry Andric // or alloca address space.
51930b57cec5SDimitry Andric Address Addr = I->hasLValue()
51940fca6ea1SDimitry Andric ? I->getKnownLValue().getAddress()
51950b57cec5SDimitry Andric : I->getKnownRValue().getAggregateAddress();
51960b57cec5SDimitry Andric CharUnits Align = ArgInfo.getIndirectAlign();
51970b57cec5SDimitry Andric const llvm::DataLayout *TD = &CGM.getDataLayout();
51980b57cec5SDimitry Andric
51990b57cec5SDimitry Andric assert((FirstIRArg >= IRFuncTy->getNumParams() ||
52000b57cec5SDimitry Andric IRFuncTy->getParamType(FirstIRArg)->getPointerAddressSpace() ==
52010b57cec5SDimitry Andric TD->getAllocaAddrSpace()) &&
52020b57cec5SDimitry Andric "indirect argument must be in alloca address space");
52030b57cec5SDimitry Andric
52040b57cec5SDimitry Andric bool NeedCopy = false;
52050b57cec5SDimitry Andric if (Addr.getAlignment() < Align &&
52060fca6ea1SDimitry Andric llvm::getOrEnforceKnownAlignment(Addr.emitRawPointer(*this),
52070fca6ea1SDimitry Andric Align.getAsAlign(),
52080fca6ea1SDimitry Andric *TD) < Align.getAsAlign()) {
52090b57cec5SDimitry Andric NeedCopy = true;
52100b57cec5SDimitry Andric } else if (I->hasLValue()) {
52110b57cec5SDimitry Andric auto LV = I->getKnownLValue();
52120b57cec5SDimitry Andric auto AS = LV.getAddressSpace();
52130b57cec5SDimitry Andric
52145f757f3fSDimitry Andric bool isByValOrRef =
52155f757f3fSDimitry Andric ArgInfo.isIndirectAliased() || ArgInfo.getIndirectByVal();
52165f757f3fSDimitry Andric
52175f757f3fSDimitry Andric if (!isByValOrRef ||
5218480093f4SDimitry Andric (LV.getAlignment() < getContext().getTypeAlignInChars(I->Ty))) {
52190b57cec5SDimitry Andric NeedCopy = true;
52200b57cec5SDimitry Andric }
52210b57cec5SDimitry Andric if (!getLangOpts().OpenCL) {
52225f757f3fSDimitry Andric if ((isByValOrRef &&
52230b57cec5SDimitry Andric (AS != LangAS::Default &&
52240b57cec5SDimitry Andric AS != CGM.getASTAllocaAddressSpace()))) {
52250b57cec5SDimitry Andric NeedCopy = true;
52260b57cec5SDimitry Andric }
52270b57cec5SDimitry Andric }
52280b57cec5SDimitry Andric // For OpenCL even if RV is located in default or alloca address space
52290b57cec5SDimitry Andric // we don't want to perform address space cast for it.
52305f757f3fSDimitry Andric else if ((isByValOrRef &&
52310b57cec5SDimitry Andric Addr.getType()->getAddressSpace() != IRFuncTy->
52320b57cec5SDimitry Andric getParamType(FirstIRArg)->getPointerAddressSpace())) {
52330b57cec5SDimitry Andric NeedCopy = true;
52340b57cec5SDimitry Andric }
52350b57cec5SDimitry Andric }
52360b57cec5SDimitry Andric
52370fca6ea1SDimitry Andric if (!NeedCopy) {
52380fca6ea1SDimitry Andric // Skip the extra memcpy call.
52390fca6ea1SDimitry Andric llvm::Value *V = getAsNaturalPointerTo(Addr, I->Ty);
52400fca6ea1SDimitry Andric auto *T = llvm::PointerType::get(
52410fca6ea1SDimitry Andric CGM.getLLVMContext(), CGM.getDataLayout().getAllocaAddrSpace());
52420fca6ea1SDimitry Andric
52430fca6ea1SDimitry Andric llvm::Value *Val = getTargetHooks().performAddrSpaceCast(
52440fca6ea1SDimitry Andric *this, V, LangAS::Default, CGM.getASTAllocaAddressSpace(), T,
52450fca6ea1SDimitry Andric true);
5246bdd1243dSDimitry Andric if (ArgHasMaybeUndefAttr)
52470fca6ea1SDimitry Andric Val = Builder.CreateFreeze(Val);
52480fca6ea1SDimitry Andric IRCallArgs[FirstIRArg] = Val;
52490fca6ea1SDimitry Andric break;
52500fca6ea1SDimitry Andric }
52510fca6ea1SDimitry Andric }
52520fca6ea1SDimitry Andric
52530fca6ea1SDimitry Andric // For non-aggregate args and aggregate args meeting conditions above
52540fca6ea1SDimitry Andric // we need to create an aligned temporary, and copy to it.
52550fca6ea1SDimitry Andric RawAddress AI = CreateMemTempWithoutCast(
52560fca6ea1SDimitry Andric I->Ty, ArgInfo.getIndirectAlign(), "byval-temp");
52570fca6ea1SDimitry Andric llvm::Value *Val = getAsNaturalPointerTo(AI, I->Ty);
52580fca6ea1SDimitry Andric if (ArgHasMaybeUndefAttr)
52590fca6ea1SDimitry Andric Val = Builder.CreateFreeze(Val);
5260bdd1243dSDimitry Andric IRCallArgs[FirstIRArg] = Val;
5261a7dea167SDimitry Andric
5262a7dea167SDimitry Andric // Emit lifetime markers for the temporary alloca.
5263fe6060f1SDimitry Andric llvm::TypeSize ByvalTempElementSize =
5264a7dea167SDimitry Andric CGM.getDataLayout().getTypeAllocSize(AI.getElementType());
5265a7dea167SDimitry Andric llvm::Value *LifetimeSize =
5266a7dea167SDimitry Andric EmitLifetimeStart(ByvalTempElementSize, AI.getPointer());
5267a7dea167SDimitry Andric
5268a7dea167SDimitry Andric // Add cleanup code to emit the end lifetime marker after the call.
5269a7dea167SDimitry Andric if (LifetimeSize) // In case we disabled lifetime markers.
5270a7dea167SDimitry Andric CallLifetimeEndAfterCall.emplace_back(AI, LifetimeSize);
5271a7dea167SDimitry Andric
5272a7dea167SDimitry Andric // Generate the copy.
52730b57cec5SDimitry Andric I->copyInto(*this, AI);
52740b57cec5SDimitry Andric break;
52750b57cec5SDimitry Andric }
52760b57cec5SDimitry Andric
52770b57cec5SDimitry Andric case ABIArgInfo::Ignore:
52780b57cec5SDimitry Andric assert(NumIRArgs == 0);
52790b57cec5SDimitry Andric break;
52800b57cec5SDimitry Andric
52810b57cec5SDimitry Andric case ABIArgInfo::Extend:
52820b57cec5SDimitry Andric case ABIArgInfo::Direct: {
52830b57cec5SDimitry Andric if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) &&
52840b57cec5SDimitry Andric ArgInfo.getCoerceToType() == ConvertType(info_it->type) &&
52850b57cec5SDimitry Andric ArgInfo.getDirectOffset() == 0) {
52860b57cec5SDimitry Andric assert(NumIRArgs == 1);
52870b57cec5SDimitry Andric llvm::Value *V;
52880b57cec5SDimitry Andric if (!I->isAggregate())
52890b57cec5SDimitry Andric V = I->getKnownRValue().getScalarVal();
52900b57cec5SDimitry Andric else
52910b57cec5SDimitry Andric V = Builder.CreateLoad(
52920fca6ea1SDimitry Andric I->hasLValue() ? I->getKnownLValue().getAddress()
52930b57cec5SDimitry Andric : I->getKnownRValue().getAggregateAddress());
52940b57cec5SDimitry Andric
52950b57cec5SDimitry Andric // Implement swifterror by copying into a new swifterror argument.
52960b57cec5SDimitry Andric // We'll write back in the normal path out of the call.
52970b57cec5SDimitry Andric if (CallInfo.getExtParameterInfo(ArgNo).getABI()
52980b57cec5SDimitry Andric == ParameterABI::SwiftErrorResult) {
52990b57cec5SDimitry Andric assert(!swiftErrorTemp.isValid() && "multiple swifterror args");
53000b57cec5SDimitry Andric
53010b57cec5SDimitry Andric QualType pointeeTy = I->Ty->getPointeeType();
53020fca6ea1SDimitry Andric swiftErrorArg = makeNaturalAddressForPointer(
53030fca6ea1SDimitry Andric V, pointeeTy, getContext().getTypeAlignInChars(pointeeTy));
53040b57cec5SDimitry Andric
53050b57cec5SDimitry Andric swiftErrorTemp =
53060b57cec5SDimitry Andric CreateMemTemp(pointeeTy, getPointerAlign(), "swifterror.temp");
53070b57cec5SDimitry Andric V = swiftErrorTemp.getPointer();
53080b57cec5SDimitry Andric cast<llvm::AllocaInst>(V)->setSwiftError(true);
53090b57cec5SDimitry Andric
53100b57cec5SDimitry Andric llvm::Value *errorValue = Builder.CreateLoad(swiftErrorArg);
53110b57cec5SDimitry Andric Builder.CreateStore(errorValue, swiftErrorTemp);
53120b57cec5SDimitry Andric }
53130b57cec5SDimitry Andric
53140b57cec5SDimitry Andric // We might have to widen integers, but we should never truncate.
53150b57cec5SDimitry Andric if (ArgInfo.getCoerceToType() != V->getType() &&
53160b57cec5SDimitry Andric V->getType()->isIntegerTy())
53170b57cec5SDimitry Andric V = Builder.CreateZExt(V, ArgInfo.getCoerceToType());
53180b57cec5SDimitry Andric
53190b57cec5SDimitry Andric // If the argument doesn't match, perform a bitcast to coerce it. This
53200b57cec5SDimitry Andric // can happen due to trivial type mismatches.
53210b57cec5SDimitry Andric if (FirstIRArg < IRFuncTy->getNumParams() &&
53220b57cec5SDimitry Andric V->getType() != IRFuncTy->getParamType(FirstIRArg))
53230b57cec5SDimitry Andric V = Builder.CreateBitCast(V, IRFuncTy->getParamType(FirstIRArg));
53240b57cec5SDimitry Andric
5325bdd1243dSDimitry Andric if (ArgHasMaybeUndefAttr)
5326bdd1243dSDimitry Andric V = Builder.CreateFreeze(V);
53270b57cec5SDimitry Andric IRCallArgs[FirstIRArg] = V;
53280b57cec5SDimitry Andric break;
53290b57cec5SDimitry Andric }
53300b57cec5SDimitry Andric
53310fca6ea1SDimitry Andric llvm::StructType *STy =
53320fca6ea1SDimitry Andric dyn_cast<llvm::StructType>(ArgInfo.getCoerceToType());
53330fca6ea1SDimitry Andric if (STy && ArgInfo.isDirect() && !ArgInfo.getCanBeFlattened()) {
53340fca6ea1SDimitry Andric llvm::Type *SrcTy = ConvertTypeForMem(I->Ty);
53350fca6ea1SDimitry Andric [[maybe_unused]] llvm::TypeSize SrcTypeSize =
53360fca6ea1SDimitry Andric CGM.getDataLayout().getTypeAllocSize(SrcTy);
53370fca6ea1SDimitry Andric [[maybe_unused]] llvm::TypeSize DstTypeSize =
53380fca6ea1SDimitry Andric CGM.getDataLayout().getTypeAllocSize(STy);
53390fca6ea1SDimitry Andric if (STy->containsHomogeneousScalableVectorTypes()) {
53400fca6ea1SDimitry Andric assert(SrcTypeSize == DstTypeSize &&
53410fca6ea1SDimitry Andric "Only allow non-fractional movement of structure with "
53420fca6ea1SDimitry Andric "homogeneous scalable vector type");
53430fca6ea1SDimitry Andric
53440fca6ea1SDimitry Andric IRCallArgs[FirstIRArg] = I->getKnownRValue().getScalarVal();
53450fca6ea1SDimitry Andric break;
53460fca6ea1SDimitry Andric }
53470fca6ea1SDimitry Andric }
53480fca6ea1SDimitry Andric
53490b57cec5SDimitry Andric // FIXME: Avoid the conversion through memory if possible.
53500b57cec5SDimitry Andric Address Src = Address::invalid();
53510b57cec5SDimitry Andric if (!I->isAggregate()) {
53520b57cec5SDimitry Andric Src = CreateMemTemp(I->Ty, "coerce");
53530b57cec5SDimitry Andric I->copyInto(*this, Src);
53540b57cec5SDimitry Andric } else {
53550fca6ea1SDimitry Andric Src = I->hasLValue() ? I->getKnownLValue().getAddress()
53560b57cec5SDimitry Andric : I->getKnownRValue().getAggregateAddress();
53570b57cec5SDimitry Andric }
53580b57cec5SDimitry Andric
53590b57cec5SDimitry Andric // If the value is offset in memory, apply the offset now.
53600b57cec5SDimitry Andric Src = emitAddressAtOffset(*this, Src, ArgInfo);
53610b57cec5SDimitry Andric
53620b57cec5SDimitry Andric // Fast-isel and the optimizer generally like scalar values better than
53630b57cec5SDimitry Andric // FCAs, so we flatten them if this is safe to do for this argument.
53640b57cec5SDimitry Andric if (STy && ArgInfo.isDirect() && ArgInfo.getCanBeFlattened()) {
53655ffd83dbSDimitry Andric llvm::Type *SrcTy = Src.getElementType();
53668a4dda33SDimitry Andric llvm::TypeSize SrcTypeSize =
53678a4dda33SDimitry Andric CGM.getDataLayout().getTypeAllocSize(SrcTy);
53688a4dda33SDimitry Andric llvm::TypeSize DstTypeSize = CGM.getDataLayout().getTypeAllocSize(STy);
53698a4dda33SDimitry Andric if (SrcTypeSize.isScalable()) {
53708a4dda33SDimitry Andric assert(STy->containsHomogeneousScalableVectorTypes() &&
53718a4dda33SDimitry Andric "ABI only supports structure with homogeneous scalable vector "
53728a4dda33SDimitry Andric "type");
53738a4dda33SDimitry Andric assert(SrcTypeSize == DstTypeSize &&
53748a4dda33SDimitry Andric "Only allow non-fractional movement of structure with "
53758a4dda33SDimitry Andric "homogeneous scalable vector type");
53768a4dda33SDimitry Andric assert(NumIRArgs == STy->getNumElements());
53778a4dda33SDimitry Andric
53788a4dda33SDimitry Andric llvm::Value *StoredStructValue =
53798a4dda33SDimitry Andric Builder.CreateLoad(Src, Src.getName() + ".tuple");
53808a4dda33SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
53818a4dda33SDimitry Andric llvm::Value *Extract = Builder.CreateExtractValue(
53828a4dda33SDimitry Andric StoredStructValue, i, Src.getName() + ".extract" + Twine(i));
53838a4dda33SDimitry Andric IRCallArgs[FirstIRArg + i] = Extract;
53848a4dda33SDimitry Andric }
53858a4dda33SDimitry Andric } else {
53868a4dda33SDimitry Andric uint64_t SrcSize = SrcTypeSize.getFixedValue();
53878a4dda33SDimitry Andric uint64_t DstSize = DstTypeSize.getFixedValue();
53880b57cec5SDimitry Andric
53890b57cec5SDimitry Andric // If the source type is smaller than the destination type of the
53900b57cec5SDimitry Andric // coerce-to logic, copy the source value into a temp alloca the size
53910b57cec5SDimitry Andric // of the destination type to allow loading all of it. The bits past
53920b57cec5SDimitry Andric // the source value are left undef.
53930b57cec5SDimitry Andric if (SrcSize < DstSize) {
53948a4dda33SDimitry Andric Address TempAlloca = CreateTempAlloca(STy, Src.getAlignment(),
53950b57cec5SDimitry Andric Src.getName() + ".coerce");
53960b57cec5SDimitry Andric Builder.CreateMemCpy(TempAlloca, Src, SrcSize);
53970b57cec5SDimitry Andric Src = TempAlloca;
53980b57cec5SDimitry Andric } else {
539906c3fb27SDimitry Andric Src = Src.withElementType(STy);
54000b57cec5SDimitry Andric }
54010b57cec5SDimitry Andric
54020b57cec5SDimitry Andric assert(NumIRArgs == STy->getNumElements());
54030b57cec5SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
54040b57cec5SDimitry Andric Address EltPtr = Builder.CreateStructGEP(Src, i);
54050b57cec5SDimitry Andric llvm::Value *LI = Builder.CreateLoad(EltPtr);
5406bdd1243dSDimitry Andric if (ArgHasMaybeUndefAttr)
5407bdd1243dSDimitry Andric LI = Builder.CreateFreeze(LI);
54080b57cec5SDimitry Andric IRCallArgs[FirstIRArg + i] = LI;
54090b57cec5SDimitry Andric }
54108a4dda33SDimitry Andric }
54110b57cec5SDimitry Andric } else {
54120b57cec5SDimitry Andric // In the simple case, just pass the coerced loaded value.
54130b57cec5SDimitry Andric assert(NumIRArgs == 1);
54145ffd83dbSDimitry Andric llvm::Value *Load =
54150b57cec5SDimitry Andric CreateCoercedLoad(Src, ArgInfo.getCoerceToType(), *this);
54165ffd83dbSDimitry Andric
54175ffd83dbSDimitry Andric if (CallInfo.isCmseNSCall()) {
54185ffd83dbSDimitry Andric // For certain parameter types, clear padding bits, as they may reveal
54195ffd83dbSDimitry Andric // sensitive information.
54205ffd83dbSDimitry Andric // Small struct/union types are passed as integer arrays.
54215ffd83dbSDimitry Andric auto *ATy = dyn_cast<llvm::ArrayType>(Load->getType());
54225ffd83dbSDimitry Andric if (ATy != nullptr && isa<RecordType>(I->Ty.getCanonicalType()))
54235ffd83dbSDimitry Andric Load = EmitCMSEClearRecord(Load, ATy, I->Ty);
54245ffd83dbSDimitry Andric }
5425bdd1243dSDimitry Andric
5426bdd1243dSDimitry Andric if (ArgHasMaybeUndefAttr)
5427bdd1243dSDimitry Andric Load = Builder.CreateFreeze(Load);
54285ffd83dbSDimitry Andric IRCallArgs[FirstIRArg] = Load;
54290b57cec5SDimitry Andric }
54300b57cec5SDimitry Andric
54310b57cec5SDimitry Andric break;
54320b57cec5SDimitry Andric }
54330b57cec5SDimitry Andric
54340b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand: {
54350b57cec5SDimitry Andric auto coercionType = ArgInfo.getCoerceAndExpandType();
54360b57cec5SDimitry Andric auto layout = CGM.getDataLayout().getStructLayout(coercionType);
54370b57cec5SDimitry Andric
54380b57cec5SDimitry Andric llvm::Value *tempSize = nullptr;
54390b57cec5SDimitry Andric Address addr = Address::invalid();
54400fca6ea1SDimitry Andric RawAddress AllocaAddr = RawAddress::invalid();
54410b57cec5SDimitry Andric if (I->isAggregate()) {
54420fca6ea1SDimitry Andric addr = I->hasLValue() ? I->getKnownLValue().getAddress()
54430b57cec5SDimitry Andric : I->getKnownRValue().getAggregateAddress();
54440b57cec5SDimitry Andric
54450b57cec5SDimitry Andric } else {
54460b57cec5SDimitry Andric RValue RV = I->getKnownRValue();
54470b57cec5SDimitry Andric assert(RV.isScalar()); // complex should always just be direct
54480b57cec5SDimitry Andric
54490b57cec5SDimitry Andric llvm::Type *scalarType = RV.getScalarVal()->getType();
54500b57cec5SDimitry Andric auto scalarSize = CGM.getDataLayout().getTypeAllocSize(scalarType);
5451bdd1243dSDimitry Andric auto scalarAlign = CGM.getDataLayout().getPrefTypeAlign(scalarType);
54520b57cec5SDimitry Andric
54530b57cec5SDimitry Andric // Materialize to a temporary.
5454bdd1243dSDimitry Andric addr = CreateTempAlloca(
5455bdd1243dSDimitry Andric RV.getScalarVal()->getType(),
5456bdd1243dSDimitry Andric CharUnits::fromQuantity(std::max(layout->getAlignment(), scalarAlign)),
54570b57cec5SDimitry Andric "tmp",
54580b57cec5SDimitry Andric /*ArraySize=*/nullptr, &AllocaAddr);
54590b57cec5SDimitry Andric tempSize = EmitLifetimeStart(scalarSize, AllocaAddr.getPointer());
54600b57cec5SDimitry Andric
54610b57cec5SDimitry Andric Builder.CreateStore(RV.getScalarVal(), addr);
54620b57cec5SDimitry Andric }
54630b57cec5SDimitry Andric
546406c3fb27SDimitry Andric addr = addr.withElementType(coercionType);
54650b57cec5SDimitry Andric
54660b57cec5SDimitry Andric unsigned IRArgPos = FirstIRArg;
54670b57cec5SDimitry Andric for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
54680b57cec5SDimitry Andric llvm::Type *eltType = coercionType->getElementType(i);
54690b57cec5SDimitry Andric if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType)) continue;
54700b57cec5SDimitry Andric Address eltAddr = Builder.CreateStructGEP(addr, i);
54710b57cec5SDimitry Andric llvm::Value *elt = Builder.CreateLoad(eltAddr);
5472bdd1243dSDimitry Andric if (ArgHasMaybeUndefAttr)
5473bdd1243dSDimitry Andric elt = Builder.CreateFreeze(elt);
54740b57cec5SDimitry Andric IRCallArgs[IRArgPos++] = elt;
54750b57cec5SDimitry Andric }
54760b57cec5SDimitry Andric assert(IRArgPos == FirstIRArg + NumIRArgs);
54770b57cec5SDimitry Andric
54780b57cec5SDimitry Andric if (tempSize) {
54790b57cec5SDimitry Andric EmitLifetimeEnd(tempSize, AllocaAddr.getPointer());
54800b57cec5SDimitry Andric }
54810b57cec5SDimitry Andric
54820b57cec5SDimitry Andric break;
54830b57cec5SDimitry Andric }
54840b57cec5SDimitry Andric
5485e8d8bef9SDimitry Andric case ABIArgInfo::Expand: {
54860b57cec5SDimitry Andric unsigned IRArgPos = FirstIRArg;
54870b57cec5SDimitry Andric ExpandTypeToArgs(I->Ty, *I, IRFuncTy, IRCallArgs, IRArgPos);
54880b57cec5SDimitry Andric assert(IRArgPos == FirstIRArg + NumIRArgs);
54890b57cec5SDimitry Andric break;
54900b57cec5SDimitry Andric }
54910b57cec5SDimitry Andric }
5492e8d8bef9SDimitry Andric }
54930b57cec5SDimitry Andric
54940b57cec5SDimitry Andric const CGCallee &ConcreteCallee = Callee.prepareConcreteCallee(*this);
54950b57cec5SDimitry Andric llvm::Value *CalleePtr = ConcreteCallee.getFunctionPointer();
54960b57cec5SDimitry Andric
54970b57cec5SDimitry Andric // If we're using inalloca, set up that argument.
54980b57cec5SDimitry Andric if (ArgMemory.isValid()) {
54990b57cec5SDimitry Andric llvm::Value *Arg = ArgMemory.getPointer();
55000b57cec5SDimitry Andric assert(IRFunctionArgs.hasInallocaArg());
55010b57cec5SDimitry Andric IRCallArgs[IRFunctionArgs.getInallocaArgNo()] = Arg;
55020b57cec5SDimitry Andric }
55030b57cec5SDimitry Andric
55040b57cec5SDimitry Andric // 2. Prepare the function pointer.
55050b57cec5SDimitry Andric
55060b57cec5SDimitry Andric // If the callee is a bitcast of a non-variadic function to have a
55070b57cec5SDimitry Andric // variadic function pointer type, check to see if we can remove the
55080b57cec5SDimitry Andric // bitcast. This comes up with unprototyped functions.
55090b57cec5SDimitry Andric //
55100b57cec5SDimitry Andric // This makes the IR nicer, but more importantly it ensures that we
55110b57cec5SDimitry Andric // can inline the function at -O0 if it is marked always_inline.
55120b57cec5SDimitry Andric auto simplifyVariadicCallee = [](llvm::FunctionType *CalleeFT,
55130b57cec5SDimitry Andric llvm::Value *Ptr) -> llvm::Function * {
55140b57cec5SDimitry Andric if (!CalleeFT->isVarArg())
55150b57cec5SDimitry Andric return nullptr;
55160b57cec5SDimitry Andric
55170b57cec5SDimitry Andric // Get underlying value if it's a bitcast
55180b57cec5SDimitry Andric if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Ptr)) {
55190b57cec5SDimitry Andric if (CE->getOpcode() == llvm::Instruction::BitCast)
55200b57cec5SDimitry Andric Ptr = CE->getOperand(0);
55210b57cec5SDimitry Andric }
55220b57cec5SDimitry Andric
55230b57cec5SDimitry Andric llvm::Function *OrigFn = dyn_cast<llvm::Function>(Ptr);
55240b57cec5SDimitry Andric if (!OrigFn)
55250b57cec5SDimitry Andric return nullptr;
55260b57cec5SDimitry Andric
55270b57cec5SDimitry Andric llvm::FunctionType *OrigFT = OrigFn->getFunctionType();
55280b57cec5SDimitry Andric
55290b57cec5SDimitry Andric // If the original type is variadic, or if any of the component types
55300b57cec5SDimitry Andric // disagree, we cannot remove the cast.
55310b57cec5SDimitry Andric if (OrigFT->isVarArg() ||
55320b57cec5SDimitry Andric OrigFT->getNumParams() != CalleeFT->getNumParams() ||
55330b57cec5SDimitry Andric OrigFT->getReturnType() != CalleeFT->getReturnType())
55340b57cec5SDimitry Andric return nullptr;
55350b57cec5SDimitry Andric
55360b57cec5SDimitry Andric for (unsigned i = 0, e = OrigFT->getNumParams(); i != e; ++i)
55370b57cec5SDimitry Andric if (OrigFT->getParamType(i) != CalleeFT->getParamType(i))
55380b57cec5SDimitry Andric return nullptr;
55390b57cec5SDimitry Andric
55400b57cec5SDimitry Andric return OrigFn;
55410b57cec5SDimitry Andric };
55420b57cec5SDimitry Andric
55430b57cec5SDimitry Andric if (llvm::Function *OrigFn = simplifyVariadicCallee(IRFuncTy, CalleePtr)) {
55440b57cec5SDimitry Andric CalleePtr = OrigFn;
55450b57cec5SDimitry Andric IRFuncTy = OrigFn->getFunctionType();
55460b57cec5SDimitry Andric }
55470b57cec5SDimitry Andric
55480b57cec5SDimitry Andric // 3. Perform the actual call.
55490b57cec5SDimitry Andric
55500b57cec5SDimitry Andric // Deactivate any cleanups that we're supposed to do immediately before
55510b57cec5SDimitry Andric // the call.
55520b57cec5SDimitry Andric if (!CallArgs.getCleanupsToDeactivate().empty())
55530b57cec5SDimitry Andric deactivateArgCleanupsBeforeCall(*this, CallArgs);
55540b57cec5SDimitry Andric
55550b57cec5SDimitry Andric // Assert that the arguments we computed match up. The IR verifier
55560b57cec5SDimitry Andric // will catch this, but this is a common enough source of problems
55570b57cec5SDimitry Andric // during IRGen changes that it's way better for debugging to catch
55580b57cec5SDimitry Andric // it ourselves here.
55590b57cec5SDimitry Andric #ifndef NDEBUG
55600b57cec5SDimitry Andric assert(IRCallArgs.size() == IRFuncTy->getNumParams() || IRFuncTy->isVarArg());
55610b57cec5SDimitry Andric for (unsigned i = 0; i < IRCallArgs.size(); ++i) {
55620b57cec5SDimitry Andric // Inalloca argument can have different type.
55630b57cec5SDimitry Andric if (IRFunctionArgs.hasInallocaArg() &&
55640b57cec5SDimitry Andric i == IRFunctionArgs.getInallocaArgNo())
55650b57cec5SDimitry Andric continue;
55660b57cec5SDimitry Andric if (i < IRFuncTy->getNumParams())
55670b57cec5SDimitry Andric assert(IRCallArgs[i]->getType() == IRFuncTy->getParamType(i));
55680b57cec5SDimitry Andric }
55690b57cec5SDimitry Andric #endif
55700b57cec5SDimitry Andric
55710b57cec5SDimitry Andric // Update the largest vector width if any arguments have vector types.
557281ad6265SDimitry Andric for (unsigned i = 0; i < IRCallArgs.size(); ++i)
557381ad6265SDimitry Andric LargestVectorWidth = std::max(LargestVectorWidth,
557481ad6265SDimitry Andric getMaxVectorWidth(IRCallArgs[i]->getType()));
55750b57cec5SDimitry Andric
55760b57cec5SDimitry Andric // Compute the calling convention and attributes.
55770b57cec5SDimitry Andric unsigned CallingConv;
55780b57cec5SDimitry Andric llvm::AttributeList Attrs;
55790b57cec5SDimitry Andric CGM.ConstructAttributeList(CalleePtr->getName(), CallInfo,
55800b57cec5SDimitry Andric Callee.getAbstractInfo(), Attrs, CallingConv,
5581fe6060f1SDimitry Andric /*AttrOnCallSite=*/true,
5582fe6060f1SDimitry Andric /*IsThunk=*/false);
55830b57cec5SDimitry Andric
55840fca6ea1SDimitry Andric if (CallingConv == llvm::CallingConv::X86_VectorCall &&
55850fca6ea1SDimitry Andric getTarget().getTriple().isWindowsArm64EC()) {
55860fca6ea1SDimitry Andric CGM.Error(Loc, "__vectorcall calling convention is not currently "
55870fca6ea1SDimitry Andric "supported");
55880fca6ea1SDimitry Andric }
55890fca6ea1SDimitry Andric
55905f757f3fSDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
5591e8d8bef9SDimitry Andric if (FD->hasAttr<StrictFPAttr>())
5592480093f4SDimitry Andric // All calls within a strictfp function are marked strictfp
5593349cc55cSDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP);
5594480093f4SDimitry Andric
55955f757f3fSDimitry Andric // If -ffast-math is enabled and the function is guarded by an
55965f757f3fSDimitry Andric // '__attribute__((optnone)) adjust the memory attribute so the BE emits the
55975f757f3fSDimitry Andric // library call instead of the intrinsic.
55985f757f3fSDimitry Andric if (FD->hasAttr<OptimizeNoneAttr>() && getLangOpts().FastMath)
55995f757f3fSDimitry Andric CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
56005f757f3fSDimitry Andric Attrs);
56015f757f3fSDimitry Andric }
56025ffd83dbSDimitry Andric // Add call-site nomerge attribute if exists.
56035ffd83dbSDimitry Andric if (InNoMergeAttributedStmt)
5604349cc55cSDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoMerge);
56055ffd83dbSDimitry Andric
560681ad6265SDimitry Andric // Add call-site noinline attribute if exists.
560781ad6265SDimitry Andric if (InNoInlineAttributedStmt)
560881ad6265SDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
560981ad6265SDimitry Andric
561081ad6265SDimitry Andric // Add call-site always_inline attribute if exists.
561181ad6265SDimitry Andric if (InAlwaysInlineAttributedStmt)
561281ad6265SDimitry Andric Attrs =
561381ad6265SDimitry Andric Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline);
561481ad6265SDimitry Andric
56150b57cec5SDimitry Andric // Apply some call-site-specific attributes.
56160b57cec5SDimitry Andric // TODO: work this into building the attribute set.
56170b57cec5SDimitry Andric
56180b57cec5SDimitry Andric // Apply always_inline to all calls within flatten functions.
56190b57cec5SDimitry Andric // FIXME: should this really take priority over __try, below?
56200b57cec5SDimitry Andric if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
562181ad6265SDimitry Andric !InNoInlineAttributedStmt &&
56220b57cec5SDimitry Andric !(TargetDecl && TargetDecl->hasAttr<NoInlineAttr>())) {
56230b57cec5SDimitry Andric Attrs =
5624349cc55cSDimitry Andric Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline);
56250b57cec5SDimitry Andric }
56260b57cec5SDimitry Andric
56270b57cec5SDimitry Andric // Disable inlining inside SEH __try blocks.
56280b57cec5SDimitry Andric if (isSEHTryScope()) {
5629349cc55cSDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
56300b57cec5SDimitry Andric }
56310b57cec5SDimitry Andric
56320b57cec5SDimitry Andric // Decide whether to use a call or an invoke.
56330b57cec5SDimitry Andric bool CannotThrow;
56340b57cec5SDimitry Andric if (currentFunctionUsesSEHTry()) {
56350b57cec5SDimitry Andric // SEH cares about asynchronous exceptions, so everything can "throw."
56360b57cec5SDimitry Andric CannotThrow = false;
56370b57cec5SDimitry Andric } else if (isCleanupPadScope() &&
56380b57cec5SDimitry Andric EHPersonality::get(*this).isMSVCXXPersonality()) {
56390b57cec5SDimitry Andric // The MSVC++ personality will implicitly terminate the program if an
56400b57cec5SDimitry Andric // exception is thrown during a cleanup outside of a try/catch.
56410b57cec5SDimitry Andric // We don't need to model anything in IR to get this behavior.
56420b57cec5SDimitry Andric CannotThrow = true;
56430b57cec5SDimitry Andric } else {
56440b57cec5SDimitry Andric // Otherwise, nounwind call sites will never throw.
5645349cc55cSDimitry Andric CannotThrow = Attrs.hasFnAttr(llvm::Attribute::NoUnwind);
5646e8d8bef9SDimitry Andric
5647e8d8bef9SDimitry Andric if (auto *FPtr = dyn_cast<llvm::Function>(CalleePtr))
5648e8d8bef9SDimitry Andric if (FPtr->hasFnAttribute(llvm::Attribute::NoUnwind))
5649e8d8bef9SDimitry Andric CannotThrow = true;
56500b57cec5SDimitry Andric }
56510b57cec5SDimitry Andric
56520b57cec5SDimitry Andric // If we made a temporary, be sure to clean up after ourselves. Note that we
56530b57cec5SDimitry Andric // can't depend on being inside of an ExprWithCleanups, so we need to manually
56540b57cec5SDimitry Andric // pop this cleanup later on. Being eager about this is OK, since this
56550b57cec5SDimitry Andric // temporary is 'invisible' outside of the callee.
56560b57cec5SDimitry Andric if (UnusedReturnSizePtr)
56570b57cec5SDimitry Andric pushFullExprCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker, SRetAlloca,
56580b57cec5SDimitry Andric UnusedReturnSizePtr);
56590b57cec5SDimitry Andric
56600b57cec5SDimitry Andric llvm::BasicBlock *InvokeDest = CannotThrow ? nullptr : getInvokeDest();
56610b57cec5SDimitry Andric
56620b57cec5SDimitry Andric SmallVector<llvm::OperandBundleDef, 1> BundleList =
56630b57cec5SDimitry Andric getBundlesForFunclet(CalleePtr);
56640b57cec5SDimitry Andric
5665bdd1243dSDimitry Andric if (SanOpts.has(SanitizerKind::KCFI) &&
5666bdd1243dSDimitry Andric !isa_and_nonnull<FunctionDecl>(TargetDecl))
5667bdd1243dSDimitry Andric EmitKCFIOperandBundle(ConcreteCallee, BundleList);
5668bdd1243dSDimitry Andric
56690fca6ea1SDimitry Andric // Add the pointer-authentication bundle.
56700fca6ea1SDimitry Andric EmitPointerAuthOperandBundle(ConcreteCallee.getPointerAuthInfo(), BundleList);
56710fca6ea1SDimitry Andric
5672480093f4SDimitry Andric if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl))
5673e8d8bef9SDimitry Andric if (FD->hasAttr<StrictFPAttr>())
5674480093f4SDimitry Andric // All calls within a strictfp function are marked strictfp
5675349cc55cSDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP);
5676480093f4SDimitry Andric
56775ffd83dbSDimitry Andric AssumeAlignedAttrEmitter AssumeAlignedAttrEmitter(*this, TargetDecl);
56785ffd83dbSDimitry Andric Attrs = AssumeAlignedAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
56795ffd83dbSDimitry Andric
56805ffd83dbSDimitry Andric AllocAlignAttrEmitter AllocAlignAttrEmitter(*this, TargetDecl, CallArgs);
56815ffd83dbSDimitry Andric Attrs = AllocAlignAttrEmitter.TryEmitAsCallSiteAttribute(Attrs);
56825ffd83dbSDimitry Andric
56830b57cec5SDimitry Andric // Emit the actual call/invoke instruction.
56840b57cec5SDimitry Andric llvm::CallBase *CI;
56850b57cec5SDimitry Andric if (!InvokeDest) {
56860b57cec5SDimitry Andric CI = Builder.CreateCall(IRFuncTy, CalleePtr, IRCallArgs, BundleList);
56870b57cec5SDimitry Andric } else {
56880b57cec5SDimitry Andric llvm::BasicBlock *Cont = createBasicBlock("invoke.cont");
56890b57cec5SDimitry Andric CI = Builder.CreateInvoke(IRFuncTy, CalleePtr, Cont, InvokeDest, IRCallArgs,
56900b57cec5SDimitry Andric BundleList);
56910b57cec5SDimitry Andric EmitBlock(Cont);
56920b57cec5SDimitry Andric }
56935f757f3fSDimitry Andric if (CI->getCalledFunction() && CI->getCalledFunction()->hasName() &&
56945f757f3fSDimitry Andric CI->getCalledFunction()->getName().starts_with("_Z4sqrt")) {
56955f757f3fSDimitry Andric SetSqrtFPAccuracy(CI);
56965f757f3fSDimitry Andric }
56970b57cec5SDimitry Andric if (callOrInvoke)
56980b57cec5SDimitry Andric *callOrInvoke = CI;
56990b57cec5SDimitry Andric
5700480093f4SDimitry Andric // If this is within a function that has the guard(nocf) attribute and is an
5701480093f4SDimitry Andric // indirect call, add the "guard_nocf" attribute to this call to indicate that
5702480093f4SDimitry Andric // Control Flow Guard checks should not be added, even if the call is inlined.
5703480093f4SDimitry Andric if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
5704480093f4SDimitry Andric if (const auto *A = FD->getAttr<CFGuardAttr>()) {
5705480093f4SDimitry Andric if (A->getGuard() == CFGuardAttr::GuardArg::nocf && !CI->getCalledFunction())
5706349cc55cSDimitry Andric Attrs = Attrs.addFnAttribute(getLLVMContext(), "guard_nocf");
5707480093f4SDimitry Andric }
5708480093f4SDimitry Andric }
5709480093f4SDimitry Andric
57100b57cec5SDimitry Andric // Apply the attributes and calling convention.
57110b57cec5SDimitry Andric CI->setAttributes(Attrs);
57120b57cec5SDimitry Andric CI->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
57130b57cec5SDimitry Andric
57140b57cec5SDimitry Andric // Apply various metadata.
57150b57cec5SDimitry Andric
57160b57cec5SDimitry Andric if (!CI->getType()->isVoidTy())
57170b57cec5SDimitry Andric CI->setName("call");
57180b57cec5SDimitry Andric
57190fca6ea1SDimitry Andric if (CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
57200fca6ea1SDimitry Andric CI = addControlledConvergenceToken(CI);
57210fca6ea1SDimitry Andric
57220b57cec5SDimitry Andric // Update largest vector width from the return type.
57235ffd83dbSDimitry Andric LargestVectorWidth =
572481ad6265SDimitry Andric std::max(LargestVectorWidth, getMaxVectorWidth(CI->getType()));
57250b57cec5SDimitry Andric
57260b57cec5SDimitry Andric // Insert instrumentation or attach profile metadata at indirect call sites.
57270b57cec5SDimitry Andric // For more details, see the comment before the definition of
57280b57cec5SDimitry Andric // IPVK_IndirectCallTarget in InstrProfData.inc.
57290b57cec5SDimitry Andric if (!CI->getCalledFunction())
57300b57cec5SDimitry Andric PGO.valueProfile(Builder, llvm::IPVK_IndirectCallTarget,
57310b57cec5SDimitry Andric CI, CalleePtr);
57320b57cec5SDimitry Andric
57330b57cec5SDimitry Andric // In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
57340b57cec5SDimitry Andric // optimizer it can aggressively ignore unwind edges.
57350b57cec5SDimitry Andric if (CGM.getLangOpts().ObjCAutoRefCount)
57360b57cec5SDimitry Andric AddObjCARCExceptionMetadata(CI);
57370b57cec5SDimitry Andric
5738fe6060f1SDimitry Andric // Set tail call kind if necessary.
57390b57cec5SDimitry Andric if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
57400b57cec5SDimitry Andric if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
57410b57cec5SDimitry Andric Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
57420fca6ea1SDimitry Andric else if (IsMustTail) {
57430fca6ea1SDimitry Andric if (getTarget().getTriple().isPPC()) {
57440fca6ea1SDimitry Andric if (getTarget().getTriple().isOSAIX())
57450fca6ea1SDimitry Andric CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
57460fca6ea1SDimitry Andric else if (!getTarget().hasFeature("pcrelative-memops")) {
57470fca6ea1SDimitry Andric if (getTarget().hasFeature("longcall"))
57480fca6ea1SDimitry Andric CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
57490fca6ea1SDimitry Andric else if (Call->isIndirectCall())
57500fca6ea1SDimitry Andric CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
57510fca6ea1SDimitry Andric else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
57520fca6ea1SDimitry Andric if (!cast<FunctionDecl>(TargetDecl)->isDefined())
57530fca6ea1SDimitry Andric // The undefined callee may be a forward declaration. Without
57540fca6ea1SDimitry Andric // knowning all symbols in the module, we won't know the symbol is
57550fca6ea1SDimitry Andric // defined or not. Collect all these symbols for later diagnosing.
57560fca6ea1SDimitry Andric CGM.addUndefinedGlobalForTailCall(
57570fca6ea1SDimitry Andric {cast<FunctionDecl>(TargetDecl), Loc});
57580fca6ea1SDimitry Andric else {
57590fca6ea1SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(
57600fca6ea1SDimitry Andric GlobalDecl(cast<FunctionDecl>(TargetDecl)));
57610fca6ea1SDimitry Andric if (llvm::GlobalValue::isWeakForLinker(Linkage) ||
57620fca6ea1SDimitry Andric llvm::GlobalValue::isDiscardableIfUnused(Linkage))
57630fca6ea1SDimitry Andric CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
57640fca6ea1SDimitry Andric << 2;
57650fca6ea1SDimitry Andric }
57660fca6ea1SDimitry Andric }
57670fca6ea1SDimitry Andric }
57680fca6ea1SDimitry Andric }
5769fe6060f1SDimitry Andric Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
57700b57cec5SDimitry Andric }
57710fca6ea1SDimitry Andric }
57720b57cec5SDimitry Andric
57730b57cec5SDimitry Andric // Add metadata for calls to MSAllocator functions
57740b57cec5SDimitry Andric if (getDebugInfo() && TargetDecl &&
57750b57cec5SDimitry Andric TargetDecl->hasAttr<MSAllocatorAttr>())
57765ffd83dbSDimitry Andric getDebugInfo()->addHeapAllocSiteMetadata(CI, RetTy->getPointeeType(), Loc);
57770b57cec5SDimitry Andric
5778349cc55cSDimitry Andric // Add metadata if calling an __attribute__((error(""))) or warning fn.
5779349cc55cSDimitry Andric if (TargetDecl && TargetDecl->hasAttr<ErrorAttr>()) {
5780349cc55cSDimitry Andric llvm::ConstantInt *Line =
57810fca6ea1SDimitry Andric llvm::ConstantInt::get(Int64Ty, Loc.getRawEncoding());
5782349cc55cSDimitry Andric llvm::ConstantAsMetadata *MD = llvm::ConstantAsMetadata::get(Line);
5783349cc55cSDimitry Andric llvm::MDTuple *MDT = llvm::MDNode::get(getLLVMContext(), {MD});
5784349cc55cSDimitry Andric CI->setMetadata("srcloc", MDT);
5785349cc55cSDimitry Andric }
5786349cc55cSDimitry Andric
57870b57cec5SDimitry Andric // 4. Finish the call.
57880b57cec5SDimitry Andric
57890b57cec5SDimitry Andric // If the call doesn't return, finish the basic block and clear the
57900b57cec5SDimitry Andric // insertion point; this allows the rest of IRGen to discard
57910b57cec5SDimitry Andric // unreachable code.
57920b57cec5SDimitry Andric if (CI->doesNotReturn()) {
57930b57cec5SDimitry Andric if (UnusedReturnSizePtr)
57940b57cec5SDimitry Andric PopCleanupBlock();
57950b57cec5SDimitry Andric
57960b57cec5SDimitry Andric // Strip away the noreturn attribute to better diagnose unreachable UB.
57970b57cec5SDimitry Andric if (SanOpts.has(SanitizerKind::Unreachable)) {
57980b57cec5SDimitry Andric // Also remove from function since CallBase::hasFnAttr additionally checks
57990b57cec5SDimitry Andric // attributes of the called function.
58000b57cec5SDimitry Andric if (auto *F = CI->getCalledFunction())
58010b57cec5SDimitry Andric F->removeFnAttr(llvm::Attribute::NoReturn);
5802349cc55cSDimitry Andric CI->removeFnAttr(llvm::Attribute::NoReturn);
58030b57cec5SDimitry Andric
58040b57cec5SDimitry Andric // Avoid incompatibility with ASan which relies on the `noreturn`
58050b57cec5SDimitry Andric // attribute to insert handler calls.
58060b57cec5SDimitry Andric if (SanOpts.hasOneOf(SanitizerKind::Address |
58070b57cec5SDimitry Andric SanitizerKind::KernelAddress)) {
58080b57cec5SDimitry Andric SanitizerScope SanScope(this);
58090b57cec5SDimitry Andric llvm::IRBuilder<>::InsertPointGuard IPGuard(Builder);
58100b57cec5SDimitry Andric Builder.SetInsertPoint(CI);
58110b57cec5SDimitry Andric auto *FnType = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
58120b57cec5SDimitry Andric llvm::FunctionCallee Fn =
58130b57cec5SDimitry Andric CGM.CreateRuntimeFunction(FnType, "__asan_handle_no_return");
58140b57cec5SDimitry Andric EmitNounwindRuntimeCall(Fn);
58150b57cec5SDimitry Andric }
58160b57cec5SDimitry Andric }
58170b57cec5SDimitry Andric
58180b57cec5SDimitry Andric EmitUnreachable(Loc);
58190b57cec5SDimitry Andric Builder.ClearInsertionPoint();
58200b57cec5SDimitry Andric
58210b57cec5SDimitry Andric // FIXME: For now, emit a dummy basic block because expr emitters in
58220b57cec5SDimitry Andric // generally are not ready to handle emitting expressions at unreachable
58230b57cec5SDimitry Andric // points.
58240b57cec5SDimitry Andric EnsureInsertPoint();
58250b57cec5SDimitry Andric
58260b57cec5SDimitry Andric // Return a reasonable RValue.
58270b57cec5SDimitry Andric return GetUndefRValue(RetTy);
58280b57cec5SDimitry Andric }
58290b57cec5SDimitry Andric
5830fe6060f1SDimitry Andric // If this is a musttail call, return immediately. We do not branch to the
5831fe6060f1SDimitry Andric // epilogue in this case.
5832fe6060f1SDimitry Andric if (IsMustTail) {
5833fe6060f1SDimitry Andric for (auto it = EHStack.find(CurrentCleanupScopeDepth); it != EHStack.end();
5834fe6060f1SDimitry Andric ++it) {
5835fe6060f1SDimitry Andric EHCleanupScope *Cleanup = dyn_cast<EHCleanupScope>(&*it);
5836fe6060f1SDimitry Andric if (!(Cleanup && Cleanup->getCleanup()->isRedundantBeforeReturn()))
5837fe6060f1SDimitry Andric CGM.ErrorUnsupported(MustTailCall, "tail call skipping over cleanups");
5838fe6060f1SDimitry Andric }
5839fe6060f1SDimitry Andric if (CI->getType()->isVoidTy())
5840fe6060f1SDimitry Andric Builder.CreateRetVoid();
5841fe6060f1SDimitry Andric else
5842fe6060f1SDimitry Andric Builder.CreateRet(CI);
5843fe6060f1SDimitry Andric Builder.ClearInsertionPoint();
5844fe6060f1SDimitry Andric EnsureInsertPoint();
5845fe6060f1SDimitry Andric return GetUndefRValue(RetTy);
5846fe6060f1SDimitry Andric }
5847fe6060f1SDimitry Andric
58480b57cec5SDimitry Andric // Perform the swifterror writeback.
58490b57cec5SDimitry Andric if (swiftErrorTemp.isValid()) {
58500b57cec5SDimitry Andric llvm::Value *errorResult = Builder.CreateLoad(swiftErrorTemp);
58510b57cec5SDimitry Andric Builder.CreateStore(errorResult, swiftErrorArg);
58520b57cec5SDimitry Andric }
58530b57cec5SDimitry Andric
58540b57cec5SDimitry Andric // Emit any call-associated writebacks immediately. Arguably this
58550b57cec5SDimitry Andric // should happen after any return-value munging.
58560b57cec5SDimitry Andric if (CallArgs.hasWritebacks())
58570b57cec5SDimitry Andric emitWritebacks(*this, CallArgs);
58580b57cec5SDimitry Andric
58590b57cec5SDimitry Andric // The stack cleanup for inalloca arguments has to run out of the normal
58600b57cec5SDimitry Andric // lexical order, so deactivate it and run it manually here.
58610b57cec5SDimitry Andric CallArgs.freeArgumentMemory(*this);
58620b57cec5SDimitry Andric
58630b57cec5SDimitry Andric // Extract the return value.
58640fca6ea1SDimitry Andric RValue Ret;
58650fca6ea1SDimitry Andric
58660fca6ea1SDimitry Andric // If the current function is a virtual function pointer thunk, avoid copying
58670fca6ea1SDimitry Andric // the return value of the musttail call to a temporary.
58680fca6ea1SDimitry Andric if (IsVirtualFunctionPointerThunk) {
58690fca6ea1SDimitry Andric Ret = RValue::get(CI);
58700fca6ea1SDimitry Andric } else {
58710fca6ea1SDimitry Andric Ret = [&] {
58720b57cec5SDimitry Andric switch (RetAI.getKind()) {
58730b57cec5SDimitry Andric case ABIArgInfo::CoerceAndExpand: {
58740b57cec5SDimitry Andric auto coercionType = RetAI.getCoerceAndExpandType();
58750b57cec5SDimitry Andric
587606c3fb27SDimitry Andric Address addr = SRetPtr.withElementType(coercionType);
58770b57cec5SDimitry Andric
58780b57cec5SDimitry Andric assert(CI->getType() == RetAI.getUnpaddedCoerceAndExpandType());
58790b57cec5SDimitry Andric bool requiresExtract = isa<llvm::StructType>(CI->getType());
58800b57cec5SDimitry Andric
58810b57cec5SDimitry Andric unsigned unpaddedIndex = 0;
58820b57cec5SDimitry Andric for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
58830b57cec5SDimitry Andric llvm::Type *eltType = coercionType->getElementType(i);
58840fca6ea1SDimitry Andric if (ABIArgInfo::isPaddingForCoerceAndExpand(eltType))
58850fca6ea1SDimitry Andric continue;
58860b57cec5SDimitry Andric Address eltAddr = Builder.CreateStructGEP(addr, i);
58870b57cec5SDimitry Andric llvm::Value *elt = CI;
58880b57cec5SDimitry Andric if (requiresExtract)
58890b57cec5SDimitry Andric elt = Builder.CreateExtractValue(elt, unpaddedIndex++);
58900b57cec5SDimitry Andric else
58910b57cec5SDimitry Andric assert(unpaddedIndex == 0);
58920b57cec5SDimitry Andric Builder.CreateStore(elt, eltAddr);
58930b57cec5SDimitry Andric }
5894bdd1243dSDimitry Andric [[fallthrough]];
58950b57cec5SDimitry Andric }
58960b57cec5SDimitry Andric
58970b57cec5SDimitry Andric case ABIArgInfo::InAlloca:
58980b57cec5SDimitry Andric case ABIArgInfo::Indirect: {
58990b57cec5SDimitry Andric RValue ret = convertTempToRValue(SRetPtr, RetTy, SourceLocation());
59000b57cec5SDimitry Andric if (UnusedReturnSizePtr)
59010b57cec5SDimitry Andric PopCleanupBlock();
59020b57cec5SDimitry Andric return ret;
59030b57cec5SDimitry Andric }
59040b57cec5SDimitry Andric
59050b57cec5SDimitry Andric case ABIArgInfo::Ignore:
59060b57cec5SDimitry Andric // If we are ignoring an argument that had a result, make sure to
59070b57cec5SDimitry Andric // construct the appropriate return value for our caller.
59080b57cec5SDimitry Andric return GetUndefRValue(RetTy);
59090b57cec5SDimitry Andric
59100b57cec5SDimitry Andric case ABIArgInfo::Extend:
59110b57cec5SDimitry Andric case ABIArgInfo::Direct: {
59120b57cec5SDimitry Andric llvm::Type *RetIRTy = ConvertType(RetTy);
59130fca6ea1SDimitry Andric if (RetAI.getCoerceToType() == RetIRTy &&
59140fca6ea1SDimitry Andric RetAI.getDirectOffset() == 0) {
59150b57cec5SDimitry Andric switch (getEvaluationKind(RetTy)) {
59160b57cec5SDimitry Andric case TEK_Complex: {
59170b57cec5SDimitry Andric llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
59180b57cec5SDimitry Andric llvm::Value *Imag = Builder.CreateExtractValue(CI, 1);
59190b57cec5SDimitry Andric return RValue::getComplex(std::make_pair(Real, Imag));
59200b57cec5SDimitry Andric }
5921c80e69b0SDimitry Andric case TEK_Aggregate:
5922c80e69b0SDimitry Andric break;
59230b57cec5SDimitry Andric case TEK_Scalar: {
59240fca6ea1SDimitry Andric // If the argument doesn't match, perform a bitcast to coerce it.
59250fca6ea1SDimitry Andric // This can happen due to trivial type mismatches.
59260b57cec5SDimitry Andric llvm::Value *V = CI;
59270b57cec5SDimitry Andric if (V->getType() != RetIRTy)
59280b57cec5SDimitry Andric V = Builder.CreateBitCast(V, RetIRTy);
59290b57cec5SDimitry Andric return RValue::get(V);
59300b57cec5SDimitry Andric }
59310b57cec5SDimitry Andric }
59320b57cec5SDimitry Andric }
59330b57cec5SDimitry Andric
593406c3fb27SDimitry Andric // If coercing a fixed vector from a scalable vector for ABI
593506c3fb27SDimitry Andric // compatibility, and the types match, use the llvm.vector.extract
593606c3fb27SDimitry Andric // intrinsic to perform the conversion.
59370fca6ea1SDimitry Andric if (auto *FixedDstTy = dyn_cast<llvm::FixedVectorType>(RetIRTy)) {
593806c3fb27SDimitry Andric llvm::Value *V = CI;
59390fca6ea1SDimitry Andric if (auto *ScalableSrcTy =
59400fca6ea1SDimitry Andric dyn_cast<llvm::ScalableVectorType>(V->getType())) {
59410fca6ea1SDimitry Andric if (FixedDstTy->getElementType() ==
59420fca6ea1SDimitry Andric ScalableSrcTy->getElementType()) {
594306c3fb27SDimitry Andric llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int64Ty);
59440fca6ea1SDimitry Andric V = Builder.CreateExtractVector(FixedDstTy, V, Zero,
59450fca6ea1SDimitry Andric "cast.fixed");
594606c3fb27SDimitry Andric return RValue::get(V);
594706c3fb27SDimitry Andric }
594806c3fb27SDimitry Andric }
594906c3fb27SDimitry Andric }
595006c3fb27SDimitry Andric
59510b57cec5SDimitry Andric Address DestPtr = ReturnValue.getValue();
59520b57cec5SDimitry Andric bool DestIsVolatile = ReturnValue.isVolatile();
5953c80e69b0SDimitry Andric uint64_t DestSize =
5954c80e69b0SDimitry Andric getContext().getTypeInfoDataSizeInChars(RetTy).Width.getQuantity();
59550b57cec5SDimitry Andric
59560b57cec5SDimitry Andric if (!DestPtr.isValid()) {
59570b57cec5SDimitry Andric DestPtr = CreateMemTemp(RetTy, "coerce");
59580b57cec5SDimitry Andric DestIsVolatile = false;
5959c80e69b0SDimitry Andric DestSize = getContext().getTypeSizeInChars(RetTy).getQuantity();
59600b57cec5SDimitry Andric }
59610b57cec5SDimitry Andric
59628a4dda33SDimitry Andric // An empty record can overlap other data (if declared with
59638a4dda33SDimitry Andric // no_unique_address); omit the store for such types - as there is no
59648a4dda33SDimitry Andric // actual data to store.
59658a4dda33SDimitry Andric if (!isEmptyRecord(getContext(), RetTy, true)) {
59660b57cec5SDimitry Andric // If the value is offset in memory, apply the offset now.
59670b57cec5SDimitry Andric Address StorePtr = emitAddressAtOffset(*this, DestPtr, RetAI);
5968c80e69b0SDimitry Andric CreateCoercedStore(
5969c80e69b0SDimitry Andric CI, StorePtr,
5970c80e69b0SDimitry Andric llvm::TypeSize::getFixed(DestSize - RetAI.getDirectOffset()),
5971c80e69b0SDimitry Andric DestIsVolatile);
59728a4dda33SDimitry Andric }
59730b57cec5SDimitry Andric
59740b57cec5SDimitry Andric return convertTempToRValue(DestPtr, RetTy, SourceLocation());
59750b57cec5SDimitry Andric }
59760b57cec5SDimitry Andric
59770b57cec5SDimitry Andric case ABIArgInfo::Expand:
5978e8d8bef9SDimitry Andric case ABIArgInfo::IndirectAliased:
59790b57cec5SDimitry Andric llvm_unreachable("Invalid ABI kind for return argument");
59800b57cec5SDimitry Andric }
59810b57cec5SDimitry Andric
59820b57cec5SDimitry Andric llvm_unreachable("Unhandled ABIArgInfo::Kind");
59830b57cec5SDimitry Andric }();
59840fca6ea1SDimitry Andric }
59850b57cec5SDimitry Andric
59860b57cec5SDimitry Andric // Emit the assume_aligned check on the return value.
59870b57cec5SDimitry Andric if (Ret.isScalar() && TargetDecl) {
59885ffd83dbSDimitry Andric AssumeAlignedAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
59895ffd83dbSDimitry Andric AllocAlignAttrEmitter.EmitAsAnAssumption(Loc, RetTy, Ret);
59900b57cec5SDimitry Andric }
59910b57cec5SDimitry Andric
5992a7dea167SDimitry Andric // Explicitly call CallLifetimeEnd::Emit just to re-use the code even though
5993a7dea167SDimitry Andric // we can't use the full cleanup mechanism.
5994a7dea167SDimitry Andric for (CallLifetimeEnd &LifetimeEnd : CallLifetimeEndAfterCall)
5995a7dea167SDimitry Andric LifetimeEnd.Emit(*this, /*Flags=*/{});
5996a7dea167SDimitry Andric
59975ffd83dbSDimitry Andric if (!ReturnValue.isExternallyDestructed() &&
59985ffd83dbSDimitry Andric RetTy.isDestructedType() == QualType::DK_nontrivial_c_struct)
59995ffd83dbSDimitry Andric pushDestroy(QualType::DK_nontrivial_c_struct, Ret.getAggregateAddress(),
60005ffd83dbSDimitry Andric RetTy);
60015ffd83dbSDimitry Andric
60020b57cec5SDimitry Andric return Ret;
60030b57cec5SDimitry Andric }
60040b57cec5SDimitry Andric
prepareConcreteCallee(CodeGenFunction & CGF) const60050b57cec5SDimitry Andric CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const {
60060b57cec5SDimitry Andric if (isVirtual()) {
60070b57cec5SDimitry Andric const CallExpr *CE = getVirtualCallExpr();
60080b57cec5SDimitry Andric return CGF.CGM.getCXXABI().getVirtualFunctionPointer(
60090b57cec5SDimitry Andric CGF, getVirtualMethodDecl(), getThisAddress(), getVirtualFunctionType(),
60100b57cec5SDimitry Andric CE ? CE->getBeginLoc() : SourceLocation());
60110b57cec5SDimitry Andric }
60120b57cec5SDimitry Andric
60130b57cec5SDimitry Andric return *this;
60140b57cec5SDimitry Andric }
60150b57cec5SDimitry Andric
60160b57cec5SDimitry Andric /* VarArg handling */
60170b57cec5SDimitry Andric
EmitVAArg(VAArgExpr * VE,Address & VAListAddr,AggValueSlot Slot)60180fca6ea1SDimitry Andric RValue CodeGenFunction::EmitVAArg(VAArgExpr *VE, Address &VAListAddr,
60190fca6ea1SDimitry Andric AggValueSlot Slot) {
60200fca6ea1SDimitry Andric VAListAddr = VE->isMicrosoftABI() ? EmitMSVAListRef(VE->getSubExpr())
60210b57cec5SDimitry Andric : EmitVAListRef(VE->getSubExpr());
60220b57cec5SDimitry Andric QualType Ty = VE->getType();
60230b57cec5SDimitry Andric if (VE->isMicrosoftABI())
6024*5deeebd8SDimitry Andric return CGM.getABIInfo().EmitMSVAArg(*this, VAListAddr, Ty, Slot);
6025*5deeebd8SDimitry Andric return CGM.getABIInfo().EmitVAArg(*this, VAListAddr, Ty, Slot);
60260b57cec5SDimitry Andric }
6027