aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/TargetInfo.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@chromium.org>2020-01-28 22:17:31 +0100
committerHans Wennborg <hans@chromium.org>2020-01-28 22:25:07 +0100
commiteaabaf7e04fe98990a8177a3e053346395efde1c (patch)
treefe9d907b263f9b7158984a4e34948f612be5cfca /clang/lib/CodeGen/TargetInfo.cpp
parent8e21d7b9249e2e35f12dbbaa18287ce8435dd855 (diff)
downloadllvm-eaabaf7e04fe98990a8177a3e053346395efde1c.zip
llvm-eaabaf7e04fe98990a8177a3e053346395efde1c.tar.gz
llvm-eaabaf7e04fe98990a8177a3e053346395efde1c.tar.bz2
Revert "[MS] Overhaul how clang passes overaligned args on x86_32"
It broke some Chromium tests, so let's revert until it can be fixed; see https://crbug.com/1046362 This reverts commit 2af74e27ed7d0832cbdde9cb969aaca7a42e99f9.
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r--clang/lib/CodeGen/TargetInfo.cpp74
1 files changed, 24 insertions, 50 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 08ef8ff..c803785 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -1676,7 +1676,6 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
bool IsVectorCall = State.CC == llvm::CallingConv::X86_VectorCall;
Ty = useFirstFieldIfTransparentUnion(Ty);
- TypeInfo TI = getContext().getTypeInfo(Ty);
// Check with the C++ ABI first.
const RecordType *RT = Ty->getAs<RecordType>();
@@ -1726,7 +1725,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
bool NeedsPadding = false;
bool InReg;
if (shouldAggregateUseDirect(Ty, State, InReg, NeedsPadding)) {
- unsigned SizeInRegs = (TI.Width + 31) / 32;
+ unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
SmallVector<llvm::Type*, 3> Elements(SizeInRegs, Int32);
llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
if (InReg)
@@ -1736,19 +1735,14 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
}
llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : nullptr;
- // Pass over-aligned aggregates on Windows indirectly. This behavior was
- // added in MSVC 2015.
- if (IsWin32StructABI && TI.AlignIsRequired && TI.Align > 32)
- return getIndirectResult(Ty, /*ByVal=*/false, State);
-
// Expand small (<= 128-bit) record types when we know that the stack layout
// of those arguments will match the struct. This is important because the
// LLVM backend isn't smart enough to remove byval, which inhibits many
// optimizations.
// Don't do this for the MCU if there are still free integer registers
// (see X86_64 ABI for full explanation).
- if (TI.Width <= 4 * 32 && (!IsMCUABI || State.FreeRegs == 0) &&
- canExpandIndirectArgument(Ty))
+ if (getContext().getTypeSize(Ty) <= 4 * 32 &&
+ (!IsMCUABI || State.FreeRegs == 0) && canExpandIndirectArgument(Ty))
return ABIArgInfo::getExpandWithPadding(
IsFastCall || IsVectorCall || IsRegCall, PaddingType);
@@ -1756,24 +1750,14 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
}
if (const VectorType *VT = Ty->getAs<VectorType>()) {
- // On Windows, vectors are passed directly if registers are available, or
- // indirectly if not. This avoids the need to align argument memory. Pass
- // user-defined vector types larger than 512 bits indirectly for simplicity.
- if (IsWin32StructABI) {
- if (TI.Width <= 512 && State.FreeSSERegs > 0) {
- --State.FreeSSERegs;
- return ABIArgInfo::getDirectInReg();
- }
- return getIndirectResult(Ty, /*ByVal=*/false, State);
- }
-
// On Darwin, some vectors are passed in memory, we handle this by passing
// it as an i8/i16/i32/i64.
if (IsDarwinVectorABI) {
- if ((TI.Width == 8 || TI.Width == 16 || TI.Width == 32) ||
- (TI.Width == 64 && VT->getNumElements() == 1))
- return ABIArgInfo::getDirect(
- llvm::IntegerType::get(getVMContext(), TI.Width));
+ uint64_t Size = getContext().getTypeSize(Ty);
+ if ((Size == 8 || Size == 16 || Size == 32) ||
+ (Size == 64 && VT->getNumElements() == 1))
+ return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
+ Size));
}
if (IsX86_MMXType(CGT.ConvertType(Ty)))
@@ -1803,10 +1787,9 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
CCState State(FI);
if (IsMCUABI)
State.FreeRegs = 3;
- else if (State.CC == llvm::CallingConv::X86_FastCall) {
+ else if (State.CC == llvm::CallingConv::X86_FastCall)
State.FreeRegs = 2;
- State.FreeSSERegs = 3;
- } else if (State.CC == llvm::CallingConv::X86_VectorCall) {
+ else if (State.CC == llvm::CallingConv::X86_VectorCall) {
State.FreeRegs = 2;
State.FreeSSERegs = 6;
} else if (FI.getHasRegParm())
@@ -1814,11 +1797,6 @@ void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
else if (State.CC == llvm::CallingConv::X86_RegCall) {
State.FreeRegs = 5;
State.FreeSSERegs = 8;
- } else if (IsWin32StructABI) {
- // Since MSVC 2015, the first three SSE vectors have been passed in
- // registers. The rest are passed indirectly.
- State.FreeRegs = DefaultNumRegisterParameters;
- State.FreeSSERegs = 3;
} else
State.FreeRegs = DefaultNumRegisterParameters;
@@ -1865,25 +1843,16 @@ X86_32ABIInfo::addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields,
CharUnits &StackOffset, ABIArgInfo &Info,
QualType Type) const {
// Arguments are always 4-byte-aligned.
- CharUnits WordSize = CharUnits::fromQuantity(4);
- assert(StackOffset.isMultipleOf(WordSize) && "unaligned inalloca struct");
+ CharUnits FieldAlign = CharUnits::fromQuantity(4);
- // sret pointers and indirect things will require an extra pointer
- // indirection, unless they are byval. Most things are byval, and will not
- // require this indirection.
- bool IsIndirect = false;
- if (Info.isIndirect() && !Info.getIndirectByVal())
- IsIndirect = true;
- Info = ABIArgInfo::getInAlloca(FrameFields.size(), IsIndirect);
- llvm::Type *LLTy = CGT.ConvertTypeForMem(Type);
- if (IsIndirect)
- LLTy = LLTy->getPointerTo(0);
- FrameFields.push_back(LLTy);
- StackOffset += IsIndirect ? WordSize : getContext().getTypeSizeInChars(Type);
+ assert(StackOffset.isMultipleOf(FieldAlign) && "unaligned inalloca struct");
+ Info = ABIArgInfo::getInAlloca(FrameFields.size());
+ FrameFields.push_back(CGT.ConvertTypeForMem(Type));
+ StackOffset += getContext().getTypeSizeInChars(Type);
// Insert padding bytes to respect alignment.
CharUnits FieldEnd = StackOffset;
- StackOffset = FieldEnd.alignTo(WordSize);
+ StackOffset = FieldEnd.alignTo(FieldAlign);
if (StackOffset != FieldEnd) {
CharUnits NumBytes = StackOffset - FieldEnd;
llvm::Type *Ty = llvm::Type::getInt8Ty(getVMContext());
@@ -1897,12 +1866,16 @@ static bool isArgInAlloca(const ABIArgInfo &Info) {
switch (Info.getKind()) {
case ABIArgInfo::InAlloca:
return true;
+ case ABIArgInfo::Indirect:
+ assert(Info.getIndirectByVal());
+ return true;
case ABIArgInfo::Ignore:
return false;
- case ABIArgInfo::Indirect:
case ABIArgInfo::Direct:
case ABIArgInfo::Extend:
- return !Info.getInReg();
+ if (Info.getInReg())
+ return false;
+ return true;
case ABIArgInfo::Expand:
case ABIArgInfo::CoerceAndExpand:
// These are aggregate types which are never passed in registers when
@@ -1936,7 +1909,8 @@ void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const {
// Put the sret parameter into the inalloca struct if it's in memory.
if (Ret.isIndirect() && !Ret.getInReg()) {
- addFieldToArgStruct(FrameFields, StackOffset, Ret, FI.getReturnType());
+ CanQualType PtrTy = getContext().getPointerType(FI.getReturnType());
+ addFieldToArgStruct(FrameFields, StackOffset, Ret, PtrTy);
// On Windows, the hidden sret parameter is always returned in eax.
Ret.setInAllocaSRet(IsWin32StructABI);
}