diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp | 608 |
1 files changed, 326 insertions, 282 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp index a061651d8b21..bcd24292ff41 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp @@ -80,17 +80,17 @@ static bool isAggregateTypeForABI(QualType T) { T->isMemberFunctionPointerType(); } -ABIArgInfo -ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByRef, bool Realign, - llvm::Type *Padding) const { - return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), - ByRef, Realign, Padding); +ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal, + bool Realign, + llvm::Type *Padding) const { + return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal, + Realign, Padding); } ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty, bool Realign) const { return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty), - /*ByRef*/ false, Realign); + /*ByVal*/ false, Realign); } Address ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, @@ -257,6 +257,11 @@ LLVM_DUMP_METHOD void ABIArgInfo::dump() const { << " ByVal=" << getIndirectByVal() << " Realign=" << getIndirectRealign(); break; + case IndirectAliased: + OS << "Indirect Align=" << getIndirectAlign().getQuantity() + << " AadrSpace=" << getIndirectAddrSpace() + << " Realign=" << getIndirectRealign(); + break; case Expand: OS << "Expand"; break; @@ -354,7 +359,7 @@ static Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, /// leaving one or more empty slots behind as padding. static Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, - std::pair<CharUnits, CharUnits> ValueInfo, + TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign) { // The size and alignment of the value that was passed directly. @@ -363,8 +368,8 @@ static Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, DirectSize = CGF.getPointerSize(); DirectAlign = CGF.getPointerAlign(); } else { - DirectSize = ValueInfo.first; - DirectAlign = ValueInfo.second; + DirectSize = ValueInfo.Width; + DirectAlign = ValueInfo.Align; } // Cast the address we've calculated to the right type. @@ -378,7 +383,7 @@ static Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, AllowHigherAlign); if (IsIndirect) { - Addr = Address(CGF.Builder.CreateLoad(Addr), ValueInfo.second); + Addr = Address(CGF.Builder.CreateLoad(Addr), ValueInfo.Align); } return Addr; @@ -651,7 +656,7 @@ Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!"); auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty); - CharUnits TyAlignForABI = TyInfo.second; + CharUnits TyAlignForABI = TyInfo.Align; llvm::Type *BaseTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty)); @@ -1084,11 +1089,6 @@ struct CCState { unsigned FreeSSERegs = 0; }; -enum { - // Vectorcall only allows the first 6 parameters to be passed in registers. - VectorcallMaxParamNumAsReg = 6 -}; - /// X86_32ABIInfo - The X86-32 ABI information. class X86_32ABIInfo : public SwiftABIInfo { enum Class { @@ -1989,6 +1989,7 @@ static bool isArgInAlloca(const ABIArgInfo &Info) { case ABIArgInfo::InAlloca: return true; case ABIArgInfo::Ignore: + case ABIArgInfo::IndirectAliased: return false; case ABIArgInfo::Indirect: case ABIArgInfo::Direct: @@ -2056,8 +2057,8 @@ Address X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, // // Just messing with TypeInfo like this works because we never pass // anything indirectly. - TypeInfo.second = CharUnits::fromQuantity( - getTypeStackAlignInBytes(Ty, TypeInfo.second.getQuantity())); + TypeInfo.Align = CharUnits::fromQuantity( + getTypeStackAlignInBytes(Ty, TypeInfo.Align.getQuantity())); return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo, CharUnits::fromQuantity(4), @@ -2091,6 +2092,23 @@ bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( } } +static void addX86InterruptAttrs(const FunctionDecl *FD, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) { + if (!FD->hasAttr<AnyX86InterruptAttr>()) + return; + + llvm::Function *Fn = cast<llvm::Function>(GV); + Fn->setCallingConv(llvm::CallingConv::X86_INTR); + if (FD->getNumParams() == 0) + return; + + auto PtrTy = cast<PointerType>(FD->getParamDecl(0)->getType()); + llvm::Type *ByValTy = CGM.getTypes().ConvertType(PtrTy->getPointeeType()); + llvm::Attribute NewAttr = llvm::Attribute::getWithByValType( + Fn->getContext(), ByValTy); + Fn->addParamAttr(0, NewAttr); +} + void X86_32TargetCodeGenInfo::setTargetAttributes( const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { if (GV->isDeclaration()) @@ -2100,10 +2118,8 @@ void X86_32TargetCodeGenInfo::setTargetAttributes( llvm::Function *Fn = cast<llvm::Function>(GV); Fn->addFnAttr("stackrealign"); } - if (FD->hasAttr<AnyX86InterruptAttr>()) { - llvm::Function *Fn = cast<llvm::Function>(GV); - Fn->setCallingConv(llvm::CallingConv::X86_INTR); - } + + addX86InterruptAttrs(FD, GV, CGM); } } @@ -2384,10 +2400,8 @@ public: private: ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs, bool IsReturnType, bool IsVectorCall, bool IsRegCall) const; - ABIArgInfo reclassifyHvaArgType(QualType Ty, unsigned &FreeSSERegs, - const ABIArgInfo ¤t) const; - void computeVectorCallArgs(CGFunctionInfo &FI, unsigned FreeSSERegs, - bool IsVectorCall, bool IsRegCall) const; + ABIArgInfo reclassifyHvaArgForVectorCall(QualType Ty, unsigned &FreeSSERegs, + const ABIArgInfo ¤t) const; X86AVXABILevel AVXLevel; @@ -2404,10 +2418,8 @@ public: } /// Disable tail call on x86-64. The epilogue code before the tail jump blocks - /// the autoreleaseRV/retainRV optimization. - bool shouldSuppressTailCallsOfRetainAutoreleasedReturnValue() const override { - return true; - } + /// autoreleaseRV/retainRV and autoreleaseRV/unsafeClaimRV optimizations. + bool markARCOptimizedReturnCallsAsNoTail() const override { return true; } int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { return 7; @@ -2472,10 +2484,8 @@ public: llvm::Function *Fn = cast<llvm::Function>(GV); Fn->addFnAttr("stackrealign"); } - if (FD->hasAttr<AnyX86InterruptAttr>()) { - llvm::Function *Fn = cast<llvm::Function>(GV); - Fn->setCallingConv(llvm::CallingConv::X86_INTR); - } + + addX86InterruptAttrs(FD, GV, CGM); } } @@ -2586,7 +2596,7 @@ static std::string qualifyWindowsLibrary(llvm::StringRef Lib) { // If the argument does not end in .lib, automatically add the suffix. // If the argument contains a space, enclose it in quotes. // This matches the behavior of MSVC. - bool Quote = (Lib.find(" ") != StringRef::npos); + bool Quote = (Lib.find(' ') != StringRef::npos); std::string ArgStr = Quote ? "\"" : ""; ArgStr += Lib; if (!Lib.endswith_lower(".lib") && !Lib.endswith_lower(".a")) @@ -2685,10 +2695,8 @@ void WinX86_64TargetCodeGenInfo::setTargetAttributes( llvm::Function *Fn = cast<llvm::Function>(GV); Fn->addFnAttr("stackrealign"); } - if (FD->hasAttr<AnyX86InterruptAttr>()) { - llvm::Function *Fn = cast<llvm::Function>(GV); - Fn->setCallingConv(llvm::CallingConv::X86_INTR); - } + + addX86InterruptAttrs(FD, GV, CGM); } addStackProbeTargetAttributes(D, GV, CGM); @@ -3057,6 +3065,11 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, // Classify the fields one at a time, merging the results. unsigned idx = 0; + bool UseClang11Compat = getContext().getLangOpts().getClangABICompat() <= + LangOptions::ClangABI::Ver11 || + getContext().getTargetInfo().getTriple().isPS4(); + bool IsUnion = RT->isUnionType() && !UseClang11Compat; + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i, ++idx) { uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); @@ -3067,14 +3080,17 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, continue; // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger than - // four eightbytes, or it contains unaligned fields, it has class MEMORY. + // eight eightbytes, or it contains unaligned fields, it has class MEMORY. // - // The only case a 256-bit wide vector could be used is when the struct - // contains a single 256-bit element. Since Lo and Hi logic isn't extended - // to work for sizes wider than 128, early check and fallback to memory. + // The only case a 256-bit or a 512-bit wide vector could be used is when + // the struct contains a single 256-bit or 512-bit element. Early check + // and fallback to memory. // - if (Size > 128 && (Size != getContext().getTypeSize(i->getType()) || - Size > getNativeVectorSizeForAVXABI(AVXLevel))) { + // FIXME: Extended the Lo and Hi logic properly to work for size wider + // than 128. + if (Size > 128 && + ((!IsUnion && Size != getContext().getTypeSize(i->getType())) || + Size > getNativeVectorSizeForAVXABI(AVXLevel))) { Lo = Memory; postMerge(Size, Lo, Hi); return; @@ -4059,10 +4075,9 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, RegAddr = CGF.Builder.CreateElementBitCast(RegAddr, LTy); // Copy to a temporary if necessary to ensure the appropriate alignment. - std::pair<CharUnits, CharUnits> SizeAlign = - getContext().getTypeInfoInChars(Ty); - uint64_t TySize = SizeAlign.first.getQuantity(); - CharUnits TyAlign = SizeAlign.second; + auto TInfo = getContext().getTypeInfoInChars(Ty); + uint64_t TySize = TInfo.Width.getQuantity(); + CharUnits TyAlign = TInfo.Align; // Copy into a temporary if the type is more aligned than the // register save area. @@ -4141,10 +4156,8 @@ Address X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } -ABIArgInfo -WinX86_64ABIInfo::reclassifyHvaArgType(QualType Ty, unsigned &FreeSSERegs, - const ABIArgInfo ¤t) const { - // Assumes vectorCall calling convention. +ABIArgInfo WinX86_64ABIInfo::reclassifyHvaArgForVectorCall( + QualType Ty, unsigned &FreeSSERegs, const ABIArgInfo ¤t) const { const Type *Base = nullptr; uint64_t NumElts = 0; @@ -4277,31 +4290,6 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs, return ABIArgInfo::getDirect(); } -void WinX86_64ABIInfo::computeVectorCallArgs(CGFunctionInfo &FI, - unsigned FreeSSERegs, - bool IsVectorCall, - bool IsRegCall) const { - unsigned Count = 0; - for (auto &I : FI.arguments()) { - // Vectorcall in x64 only permits the first 6 arguments to be passed - // as XMM/YMM registers. - if (Count < VectorcallMaxParamNumAsReg) - I.info = classify(I.type, FreeSSERegs, false, IsVectorCall, IsRegCall); - else { - // Since these cannot be passed in registers, pretend no registers - // are left. - unsigned ZeroSSERegsAvail = 0; - I.info = classify(I.type, /*FreeSSERegs=*/ZeroSSERegsAvail, false, - IsVectorCall, IsRegCall); - } - ++Count; - } - - for (auto &I : FI.arguments()) { - I.info = reclassifyHvaArgType(I.type, FreeSSERegs, I.info); - } -} - void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { const unsigned CC = FI.getCallingConvention(); bool IsVectorCall = CC == llvm::CallingConv::X86_VectorCall; @@ -4336,13 +4324,25 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { FreeSSERegs = 16; } + unsigned ArgNum = 0; + unsigned ZeroSSERegs = 0; + for (auto &I : FI.arguments()) { + // Vectorcall in x64 only permits the first 6 arguments to be passed as + // XMM/YMM registers. After the sixth argument, pretend no vector + // registers are left. + unsigned *MaybeFreeSSERegs = + (IsVectorCall && ArgNum >= 6) ? &ZeroSSERegs : &FreeSSERegs; + I.info = + classify(I.type, *MaybeFreeSSERegs, false, IsVectorCall, IsRegCall); + ++ArgNum; + } + if (IsVectorCall) { - computeVectorCallArgs(FI, FreeSSERegs, IsVectorCall, IsRegCall); - } else { + // For vectorcall, assign aggregate HVAs to any free vector registers in a + // second pass. for (auto &I : FI.arguments()) - I.info = classify(I.type, FreeSSERegs, false, IsVectorCall, IsRegCall); + I.info = reclassifyHvaArgForVectorCall(I.type, FreeSSERegs, I.info); } - } Address WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, @@ -4500,16 +4500,14 @@ bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const { ABIArgInfo AIXABIInfo::classifyReturnType(QualType RetTy) const { if (RetTy->isAnyComplexType()) - llvm::report_fatal_error("complex type is not supported on AIX yet"); + return ABIArgInfo::getDirect(); if (RetTy->isVectorType()) - llvm::report_fatal_error("vector type is not supported on AIX yet"); + return ABIArgInfo::getDirect(); if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); - // TODO: Evaluate if AIX power alignment rule would have an impact on the - // alignment here. if (isAggregateTypeForABI(RetTy)) return getNaturalAlignIndirect(RetTy); @@ -4521,13 +4519,11 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { Ty = useFirstFieldIfTransparentUnion(Ty); if (Ty->isAnyComplexType()) - llvm::report_fatal_error("complex type is not supported on AIX yet"); + return ABIArgInfo::getDirect(); if (Ty->isVectorType()) - llvm::report_fatal_error("vector type is not supported on AIX yet"); + return ABIArgInfo::getDirect(); - // TODO: Evaluate if AIX power alignment rule would have an impact on the - // alignment here. if (isAggregateTypeForABI(Ty)) { // Records with non-trivial destructors/copy-constructors should not be // passed by value. @@ -4546,11 +4542,12 @@ ABIArgInfo AIXABIInfo::classifyArgumentType(QualType Ty) const { } CharUnits AIXABIInfo::getParamTypeAlignment(QualType Ty) const { - if (Ty->isAnyComplexType()) - llvm::report_fatal_error("complex type is not supported on AIX yet"); + // Complex types are passed just like their elements. + if (const ComplexType *CTy = Ty->getAs<ComplexType>()) + Ty = CTy->getElementType(); if (Ty->isVectorType()) - llvm::report_fatal_error("vector type is not supported on AIX yet"); + return CharUnits::fromQuantity(16); // If the structure contains a vector type, the alignment is 16. if (isRecordWithSIMDVectorType(getContext(), Ty)) @@ -4565,10 +4562,11 @@ Address AIXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, llvm::report_fatal_error("complex type is not supported on AIX yet"); if (Ty->isVectorType()) - llvm::report_fatal_error("vector type is not supported on AIX yet"); + llvm::report_fatal_error( + "vector types are not yet supported for variadic functions on AIX"); auto TypeInfo = getContext().getTypeInfoInChars(Ty); - TypeInfo.second = getParamTypeAlignment(Ty); + TypeInfo.Align = getParamTypeAlignment(Ty); CharUnits SlotSize = CharUnits::fromQuantity(PtrByteSize); @@ -4687,7 +4685,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, QualType Ty) const { if (getTarget().getTriple().isOSDarwin()) { auto TI = getContext().getTypeInfoInChars(Ty); - TI.second = getParamTypeAlignment(Ty); + TI.Align = getParamTypeAlignment(Ty); CharUnits SlotSize = CharUnits::fromQuantity(4); return emitVoidPtrVAArg(CGF, VAList, Ty, @@ -4711,13 +4709,12 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, // }; bool isI64 = Ty->isIntegerType() && getContext().getTypeSize(Ty) == 64; - bool isInt = - Ty->isIntegerType() || Ty->isPointerType() || Ty->isAggregateType(); + bool isInt = !Ty->isFloatingType(); bool isF64 = Ty->isFloatingType() && getContext().getTypeSize(Ty) == 64; // All aggregates are passed indirectly? That doesn't seem consistent // with the argument-lowering code. - bool isIndirect = Ty->isAggregateType(); + bool isIndirect = isAggregateTypeForABI(Ty); CGBuilderTy &Builder = CGF.Builder; @@ -4797,7 +4794,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, CharUnits Size; if (!isIndirect) { auto TypeInfo = CGF.getContext().getTypeInfoInChars(Ty); - Size = TypeInfo.first.alignTo(OverflowAreaAlign); + Size = TypeInfo.Width.alignTo(OverflowAreaAlign); } else { Size = CGF.getPointerSize(); } @@ -4838,7 +4835,7 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, bool PPC32TargetCodeGenInfo::isStructReturnInRegABI( const llvm::Triple &Triple, const CodeGenOptions &Opts) { - assert(Triple.getArch() == llvm::Triple::ppc); + assert(Triple.isPPC32()); switch (Opts.getStructReturnConvention()) { case CodeGenOptions::SRCK_Default: @@ -4876,42 +4873,12 @@ public: private: static const unsigned GPRBits = 64; ABIKind Kind; - bool HasQPX; bool IsSoftFloatABI; - // A vector of float or double will be promoted to <4 x f32> or <4 x f64> and - // will be passed in a QPX register. - bool IsQPXVectorTy(const Type *Ty) const { - if (!HasQPX) - return false; - - if (const VectorType *VT = Ty->getAs<VectorType>()) { - unsigned NumElements = VT->getNumElements(); - if (NumElements == 1) - return false; - - if (VT->getElementType()->isSpecificBuiltinType(BuiltinType::Double)) { - if (getContext().getTypeSize(Ty) <= 256) - return true; - } else if (VT->getElementType()-> - isSpecificBuiltinType(BuiltinType::Float)) { - if (getContext().getTypeSize(Ty) <= 128) - return true; - } - } - - return false; - } - - bool IsQPXVectorTy(QualType Ty) const { - return IsQPXVectorTy(Ty.getTypePtr()); - } - public: - PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind, bool HasQPX, + PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind, bool SoftFloatABI) - : SwiftABIInfo(CGT), Kind(Kind), HasQPX(HasQPX), - IsSoftFloatABI(SoftFloatABI) {} + : SwiftABIInfo(CGT), Kind(Kind), IsSoftFloatABI(SoftFloatABI) {} bool isPromotableTypeForABI(QualType Ty) const; CharUnits getParamTypeAlignment(QualType Ty) const; @@ -4939,8 +4906,7 @@ public: const Type *T = isSingleElementStruct(I.type, getContext()); if (T) { const BuiltinType *BT = T->getAs<BuiltinType>(); - if (IsQPXVectorTy(T) || - (T->isVectorType() && getContext().getTypeSize(T) == 128) || + if ((T->isVectorType() && getContext().getTypeSize(T) == 128) || (BT && BT->isFloatingPoint())) { QualType QT(T, 0); I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); @@ -4968,10 +4934,10 @@ class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo { public: PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT, - PPC64_SVR4_ABIInfo::ABIKind Kind, bool HasQPX, + PPC64_SVR4_ABIInfo::ABIKind Kind, bool SoftFloatABI) - : TargetCodeGenInfo(std::make_unique<PPC64_SVR4_ABIInfo>( - CGT, Kind, HasQPX, SoftFloatABI)) {} + : TargetCodeGenInfo( + std::make_unique<PPC64_SVR4_ABIInfo>(CGT, Kind, SoftFloatABI)) {} int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { // This is recovered from gcc output. @@ -5036,13 +5002,15 @@ CharUnits PPC64_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { // Only vector types of size 16 bytes need alignment (larger types are // passed via reference, smaller types are not aligned). - if (IsQPXVectorTy(Ty)) { - if (getContext().getTypeSize(Ty) > 128) - return CharUnits::fromQuantity(32); - - return CharUnits::fromQuantity(16); - } else if (Ty->isVectorType()) { + if (Ty->isVectorType()) { return CharUnits::fromQuantity(getContext().getTypeSize(Ty) == 128 ? 16 : 8); + } else if (Ty->isRealFloatingType() && + &getContext().getFloatTypeSemantics(Ty) == + &llvm::APFloat::IEEEquad()) { + // According to ABI document section 'Optional Save Areas': If extended + // precision floating-point values in IEEE BINARY 128 QUADRUPLE PRECISION + // format are supported, map them to a single quadword, quadword aligned. + return CharUnits::fromQuantity(16); } // For single-element float/vector structs, we consider the whole type @@ -5051,8 +5019,7 @@ CharUnits PPC64_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { const Type *EltType = isSingleElementStruct(Ty, getContext()); if (EltType) { const BuiltinType *BT = EltType->getAs<BuiltinType>(); - if (IsQPXVectorTy(EltType) || (EltType->isVectorType() && - getContext().getTypeSize(EltType) == 128) || + if ((EltType->isVectorType() && getContext().getTypeSize(EltType) == 128) || (BT && BT->isFloatingPoint())) AlignAsType = EltType; } @@ -5065,20 +5032,13 @@ CharUnits PPC64_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { AlignAsType = Base; // With special case aggregates, only vector base types need alignment. - if (AlignAsType && IsQPXVectorTy(AlignAsType)) { - if (getContext().getTypeSize(AlignAsType) > 128) - return CharUnits::fromQuantity(32); - - return CharUnits::fromQuantity(16); - } else if (AlignAsType) { + if (AlignAsType) { return CharUnits::fromQuantity(AlignAsType->isVectorType() ? 16 : 8); } // Otherwise, we only need alignment for any aggregate type that // has an alignment requirement of >= 16 bytes. if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128) { - if (HasQPX && getContext().getTypeAlign(Ty) >= 256) - return CharUnits::fromQuantity(32); return CharUnits::fromQuantity(16); } @@ -5104,8 +5064,12 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, Members = 0; - // If this is a C++ record, check the bases first. + // If this is a C++ record, check the properties of the record such as + // bases and ABI specific restrictions if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD)) + return false; + for (const auto &I : CXXRD->bases()) { // Ignore empty records. if (isEmptyRecord(getContext(), I.getType(), true)) @@ -5202,7 +5166,7 @@ bool PPC64_SVR4_ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const { } } if (const VectorType *VT = Ty->getAs<VectorType>()) { - if (getContext().getTypeSize(VT) == 128 || IsQPXVectorTy(Ty)) + if (getContext().getTypeSize(VT) == 128) return true; } return false; @@ -5231,7 +5195,7 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes) // or via reference (larger than 16 bytes). - if (Ty->isVectorType() && !IsQPXVectorTy(Ty)) { + if (Ty->isVectorType()) { uint64_t Size = getContext().getTypeSize(Ty); if (Size > 128) return getNaturalAlignIndirect(Ty, /*ByVal=*/false); @@ -5307,7 +5271,7 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes) // or via reference (larger than 16 bytes). - if (RetTy->isVectorType() && !IsQPXVectorTy(RetTy)) { + if (RetTy->isVectorType()) { uint64_t Size = getContext().getTypeSize(RetTy); if (Size > 128) return getNaturalAlignIndirect(RetTy); @@ -5360,7 +5324,7 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { Address PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const { auto TypeInfo = getContext().getTypeInfoInChars(Ty); - TypeInfo.second = getParamTypeAlignment(Ty); + TypeInfo.Align = getParamTypeAlignment(Ty); CharUnits SlotSize = CharUnits::fromQuantity(8); @@ -5371,7 +5335,7 @@ Address PPC64_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // loads of the real and imaginary parts relative to the va_list pointer, // and store them to a temporary structure. if (const ComplexType *CTy = Ty->getAs<ComplexType>()) { - CharUnits EltSize = TypeInfo.first / 2; + CharUnits EltSize = TypeInfo.Width / 2; if (EltSize < SlotSize) { Address Addr = emitVoidPtrDirectVAArg(CGF, VAListAddr, CGF.Int8Ty, SlotSize * 2, SlotSize, @@ -5448,6 +5412,7 @@ private: ABIArgInfo classifyReturnType(QualType RetTy, bool IsVariadic) const; ABIArgInfo classifyArgumentType(QualType RetTy) const; + ABIArgInfo coerceIllegalVector(QualType Ty) const; bool isHomogeneousAggregateBaseType(QualType Ty) const override; bool isHomogeneousAggregateSmallEnough(const Type *Ty, uint64_t Members) const override; @@ -5521,40 +5486,33 @@ public: if (!FD) return; - LangOptions::SignReturnAddressScopeKind Scope = - CGM.getLangOpts().getSignReturnAddressScope(); - LangOptions::SignReturnAddressKeyKind Key = - CGM.getLangOpts().getSignReturnAddressKey(); - bool BranchTargetEnforcement = CGM.getLangOpts().BranchTargetEnforcement; - if (const auto *TA = FD->getAttr<TargetAttr>()) { - ParsedTargetAttr Attr = TA->parse(); - if (!Attr.BranchProtection.empty()) { - TargetInfo::BranchProtectionInfo BPI; - StringRef Error; - (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection, - BPI, Error); - assert(Error.empty()); - Scope = BPI.SignReturnAddr; - Key = BPI.SignKey; - BranchTargetEnforcement = BPI.BranchTargetEnforcement; - } - } + const auto *TA = FD->getAttr<TargetAttr>(); + if (TA == nullptr) + return; + + ParsedTargetAttr Attr = TA->parse(); + if (Attr.BranchProtection.empty()) + return; + + TargetInfo::BranchProtectionInfo BPI; + StringRef Error; + (void)CGM.getTarget().validateBranchProtection(Attr.BranchProtection, + BPI, Error); + assert(Error.empty()); auto *Fn = cast<llvm::Function>(GV); - if (Scope != LangOptions::SignReturnAddressScopeKind::None) { - Fn->addFnAttr("sign-return-address", - Scope == LangOptions::SignReturnAddressScopeKind::All - ? "all" - : "non-leaf"); + static const char *SignReturnAddrStr[] = {"none", "non-leaf", "all"}; + Fn->addFnAttr("sign-return-address", SignReturnAddrStr[static_cast<int>(BPI.SignReturnAddr)]); + if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) { Fn->addFnAttr("sign-return-address-key", - Key == LangOptions::SignReturnAddressKeyKind::AKey + BPI.SignKey == LangOptions::SignReturnAddressKeyKind::AKey ? "a_key" : "b_key"); } - if (BranchTargetEnforcement) - Fn->addFnAttr("branch-target-enforcement"); + Fn->addFnAttr("branch-target-enforcement", + BPI.BranchTargetEnforcement ? "true" : "false"); } }; @@ -5586,33 +5544,96 @@ void WindowsAArch64TargetCodeGenInfo::setTargetAttributes( } } +ABIArgInfo AArch64ABIInfo::coerceIllegalVector(QualType Ty) const { + assert(Ty->isVectorType() && "expected vector type!"); + + const auto *VT = Ty->castAs<VectorType>(); + if (VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector) { + assert(VT->getElementType()->isBuiltinType() && "expected builtin type!"); + assert(VT->getElementType()->castAs<BuiltinType>()->getKind() == + BuiltinType::UChar && + "unexpected builtin type for SVE predicate!"); + return ABIArgInfo::getDirect(llvm::ScalableVectorType::get( + llvm::Type::getInt1Ty(getVMContext()), 16)); + } + + if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector) { + assert(VT->getElementType()->isBuiltinType() && "expected builtin type!"); + + const auto *BT = VT->getElementType()->castAs<BuiltinType>(); + llvm::ScalableVectorType *ResType = nullptr; + switch (BT->getKind()) { + default: + llvm_unreachable("unexpected builtin type for SVE vector!"); + case BuiltinType::SChar: + case BuiltinType::UChar: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getInt8Ty(getVMContext()), 16); + break; + case BuiltinType::Short: + case BuiltinType::UShort: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getInt16Ty(getVMContext()), 8); + break; + case BuiltinType::Int: + case BuiltinType::UInt: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getInt32Ty(getVMContext()), 4); + break; + case BuiltinType::Long: + case BuiltinType::ULong: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getInt64Ty(getVMContext()), 2); + break; + case BuiltinType::Half: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getHalfTy(getVMContext()), 8); + break; + case BuiltinType::Float: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getFloatTy(getVMContext()), 4); + break; + case BuiltinType::Double: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getDoubleTy(getVMContext()), 2); + break; + case BuiltinType::BFloat16: + ResType = llvm::ScalableVectorType::get( + llvm::Type::getBFloatTy(getVMContext()), 8); + break; + } + return ABIArgInfo::getDirect(ResType); + } + + uint64_t Size = getContext().getTypeSize(Ty); + // Android promotes <2 x i8> to i16, not i32 + if (isAndroid() && (Size <= 16)) { + llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext()); + return ABIArgInfo::getDirect(ResType); + } + if (Size <= 32) { + llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext()); + return ABIArgInfo::getDirect(ResType); + } + if (Size == 64) { + auto *ResType = + llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2); + return ABIArgInfo::getDirect(ResType); + } + if (Size == 128) { + auto *ResType = + llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4); + return ABIArgInfo::getDirect(ResType); + } + return getNaturalAlignIndirect(Ty, /*ByVal=*/false); +} + ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty) const { Ty = useFirstFieldIfTransparentUnion(Ty); // Handle illegal vector types here. - if (isIllegalVectorType(Ty)) { - uint64_t Size = getContext().getTypeSize(Ty); - // Android promotes <2 x i8> to i16, not i32 - if (isAndroid() && (Size <= 16)) { - llvm::Type *ResType = llvm::Type::getInt16Ty(getVMContext()); - return ABIArgInfo::getDirect(ResType); - } - if (Size <= 32) { - llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext()); - return ABIArgInfo::getDirect(ResType); - } - if (Size == 64) { - auto *ResType = - llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2); - return ABIArgInfo::getDirect(ResType); - } - if (Size == 128) { - auto *ResType = - llvm::FixedVectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4); - return ABIArgInfo::getDirect(ResType); - } - return getNaturalAlignIndirect(Ty, /*ByVal=*/false); - } + if (isIllegalVectorType(Ty)) + return coerceIllegalVector(Ty); if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. @@ -5691,6 +5712,12 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy, if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); + if (const auto *VT = RetTy->getAs<VectorType>()) { + if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector || + VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector) + return coerceIllegalVector(RetTy); + } + // Large vector types should be returned via memory. if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128) return getNaturalAlignIndirect(RetTy); @@ -5746,6 +5773,13 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy, /// isIllegalVectorType - check whether the vector type is legal for AArch64. bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const { if (const VectorType *VT = Ty->getAs<VectorType>()) { + // Check whether VT is a fixed-length SVE vector. These types are + // represented as scalable vectors in function args/return and must be + // coerced from fixed vectors. + if (VT->getVectorKind() == VectorType::SveFixedLengthDataVector || + VT->getVectorKind() == VectorType::SveFixedLengthPredicateVector) + return true; + // Check whether VT is legal. unsigned NumElements = VT->getNumElements(); uint64_t Size = getContext().getTypeSize(VT); @@ -5938,13 +5972,13 @@ Address AArch64ABIInfo::EmitAAPCSVAArg(Address VAListAddr, llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0)); llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers); Address Tmp = CGF.CreateTempAlloca(HFATy, - std::max(TyAlign, BaseTyInfo.second)); + std::max(TyAlign, BaseTyInfo.Align)); // On big-endian platforms, the value will be right-aligned in its slot. int Offset = 0; if (CGF.CGM.getDataLayout().isBigEndian() && - BaseTyInfo.first.getQuantity() < 16) - Offset = 16 - BaseTyInfo.first.getQuantity(); + BaseTyInfo.Width.getQuantity() < 16) + Offset = 16 - BaseTyInfo.Width.getQuantity(); for (unsigned i = 0; i < NumMembers; ++i) { CharUnits BaseOffset = CharUnits::fromQuantity(16 * i + Offset); @@ -6068,7 +6102,7 @@ Address AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty, // Arguments bigger than 16 bytes which aren't homogeneous // aggregates should be passed indirectly. bool IsIndirect = false; - if (TyInfo.first.getQuantity() > 16) { + if (TyInfo.Width.getQuantity() > 16) { const Type *Base = nullptr; uint64_t Members = 0; IsIndirect = !isHomogeneousAggregate(Ty, Base, Members); @@ -6830,7 +6864,7 @@ Address ARMABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, TyAlignForABI = CharUnits::fromQuantity(4); } - std::pair<CharUnits, CharUnits> TyInfo = { TySize, TyAlignForABI }; + TypeInfoChars TyInfo(TySize, TyAlignForABI, false); return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TyInfo, SlotSize, /*AllowHigherAlign*/ true); } @@ -7304,8 +7338,8 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, ArgTy = AI.getCoerceToType(); InFPRs = (!IsSoftFloatABI && (ArgTy->isFloatTy() || ArgTy->isDoubleTy())); IsVector = ArgTy->isVectorTy(); - UnpaddedSize = TyInfo.first; - DirectAlign = TyInfo.second; + UnpaddedSize = TyInfo.Width; + DirectAlign = TyInfo.Align; } CharUnits PaddedSize = CharUnits::fromQuantity(8); if (IsVector && UnpaddedSize > PaddedSize) @@ -7326,7 +7360,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr"); Address OverflowArgArea = Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"), - TyInfo.second); + TyInfo.Align); Address MemAddr = CGF.Builder.CreateElementBitCast(OverflowArgArea, DirectTy, "mem_addr"); @@ -7423,7 +7457,7 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, if (IsIndirect) ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), - TyInfo.second); + TyInfo.Align); return ResAddr; } @@ -7920,8 +7954,8 @@ Address MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, // The alignment of things in the argument area is never larger than // StackAlignInBytes. - TyInfo.second = - std::min(TyInfo.second, CharUnits::fromQuantity(StackAlignInBytes)); + TyInfo.Align = + std::min(TyInfo.Align, CharUnits::fromQuantity(StackAlignInBytes)); // MinABIStackAlignInBytes is the size of argument slots on the stack. CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes); @@ -8562,7 +8596,7 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty, if (RAA == CGCXXABI::RAA_Indirect) { return getIndirectResult(Ty, /*ByVal=*/false, State); } else if (RAA == CGCXXABI::RAA_DirectInMemory) { - return getNaturalAlignIndirect(Ty, /*ByRef=*/true); + return getNaturalAlignIndirect(Ty, /*ByVal=*/true); } } @@ -8634,35 +8668,9 @@ private: bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const override; - // Coerce HIP pointer arguments from generic pointers to global ones. + // Coerce HIP scalar pointer arguments from generic pointers to global ones. llvm::Type *coerceKernelArgumentType(llvm::Type *Ty, unsigned FromAS, unsigned ToAS) const { - // Structure types. - if (auto STy = dyn_cast<llvm::StructType>(Ty)) { - SmallVector<llvm::Type *, 8> EltTys; - bool Changed = false; - for (auto T : STy->elements()) { - auto NT = coerceKernelArgumentType(T, FromAS, ToAS); - EltTys.push_back(NT); - Changed |= (NT != T); - } - // Skip if there is no change in element types. - if (!Changed) - return STy; - if (STy->hasName()) - return llvm::StructType::create( - EltTys, (STy->getName() + ".coerce").str(), STy->isPacked()); - return llvm::StructType::get(getVMContext(), EltTys, STy->isPacked()); - } - // Array types. - if (auto ATy = dyn_cast<llvm::ArrayType>(Ty)) { - auto T = ATy->getElementType(); - auto NT = coerceKernelArgumentType(T, FromAS, ToAS); - // Skip if there is no change in that element type. - if (NT == T) - return ATy; - return llvm::ArrayType::get(NT, ATy->getNumElements()); - } // Single value types. if (Ty->isPointerTy() && Ty->getPointerAddressSpace() == FromAS) return llvm::PointerType::get( @@ -8797,18 +8805,31 @@ ABIArgInfo AMDGPUABIInfo::classifyKernelArgumentType(QualType Ty) const { // TODO: Can we omit empty structs? - llvm::Type *LTy = nullptr; if (const Type *SeltTy = isSingleElementStruct(Ty, getContext())) - LTy = CGT.ConvertType(QualType(SeltTy, 0)); + Ty = QualType(SeltTy, 0); + llvm::Type *OrigLTy = CGT.ConvertType(Ty); + llvm::Type *LTy = OrigLTy; if (getContext().getLangOpts().HIP) { - if (!LTy) - LTy = CGT.ConvertType(Ty); LTy = coerceKernelArgumentType( - LTy, /*FromAS=*/getContext().getTargetAddressSpace(LangAS::Default), + OrigLTy, /*FromAS=*/getContext().getTargetAddressSpace(LangAS::Default), /*ToAS=*/getContext().getTargetAddressSpace(LangAS::cuda_device)); } + // FIXME: Should also use this for OpenCL, but it requires addressing the + // problem of kernels being called. + // + // FIXME: This doesn't apply the optimization of coercing pointers in structs + // to global address space when using byref. This would require implementing a + // new kind of coercion of the in-memory type when for indirect arguments. + if (!getContext().getLangOpts().OpenCL && LTy == OrigLTy && + isAggregateTypeForABI(Ty)) { + return ABIArgInfo::getIndirectAliased( + getContext().getTypeAlignInChars(Ty), + getContext().getTargetAddressSpace(LangAS::opencl_constant), + false /*Realign*/, nullptr /*Padding*/); + } + // If we set CanBeFlattened to true, CodeGen will expand the struct to its // individual elements, which confuses the Clover OpenCL backend; therefore we // have to set it to false here. Other args of getDirect() are just defaults. @@ -8977,13 +8998,9 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes( assert(Max == 0 && "Max must be zero"); } else if (IsOpenCLKernel || IsHIPKernel) { // By default, restrict the maximum size to a value specified by - // --gpu-max-threads-per-block=n or its default value for HIP. - const unsigned OpenCLDefaultMaxWorkGroupSize = 256; - const unsigned DefaultMaxWorkGroupSize = - IsOpenCLKernel ? OpenCLDefaultMaxWorkGroupSize - : M.getLangOpts().GPUMaxThreadsPerBlock; + // --gpu-max-threads-per-block=n or its default value. std::string AttrVal = - std::string("1,") + llvm::utostr(DefaultMaxWorkGroupSize); + std::string("1,") + llvm::utostr(M.getLangOpts().GPUMaxThreadsPerBlock); F->addFnAttr("amdgpu-flat-work-group-size", AttrVal); } @@ -9019,6 +9036,9 @@ void AMDGPUTargetCodeGenInfo::setTargetAttributes( if (NumVGPR != 0) F->addFnAttr("amdgpu-num-vgpr", llvm::utostr(NumVGPR)); } + + if (M.getContext().getTargetInfo().allowAMDGPUUnsafeFPAtomics()) + F->addFnAttr("amdgpu-unsafe-fp-atomics", "true"); } unsigned AMDGPUTargetCodeGenInfo::getOpenCLKernelCallingConv() const { @@ -9371,7 +9391,7 @@ Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, case ABIArgInfo::Extend: { Stride = SlotSize; - CharUnits Offset = SlotSize - TypeInfo.first; + CharUnits Offset = SlotSize - TypeInfo.Width; ArgAddr = Builder.CreateConstInBoundsByteGEP(Addr, Offset, "extend"); break; } @@ -9384,14 +9404,15 @@ Address SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, } case ABIArgInfo::Indirect: + case ABIArgInfo::IndirectAliased: Stride = SlotSize; ArgAddr = Builder.CreateElementBitCast(Addr, ArgPtrTy, "indirect"); ArgAddr = Address(Builder.CreateLoad(ArgAddr, "indirect.arg"), - TypeInfo.second); + TypeInfo.Align); break; case ABIArgInfo::Ignore: - return Address(llvm::UndefValue::get(ArgPtrTy), TypeInfo.second); + return Address(llvm::UndefValue::get(ArgPtrTy), TypeInfo.Align); } // Update VAList. @@ -9749,6 +9770,7 @@ Address XCoreABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, ArgSize = ArgSize.alignTo(SlotSize); break; case ABIArgInfo::Indirect: + case ABIArgInfo::IndirectAliased: Val = Builder.CreateElementBitCast(AP, ArgPtrTy); Val = Address(Builder.CreateLoad(Val), TypeAlign); ArgSize = SlotSize; @@ -9906,14 +9928,27 @@ void XCoreTargetCodeGenInfo::emitTargetMetadata( //===----------------------------------------------------------------------===// namespace { +class SPIRABIInfo : public DefaultABIInfo { +public: + SPIRABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) { setCCs(); } + +private: + void setCCs(); +}; +} // end anonymous namespace +namespace { class SPIRTargetCodeGenInfo : public TargetCodeGenInfo { public: SPIRTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) - : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} + : TargetCodeGenInfo(std::make_unique<SPIRABIInfo>(CGT)) {} unsigned getOpenCLKernelCallingConv() const override; }; } // End anonymous namespace. +void SPIRABIInfo::setCCs() { + assert(getRuntimeCC() == llvm::CallingConv::C); + RuntimeCC = llvm::CallingConv::SPIR_FUNC; +} namespace clang { namespace CodeGen { @@ -10323,7 +10358,7 @@ void RISCVABIInfo::computeInfo(CGFunctionInfo &FI) const { if (!IsRetIndirect && RetTy->isScalarType() && getContext().getTypeSize(RetTy) > (2 * XLen)) { if (RetTy->isComplexType() && FLen) { - QualType EltTy = RetTy->getAs<ComplexType>()->getElementType(); + QualType EltTy = RetTy->castAs<ComplexType>()->getElementType(); IsRetIndirect = getContext().getTypeSize(EltTy) > FLen; } else { // This is a normal scalar > 2*XLen, such as fp128 on RV32. @@ -10685,13 +10720,12 @@ Address RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, return Addr; } - std::pair<CharUnits, CharUnits> SizeAndAlign = - getContext().getTypeInfoInChars(Ty); + auto TInfo = getContext().getTypeInfoInChars(Ty); // Arguments bigger than 2*Xlen bytes are passed indirectly. - bool IsIndirect = SizeAndAlign.first > 2 * SlotSize; + bool IsIndirect = TInfo.Width > 2 * SlotSize; - return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, SizeAndAlign, + return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo, SlotSize, /*AllowHigherAlign=*/true); } @@ -10749,21 +10783,24 @@ private: } // end anonymous namespace ABIArgInfo VEABIInfo::classifyReturnType(QualType Ty) const { - if (Ty->isAnyComplexType()) { + if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); - } + uint64_t Size = getContext().getTypeSize(Ty); + if (Size < 64 && Ty->isIntegerType()) + return ABIArgInfo::getExtend(Ty); return DefaultABIInfo::classifyReturnType(Ty); } ABIArgInfo VEABIInfo::classifyArgumentType(QualType Ty) const { - if (Ty->isAnyComplexType()) { + if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); - } + uint64_t Size = getContext().getTypeSize(Ty); + if (Size < 64 && Ty->isIntegerType()) + return ABIArgInfo::getExtend(Ty); return DefaultABIInfo::classifyArgumentType(Ty); } void VEABIInfo::computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); for (auto &Arg : FI.arguments()) Arg.info = classifyArgumentType(Arg.type); @@ -10878,6 +10915,13 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { return SetCGInfo( new PPC32TargetCodeGenInfo(Types, IsSoftFloat, RetSmallStructInRegABI)); } + case llvm::Triple::ppcle: { + bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; + bool RetSmallStructInRegABI = + PPC32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts); + return SetCGInfo( + new PPC32TargetCodeGenInfo(Types, IsSoftFloat, RetSmallStructInRegABI)); + } case llvm::Triple::ppc64: if (Triple.isOSAIX()) return SetCGInfo(new AIXTargetCodeGenInfo(Types, /*Is64Bit*/ true)); @@ -10886,23 +10930,21 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1; if (getTarget().getABI() == "elfv2") Kind = PPC64_SVR4_ABIInfo::ELFv2; - bool HasQPX = getTarget().getABI() == "elfv1-qpx"; bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; - return SetCGInfo(new PPC64_SVR4_TargetCodeGenInfo(Types, Kind, HasQPX, - IsSoftFloat)); + return SetCGInfo( + new PPC64_SVR4_TargetCodeGenInfo(Types, Kind, IsSoftFloat)); } return SetCGInfo(new PPC64TargetCodeGenInfo(Types)); case llvm::Triple::ppc64le: { assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!"); PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv2; - if (getTarget().getABI() == "elfv1" || getTarget().getABI() == "elfv1-qpx") + if (getTarget().getABI() == "elfv1") Kind = PPC64_SVR4_ABIInfo::ELFv1; - bool HasQPX = getTarget().getABI() == "elfv1-qpx"; bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; - return SetCGInfo(new PPC64_SVR4_TargetCodeGenInfo(Types, Kind, HasQPX, - IsSoftFloat)); + return SetCGInfo( + new PPC64_SVR4_TargetCodeGenInfo(Types, Kind, IsSoftFloat)); } case llvm::Triple::nvptx: @@ -11015,7 +11057,8 @@ TargetCodeGenInfo::createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::SmallVector<llvm::Value *, 2> Args; for (auto &A : F->args()) Args.push_back(&A); - Builder.CreateCall(Invoke, Args); + llvm::CallInst *call = Builder.CreateCall(Invoke, Args); + call->setCallingConv(Invoke->getCallingConv()); Builder.CreateRetVoid(); Builder.restoreIP(IP); return F; @@ -11079,7 +11122,8 @@ llvm::Function *AMDGPUTargetCodeGenInfo::createEnqueuedBlockKernel( Args.push_back(Cast); for (auto I = F->arg_begin() + 1, E = F->arg_end(); I != E; ++I) Args.push_back(I); - Builder.CreateCall(Invoke, Args); + llvm::CallInst *call = Builder.CreateCall(Invoke, Args); + call->setCallingConv(Invoke->getCallingConv()); Builder.CreateRetVoid(); Builder.restoreIP(IP); |