[llvm] [SystemZ] Address issue with supper large stack frames (PR #96318)
Zibi Sarbinowski via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 21 11:40:45 PDT 2024
https://github.com/zibi2 updated https://github.com/llvm/llvm-project/pull/96318
>From be3b9cdded89b452d4d74623f0c68dbeb359b51e Mon Sep 17 00:00:00 2001
From: Zbigniew Sarbinowski <zibi at ca.ibm.com>
Date: Fri, 21 Jun 2024 15:01:40 +0000
Subject: [PATCH 1/2] Address issue with supper large stack frames on
achitecture SystemZ
---
.../Target/SystemZ/SystemZFrameLowering.cpp | 22 ++++++++++
.../SystemZ/systemz-large-stack-frames.ll | 42 +++++++++++++++++++
2 files changed, 64 insertions(+)
create mode 100644 llvm/test/CodeGen/SystemZ/systemz-large-stack-frames.ll
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index fa20977ec0187..a769fdeff5684 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.
diff --git a/llvm/test/CodeGen/SystemZ/systemz-large-stack-frames.ll b/llvm/test/CodeGen/SystemZ/systemz-large-stack-frames.ll
new file mode 100644
index 0000000000000..51997a6c17c65
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/systemz-large-stack-frames.ll
@@ -0,0 +1,42 @@
+; REQUIRES: asserts
+; REQUIRES: systemz-registered-target
+; Used to fail with: LLVM ERROR: Error while trying to spill R5D from class ADDR64Bit: Cannot scavenge register without an emergency spill slot!
+
+
+; RUN: llc %s --mtriple s390x-ibm-zos -filetype obj -o %t
+
+; ModuleID = 'main.cpp'
+source_filename = "main.cpp"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; ModuleID = 'large-stack-frames.cpp'
+source_filename = "large-stack-frames.cpp"
+target datalayout = "E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
+target triple = "s390x-ibm-zos"
+%struct.slice.108 = type { ptr, ptr, [8 x i64], [8 x i64], [8 x i64] }
+declare void @dealloc(ptr) local_unnamed_addr #0
+define internal void @foo([26 x i64] %co1, [26 x i64] %co2, [26 x i64] %co3, [26 x i64] %co4, [26 x i64] %co5, [26 x i64] %co6, [26 x i64] %co7, [26 x i64] %co8, i32 %skip_dispatch, ptr %0, i1 %1) #0 {
+entry:
+ %ref.tmp = alloca %struct.slice.108, align 8
+ br i1 %1, label %error, label %if.end95
+if.end95:
+ br i1 %1, label %if.else.i1546, label %object.exit1547
+if.else.i1546:
+ tail call void @dealloc(ptr noundef nonnull %0)
+ br label %object.exit1547
+object.exit1547:
+ %call96 = tail call fastcc noundef ptr @slice([26 x i64] inreg %co7, i32 noundef signext 1, ptr noundef nonnull @get_float, ptr noundef nonnull @object, i32 noundef signext 0)
+ ret void
+error:
+ ret void
+}
+declare dso_local fastcc ptr @slice([26 x i64], i32, ptr, ptr, i32) unnamed_addr #0
+define internal ptr @get_float(ptr %itemp, ptr %2) #0 {
+entry:
+ ret ptr %2
+}
+define internal i32 @object(ptr %itemp, ptr %obj) #0 {
+entry:
+ ret i32 1
+}
>From e4151fee8ed6b9804e168a4ed58d27a69dfab084 Mon Sep 17 00:00:00 2001
From: Zbigniew Sarbinowski <zibi at ca.ibm.com>
Date: Fri, 21 Jun 2024 18:47:29 +0000
Subject: [PATCH 2/2] Adjust LIT for larger DSA Size 0x1000e0
---
llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll b/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll
index d3e5823fcb1fe..3a8e3a35e2ef7 100644
--- a/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll
+++ b/llvm/test/CodeGen/SystemZ/zos-prologue-epilog.ll
@@ -303,7 +303,7 @@ define i64 @func4(i64 %n) {
; Require saving of r4 and in addition, a displacement large enough
; to force use of agfi before stmg.
; CHECK64: lgr 0, 4
-; CHECK64: agfi 4, -1040192
+; CHECK64: agfi 4, -1040224
; CHECK64: stmg 4, 10, 2048(4)
; CHECK64: lgr 8, 4
; CHECK64: basr 7, 6
@@ -317,7 +317,7 @@ define i64 @func5(i64 %n) {
}
; CHECK-LABEL: large_stack
-; CHECK64: agfi 4, -1048768
+; CHECK64: agfi 4, -1048800
; CHECK64-NEXT: llgt 3, 1208
; CHECK64-NEXT: cg 4, 64(3)
; CHECK64-NEXT: jhe
@@ -332,7 +332,7 @@ define void @large_stack0() {
}
; CHECK-LABEL: large_stack1
-; CHECK64: agfi 4, -1048768
+; CHECK64: agfi 4, -1048800
; CHECK64: lgr 0, 3
; CHECK64: llgt 3, 1208
; CHECK64: cg 4, 64(3)
@@ -358,7 +358,7 @@ define void @large_stack1(i64 %n1, i64 %n2, i64 %n3) {
; CHECK-LABEL: large_stack2
; CHECK64: lgr 0, 4
; CHECK64: stg 3, 2192(4)
-; CHECK64: agfi 4, -1048768
+; CHECK64: agfi 4, -1048800
; CHECK64: llgt 3, 1208
; CHECK64: cg 4, 64(3)
; CHECK64: jhe L#BB8_2
More information about the llvm-commits
mailing list