summaryrefslogtreecommitdiff
path: root/test/CodeGen/SystemZ
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2017-06-26 16:50:32 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2017-06-26 16:50:32 +0000
commit18f8cae766887153fd96bdffb5c4e289973d8369 (patch)
tree858411e08a9faba722e364f6c34e51b4c3a4ab54 /test/CodeGen/SystemZ
parent575411ebf86ac8f8c1162626cc2115c5426026a8 (diff)
[SystemZ] Fix missing emergency spill slot corner case
We sometimes need emergency spill slots for the register scavenger. This may be the case when code needs to access a stack slot that has an offset of 4096 or more relative to the stack pointer. To make that determination, processFunctionBeforeFrameFinalized currently simply checks the total stack frame size of the current function. But this is not enough, since code may need to access stack slots in the caller's stack frame as well, in particular incoming arguments stored on the stack. This commit fixes the problem by taking argument slots into account. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306305 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/SystemZ')
-rw-r--r--test/CodeGen/SystemZ/frame-21.ll76
1 files changed, 76 insertions, 0 deletions
diff --git a/test/CodeGen/SystemZ/frame-21.ll b/test/CodeGen/SystemZ/frame-21.ll
new file mode 100644
index 00000000000..360740028a9
--- /dev/null
+++ b/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
+}
+