diff options
-rw-r--r-- | llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp | 17 | ||||
-rw-r--r-- | llvm/test/CodeGen/SystemZ/frame-21.ll | 76 |
2 files changed, 91 insertions, 2 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index a28a91e834f..0cb2b5a14ce 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -277,8 +277,21 @@ void SystemZFrameLowering:: processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const { MachineFrameInfo &MFFrame = MF.getFrameInfo(); - uint64_t MaxReach = (MFFrame.estimateStackSize(MF) + - SystemZMC::CallFrameSize * 2); + // Get the size of our stack frame to be allocated ... + uint64_t StackSize = (MFFrame.estimateStackSize(MF) + + SystemZMC::CallFrameSize); + // ... and the maximum offset we may need to reach into the + // caller's frame to access the save area or stack arguments. + int64_t MaxArgOffset = SystemZMC::CallFrameSize; + for (int I = MFFrame.getObjectIndexBegin(); I != 0; ++I) + if (MFFrame.getObjectOffset(I) >= 0) { + int64_t ArgOffset = SystemZMC::CallFrameSize + + MFFrame.getObjectOffset(I) + + MFFrame.getObjectSize(I); + MaxArgOffset = std::max(MaxArgOffset, ArgOffset); + } + + uint64_t MaxReach = StackSize + MaxArgOffset; 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. diff --git a/llvm/test/CodeGen/SystemZ/frame-21.ll b/llvm/test/CodeGen/SystemZ/frame-21.ll new file mode 100644 index 00000000000..360740028a9 --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/frame-21.ll @@ -0,0 +1,76 @@ +; Test the allocation of emergency spill slots. +; +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +; For frames of size less than 4096 - 2*160, no emercengy spill slot +; is required. Check the maximum such case. +define void @f1(i64 %x) { +; CHECK-LABEL: f1: +; CHECK: stg %r2, 160(%r15) +; CHECK: br %r14 + %y = alloca [471 x i64], align 8 + %ptr = getelementptr inbounds [471 x i64], [471 x i64]* %y, i64 0, i64 0 + store volatile i64 %x, i64* %ptr + ret void +} + +; If the frame size is at least 4096 - 2*160, we do need the emergency +; spill slots. Check the minimum such case. +define void @f2(i64 %x) { +; CHECK-LABEL: f2: +; CHECK: stg %r2, 176(%r15) +; CHECK: br %r14 + %y = alloca [472 x i64], align 8 + %ptr = getelementptr inbounds [472 x i64], [472 x i64]* %y, i64 0, i64 0 + store volatile i64 %x, i64* %ptr + ret void +} + +; However, if there are incoming stack arguments, those also need to be +; in reach, so the maximum frame size without emergency spill slots is +; 4096 - 2*160 - <size of incoming stack arguments>. Check the maximum +; case where we still need no emergency spill slots ... +define void @f3(i64 %x, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64 %stack) { +; CHECK-LABEL: f3: +; CHECK: stg %r2, 160(%r15) +; CHECK: br %r14 + %y = alloca [470 x i64], align 8 + %ptr = getelementptr inbounds [470 x i64], [470 x i64]* %y, i64 0, i64 0 + store volatile i64 %x, i64* %ptr + ret void +} + +; ... and the minimum case where we do. +define void @f4(i64 %x, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64 %stack) { +; CHECK-LABEL: f4: +; CHECK: stg %r2, 176(%r15) +; CHECK: br %r14 + %y = alloca [471 x i64], align 8 + %ptr = getelementptr inbounds [471 x i64], [471 x i64]* %y, i64 0, i64 0 + store volatile i64 %x, i64* %ptr + ret void +} + +; Try again for the case of two stack arguments. +; Check the maximum case where we still need no emergency spill slots ... +define void @f5(i64 %x, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64 %stack1, i64 %stack2) { +; CHECK-LABEL: f5: +; CHECK: stg %r2, 160(%r15) +; CHECK: br %r14 + %y = alloca [469 x i64], align 8 + %ptr = getelementptr inbounds [469 x i64], [469 x i64]* %y, i64 0, i64 0 + store volatile i64 %x, i64* %ptr + ret void +} + +; ... and the minimum case where we do. +define void @f6(i64 %x, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64 %stack1, i64 %stack2) { +; CHECK-LABEL: f6: +; CHECK: stg %r2, 176(%r15) +; CHECK: br %r14 + %y = alloca [470 x i64], align 8 + %ptr = getelementptr inbounds [470 x i64], [470 x i64]* %y, i64 0, i64 0 + store volatile i64 %x, i64* %ptr + ret void +} + |