aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
diff options
context:
space:
mode:
authorNeumann Hon <neumann.hon@ibm.com>2023-05-11 21:25:05 -0400
committerNeumann Hon <neumann.hon@ibm.com>2023-05-11 21:25:05 -0400
commit1aec3d15aaa25c39fae026688708d7353d488974 (patch)
tree801d2499c2243088c5227314fdd828742c0495b5 /llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
parentc2f0c204d1847fac9f8d47c06a40cecd717a546d (diff)
downloadllvm-1aec3d15aaa25c39fae026688708d7353d488974.zip
llvm-1aec3d15aaa25c39fae026688708d7353d488974.tar.gz
llvm-1aec3d15aaa25c39fae026688708d7353d488974.tar.bz2
[SystemZ][z/OS] Save (and restore) R3 to avoid clobbering parameter when call stack frame extension is invoked
When the stack frame extension routine is used, the contents of r3 is overwritten. However, if r3 is live in the prologue (ie. one of the function's parameters resides in r3), it needs to be saved. We save r3 in r0 if r0 is available (ie. r0 is not used as temporary storage for r4), and in the corresponding stack slot for the third parameter otherwise. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D150332
Diffstat (limited to 'llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp46
1 files changed, 45 insertions, 1 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index d7a2a51..ba6458f 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -1315,6 +1315,10 @@ void SystemZXPLINKFrameLowering::inlineStackProbe(
if (StackAllocMI == nullptr)
return;
+ bool NeedSaveSP = hasFP(MF);
+ bool NeedSaveArg = PrologMBB.isLiveIn(SystemZ::R3D);
+ const int64_t SaveSlotR3 = 2192;
+
MachineBasicBlock &MBB = PrologMBB;
const DebugLoc DL = StackAllocMI->getDebugLoc();
@@ -1334,7 +1338,25 @@ void SystemZXPLINKFrameLowering::inlineStackProbe(
// BASR r3,r3
BuildMI(StackExtMBB, DL, ZII->get(SystemZ::CallBASR_STACKEXT))
.addReg(SystemZ::R3D);
-
+ if (NeedSaveArg) {
+ if (!NeedSaveSP) {
+ // LGR r0,r3
+ BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::LGR))
+ .addReg(SystemZ::R0D, RegState::Define)
+ .addReg(SystemZ::R3D);
+ } else {
+ // In this case, the incoming value of r4 is saved in r0 so the
+ // latter register is unavailable. Store r3 in its corresponding
+ // slot in the parameter list instead. Do this at the start of
+ // the prolog before r4 is manipulated by anything else.
+ // STG r3, 2192(r4)
+ BuildMI(MBB, MBB.begin(), DL, ZII->get(SystemZ::STG))
+ .addReg(SystemZ::R3D)
+ .addReg(SystemZ::R4D)
+ .addImm(SaveSlotR3)
+ .addReg(0);
+ }
+ }
// LLGT r3,1208
BuildMI(MBB, StackAllocMI, DL, ZII->get(SystemZ::LLGT), SystemZ::R3D)
.addReg(0)
@@ -1355,6 +1377,28 @@ void SystemZXPLINKFrameLowering::inlineStackProbe(
NextMBB = SystemZ::splitBlockBefore(StackAllocMI, &MBB);
MBB.addSuccessor(NextMBB);
MBB.addSuccessor(StackExtMBB);
+ if (NeedSaveArg) {
+ if (!NeedSaveSP) {
+ // LGR r3, r0
+ BuildMI(*NextMBB, StackAllocMI, DL, ZII->get(SystemZ::LGR))
+ .addReg(SystemZ::R3D, RegState::Define)
+ .addReg(SystemZ::R0D, RegState::Kill);
+ } else {
+ // In this case, the incoming value of r4 is saved in r0 so the
+ // latter register is unavailable. We stored r3 in its corresponding
+ // slot in the parameter list instead and we now restore it from there.
+ // LGR r3, r0
+ BuildMI(*NextMBB, StackAllocMI, DL, ZII->get(SystemZ::LGR))
+ .addReg(SystemZ::R3D)
+ .addReg(SystemZ::R0D);
+ // LG r3, 2192(r3)
+ BuildMI(*NextMBB, StackAllocMI, DL, ZII->get(SystemZ::LG))
+ .addReg(SystemZ::R3D, RegState::Define)
+ .addReg(SystemZ::R3D)
+ .addImm(SaveSlotR3)
+ .addReg(0);
+ }
+ }
// Add jump back from stack extension BB.
BuildMI(StackExtMBB, DL, ZII->get(SystemZ::J)).addMBB(NextMBB);