[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