summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index fa20977ec018..a769fdeff568 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -1475,6 +1475,28 @@ void SystemZXPLINKFrameLowering::processFunctionBeforeFrameFinalized(
// with existing compilers.
MFFrame.setMaxCallFrameSize(
std::max(64U, (unsigned)alignTo(MFFrame.getMaxCallFrameSize(), 64)));
+
+ // Add frame values with positive object offsets. Since the displacement from
+ // the SP/FP is calculated by ObjectOffset + StackSize + Bias, object offsets
+ // with positive values are in the caller's stack frame. We need to include
+ // that since it is accessed by displacement to SP/FP.
+ int64_t LargestArgOffset = 0;
+ for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I) {
+ if (MFFrame.getObjectOffset(I) >= 0) {
+ int64_t ObjOffset = MFFrame.getObjectOffset(I) + MFFrame.getObjectSize(I);
+ LargestArgOffset = std::max(ObjOffset, LargestArgOffset);
+ }
+ }
+
+ uint64_t MaxReach = (StackSize + Regs.getCallFrameSize() +
+ Regs.getStackPointerBias() + LargestArgOffset);
+
+ if (!isUInt<12>(MaxReach)) {
+ // We may need register scavenging slots if some parts of the frame
+ // are outside the reach of an unsigned 12-bit displacement.
+ RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false));
+ RS->addScavengingFrameIndex(MFFrame.CreateStackObject(8, Align(8), false));
+ }
}
// Determines the size of the frame, and creates the deferred spill objects.