aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-06-13 19:31:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-06-13 19:37:19 +0000
commite8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch)
tree94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp
parentbb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff)
parentb60736ec1405bb0a8dd40989f67ef4c93da068ab (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/TargetInfo.cpp608
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 &current) const;
- void computeVectorCallArgs(CGFunctionInfo &FI, unsigned FreeSSERegs,
- bool IsVectorCall, bool IsRegCall) const;
+ ABIArgInfo reclassifyHvaArgForVectorCall(QualType Ty, unsigned &FreeSSERegs,
+ const ABIArgInfo &current) 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 &current) const {
- // Assumes vectorCall calling convention.
+ABIArgInfo WinX86_64ABIInfo::reclassifyHvaArgForVectorCall(
+ QualType Ty, unsigned &FreeSSERegs, const ABIArgInfo &current) 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);