summaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/CodeGen/CallingConvLower.h42
-rw-r--r--llvm/lib/CodeGen/CallingConvLower.cpp15
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp8
-rw-r--r--llvm/lib/Target/Sparc/SparcISelLowering.cpp2
-rw-r--r--llvm/unittests/CodeGen/CCStateTest.cpp49
-rw-r--r--llvm/unittests/CodeGen/CMakeLists.txt1
-rw-r--r--llvm/utils/TableGen/CallingConvEmitter.cpp4
7 files changed, 91 insertions, 30 deletions
diff --git a/llvm/include/llvm/CodeGen/CallingConvLower.h b/llvm/include/llvm/CodeGen/CallingConvLower.h
index 3d70f5a2d8e9..a99519252cf9 100644
--- a/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -91,14 +91,14 @@ public:
return getReg(ValNo, ValVT, RegNo, LocVT, HTP, /*IsCustom=*/true);
}
- static CCValAssign getMem(unsigned ValNo, MVT ValVT, unsigned Offset,
+ static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset,
MVT LocVT, LocInfo HTP, bool IsCustom = false) {
CCValAssign Ret(HTP, ValNo, ValVT, LocVT, IsCustom);
- Ret.Data = int64_t(Offset);
+ Ret.Data = Offset;
return Ret;
}
- static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, unsigned Offset,
+ static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset,
MVT LocVT, LocInfo HTP) {
return getMem(ValNo, ValVT, Offset, LocVT, HTP, /*IsCustom=*/true);
}
@@ -112,7 +112,7 @@ public:
void convertToReg(unsigned RegNo) { Data = Register(RegNo); }
- void convertToMem(unsigned Offset) { Data = int64_t(Offset); }
+ void convertToMem(int64_t Offset) { Data = Offset; }
unsigned getValNo() const { return ValNo; }
MVT getValVT() const { return ValVT; }
@@ -124,7 +124,7 @@ public:
bool needsCustom() const { return isCustom; }
Register getLocReg() const { return std::get<Register>(Data); }
- unsigned getLocMemOffset() const { return std::get<int64_t>(Data); }
+ int64_t getLocMemOffset() const { return std::get<int64_t>(Data); }
unsigned getExtraInfo() const { return std::get<unsigned>(Data); }
MVT getLocVT() const { return LocVT; }
@@ -174,8 +174,10 @@ private:
const TargetRegisterInfo &TRI;
SmallVectorImpl<CCValAssign> &Locs;
LLVMContext &Context;
+ // True if arguments should be allocated at negative offsets.
+ bool NegativeOffsets;
- unsigned StackSize;
+ uint64_t StackSize;
Align MaxStackArgAlign;
SmallVector<uint32_t, 16> UsedRegs;
SmallVector<CCValAssign, 4> PendingLocs;
@@ -224,8 +226,9 @@ private:
unsigned InRegsParamsProcessed;
public:
- CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
- SmallVectorImpl<CCValAssign> &locs, LLVMContext &C);
+ CCState(CallingConv::ID CC, bool IsVarArg, MachineFunction &MF,
+ SmallVectorImpl<CCValAssign> &Locs, LLVMContext &Context,
+ bool NegativeOffsets = false);
void addLoc(const CCValAssign &V) {
Locs.push_back(V);
@@ -237,12 +240,12 @@ public:
bool isVarArg() const { return IsVarArg; }
/// Returns the size of the currently allocated portion of the stack.
- unsigned getStackSize() const { return StackSize; }
+ uint64_t getStackSize() const { return StackSize; }
/// getAlignedCallFrameSize - Return the size of the call frame needed to
/// be able to store all arguments and such that the alignment requirement
/// of each of the arguments is satisfied.
- unsigned getAlignedCallFrameSize() const {
+ uint64_t getAlignedCallFrameSize() const {
return alignTo(StackSize, MaxStackArgAlign);
}
@@ -396,21 +399,26 @@ public:
/// AllocateStack - Allocate a chunk of stack space with the specified size
/// and alignment.
- unsigned AllocateStack(unsigned Size, Align Alignment) {
- StackSize = alignTo(StackSize, Alignment);
- unsigned Result = StackSize;
- StackSize += Size;
+ int64_t AllocateStack(unsigned Size, Align Alignment) {
+ int64_t Offset;
+ if (NegativeOffsets) {
+ StackSize = alignTo(StackSize + Size, Alignment);
+ Offset = -StackSize;
+ } else {
+ Offset = alignTo(StackSize, Alignment);
+ StackSize = Offset + Size;
+ }
MaxStackArgAlign = std::max(Alignment, MaxStackArgAlign);
ensureMaxAlignment(Alignment);
- return Result;
+ return Offset;
}
void ensureMaxAlignment(Align Alignment);
/// Version of AllocateStack with list of extra registers to be shadowed.
/// Note that, unlike AllocateReg, this shadows ALL of the shadow registers.
- unsigned AllocateStack(unsigned Size, Align Alignment,
- ArrayRef<MCPhysReg> ShadowRegs) {
+ int64_t AllocateStack(unsigned Size, Align Alignment,
+ ArrayRef<MCPhysReg> ShadowRegs) {
for (MCPhysReg Reg : ShadowRegs)
MarkAllocated(Reg);
return AllocateStack(Size, Alignment);
diff --git a/llvm/lib/CodeGen/CallingConvLower.cpp b/llvm/lib/CodeGen/CallingConvLower.cpp
index 0cd9b005d074..b7152587a9fa 100644
--- a/llvm/lib/CodeGen/CallingConvLower.cpp
+++ b/llvm/lib/CodeGen/CallingConvLower.cpp
@@ -25,10 +25,13 @@
using namespace llvm;
-CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf,
- SmallVectorImpl<CCValAssign> &locs, LLVMContext &C)
- : CallingConv(CC), IsVarArg(isVarArg), MF(mf),
- TRI(*MF.getSubtarget().getRegisterInfo()), Locs(locs), Context(C) {
+CCState::CCState(CallingConv::ID CC, bool IsVarArg, MachineFunction &MF,
+ SmallVectorImpl<CCValAssign> &Locs, LLVMContext &Context,
+ bool NegativeOffsets)
+ : CallingConv(CC), IsVarArg(IsVarArg), MF(MF),
+ TRI(*MF.getSubtarget().getRegisterInfo()), Locs(Locs), Context(Context),
+ NegativeOffsets(NegativeOffsets) {
+
// No stack is used.
StackSize = 0;
@@ -51,7 +54,7 @@ void CCState::HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT,
ensureMaxAlignment(Alignment);
MF.getSubtarget().getTargetLowering()->HandleByVal(this, Size, Alignment);
Size = unsigned(alignTo(Size, MinAlign));
- unsigned Offset = AllocateStack(Size, Alignment);
+ uint64_t Offset = AllocateStack(Size, Alignment);
addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
}
@@ -197,7 +200,7 @@ static bool isValueTypeInRegForCC(CallingConv::ID CC, MVT VT) {
void CCState::getRemainingRegParmsForType(SmallVectorImpl<MCPhysReg> &Regs,
MVT VT, CCAssignFn Fn) {
- unsigned SavedStackSize = StackSize;
+ uint64_t SavedStackSize = StackSize;
Align SavedMaxStackArgAlign = MaxStackArgAlign;
unsigned NumLocs = Locs.size();
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index a6ff951b71c7..93577dc4ff0d 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -7224,8 +7224,8 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
// On AIX a minimum of 8 words is saved to the parameter save area.
const unsigned MinParameterSaveArea = 8 * PtrByteSize;
// Area that is at least reserved in the caller of this function.
- unsigned CallerReservedArea =
- std::max(CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
+ unsigned CallerReservedArea = std::max<unsigned>(
+ CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
// Set the size that is at least reserved in caller of this function. Tail
// call optimized function's reserved stack space needs to be aligned so
@@ -7317,8 +7317,8 @@ SDValue PPCTargetLowering::LowerCall_AIX(
// conservatively assume that it is needed. As such, make sure we have at
// least enough stack space for the caller to store the 8 GPRs.
const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
- const unsigned NumBytes =
- std::max(LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
+ const unsigned NumBytes = std::max<unsigned>(
+ LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
// Adjust the stack pointer for the new arguments...
// These operations are automatically eliminated by the prolog/epilog pass.
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 6e6041b782fb..0aa3c875a14f 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1204,7 +1204,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::CallLoweringInfo &CLI,
// Called functions expect 6 argument words to exist in the stack frame, used
// or not.
unsigned StackReserved = 6 * 8u;
- unsigned ArgsSize = std::max(StackReserved, CCInfo.getStackSize());
+ unsigned ArgsSize = std::max<unsigned>(StackReserved, CCInfo.getStackSize());
// Keep stack frames 16-byte aligned.
ArgsSize = alignTo(ArgsSize, 16);
diff --git a/llvm/unittests/CodeGen/CCStateTest.cpp b/llvm/unittests/CodeGen/CCStateTest.cpp
new file mode 100644
index 000000000000..405e1c6ef90d
--- /dev/null
+++ b/llvm/unittests/CodeGen/CCStateTest.cpp
@@ -0,0 +1,49 @@
+//===- CCStateTest.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/Module.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Target/TargetMachine.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+#include "MFCommon.inc"
+
+TEST(CCStateTest, NegativeOffsets) {
+ LLVMContext Ctx;
+ Module Mod("Module", Ctx);
+ auto MF = createMachineFunction(Ctx, Mod);
+
+ SmallVector<CCValAssign, 8> Locs;
+ CCState Info(CallingConv::C, /*IsVarArg=*/false, *MF, Locs, Ctx,
+ /*NegativeOffsets=*/true);
+
+ ASSERT_EQ(Info.AllocateStack(1, Align(1)), -1);
+ ASSERT_EQ(Info.AllocateStack(1, Align(2)), -2);
+ ASSERT_EQ(Info.AllocateStack(1, Align(2)), -4);
+ ASSERT_EQ(Info.AllocateStack(1, Align(1)), -5);
+ ASSERT_EQ(Info.AllocateStack(2, Align(2)), -8);
+ ASSERT_EQ(Info.AllocateStack(2, Align(2)), -10);
+ ASSERT_EQ(Info.AllocateStack(2, Align(1)), -12);
+ ASSERT_EQ(Info.AllocateStack(1, Align(1)), -13);
+ ASSERT_EQ(Info.getStackSize(), 13u);
+ ASSERT_EQ(Info.getAlignedCallFrameSize(), 14u);
+}
+
+} // namespace
diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
index a559e35f1219..a4d761bee5a4 100644
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -21,6 +21,7 @@ add_llvm_unittest(CodeGenTests
AllocationOrderTest.cpp
AMDGPUMetadataTest.cpp
AsmPrinterDwarfTest.cpp
+ CCStateTest.cpp
DIEHashTest.cpp
DIETest.cpp
DwarfStringPoolEntryRefTest.cpp
diff --git a/llvm/utils/TableGen/CallingConvEmitter.cpp b/llvm/utils/TableGen/CallingConvEmitter.cpp
index 8e6b40e6cd20..de3810b2e227 100644
--- a/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -251,7 +251,7 @@ void CallingConvEmitter::EmitAction(Record *Action,
int Size = Action->getValueAsInt("Size");
int Align = Action->getValueAsInt("Align");
- O << IndentStr << "unsigned Offset" << ++Counter
+ O << IndentStr << "int64_t Offset" << ++Counter
<< " = State.AllocateStack(";
if (Size)
O << Size << ", ";
@@ -287,7 +287,7 @@ void CallingConvEmitter::EmitAction(Record *Action,
O << LS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
O << "\n" << IndentStr << "};\n";
- O << IndentStr << "unsigned Offset" << ++Counter
+ O << IndentStr << "int64_t Offset" << ++Counter
<< " = State.AllocateStack(" << Size << ", Align(" << Align << "), "
<< "ShadowRegList" << ShadowRegListNumber << ");\n";
O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"