diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZFRAMELOWERING_H +#include "MCTargetDesc/SystemZMCTargetDesc.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/Support/TypeSize.h" @@ -63,6 +64,12 @@ int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const; bool usePackedStack(MachineFunction &MF) const; + + // Return the offset of the backchain. + unsigned getBackchainOffset(MachineFunction &MF) const { + // The back chain is stored topmost with packed-stack. + return usePackedStack(MF) ? SystemZMC::CallFrameSize - 8 : 0; + } }; } // end namespace llvm diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -511,13 +511,10 @@ .addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D); emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII); buildCFAOffs(MBB, MBBI, DL, SPOffsetFromCFA + Delta, ZII); - if (StoreBackchain) { - // The back chain is stored topmost with packed-stack. - int Offset = usePackedStack(MF) ? SystemZMC::CallFrameSize - 8 : 0; + if (StoreBackchain) BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG)) .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D) - .addImm(Offset).addReg(0); - } + .addImm(getBackchainOffset(MF)).addReg(0); } SPOffsetFromCFA += Delta; } @@ -709,13 +706,10 @@ if (Residual) allocateAndProbe(*MBB, MBBI, Residual, true/*EmitCFI*/); - if (StoreBackchain) { - // The back chain is stored topmost with packed-stack. - int Offset = usePackedStack(MF) ? SystemZMC::CallFrameSize - 8 : 0; + if (StoreBackchain) BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::STG)) .addReg(SystemZ::R1D, RegState::Kill).addReg(SystemZ::R15D) - .addImm(Offset).addReg(0); - } + .addImm(getBackchainOffset(MF)).addReg(0); StackAllocMI->eraseFromParent(); if (DoneMBB != nullptr) { @@ -790,8 +784,7 @@ int FI = ZFI->getFramePointerSaveIndex(); if (!FI) { MachineFrameInfo &MFFrame = MF.getFrameInfo(); - // The back chain is stored topmost with packed-stack. - int Offset = usePackedStack(MF) ? -8 : -SystemZMC::CallFrameSize; + int Offset = getBackchainOffset(MF) - SystemZMC::CallFrameSize; FI = MFFrame.CreateFixedObject(8, Offset, false); ZFI->setFramePointerSaveIndex(FI); } diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.h b/llvm/lib/Target/SystemZ/SystemZISelLowering.h --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.h +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.h @@ -698,6 +698,8 @@ MachineBasicBlock *emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const; + SDValue getBackchainAddress(SDValue SP, SelectionDAG &DAG) const; + MachineMemOperand::Flags getTargetMMOFlags(const Instruction &I) const override; const TargetRegisterClass *getRepRegClassFor(MVT VT) const override; diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -3435,7 +3435,8 @@ // If we need a backchain, save it now. SDValue Backchain; if (StoreBackchain) - Backchain = DAG.getLoad(MVT::i64, DL, Chain, OldSP, MachinePointerInfo()); + Backchain = DAG.getLoad(MVT::i64, DL, Chain, getBackchainAddress(OldSP, DAG), + MachinePointerInfo()); // Add extra space for alignment if needed. if (ExtraAlignSpace) @@ -3472,7 +3473,8 @@ } if (StoreBackchain) - Chain = DAG.getStore(Chain, DL, Backchain, NewSP, MachinePointerInfo()); + Chain = DAG.getStore(Chain, DL, Backchain, getBackchainAddress(NewSP, DAG), + MachinePointerInfo()); SDValue Ops[2] = { Result, Chain }; return DAG.getMergeValues(Ops, DL); @@ -4095,13 +4097,15 @@ if (StoreBackchain) { SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SystemZ::R15D, MVT::i64); - Backchain = DAG.getLoad(MVT::i64, DL, Chain, OldSP, MachinePointerInfo()); + Backchain = DAG.getLoad(MVT::i64, DL, Chain, getBackchainAddress(OldSP, DAG), + MachinePointerInfo()); } Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R15D, NewSP); if (StoreBackchain) - Chain = DAG.getStore(Chain, DL, Backchain, NewSP, MachinePointerInfo()); + Chain = DAG.getStore(Chain, DL, Backchain, getBackchainAddress(NewSP, DAG), + MachinePointerInfo()); return Chain; } @@ -8144,6 +8148,16 @@ return DoneMBB; } +SDValue SystemZTargetLowering:: +getBackchainAddress(SDValue SP, SelectionDAG &DAG) const { + MachineFunction &MF = DAG.getMachineFunction(); + auto *TFL = + static_cast(Subtarget.getFrameLowering()); + SDLoc DL(SP); + return DAG.getNode(ISD::ADD, DL, MVT::i64, SP, + DAG.getIntPtrConstant(TFL->getBackchainOffset(MF), DL)); +} + MachineBasicBlock *SystemZTargetLowering::EmitInstrWithCustomInserter( MachineInstr &MI, MachineBasicBlock *MBB) const { switch (MI.getOpcode()) { diff --git a/llvm/test/CodeGen/SystemZ/backchain.ll b/llvm/test/CodeGen/SystemZ/backchain.ll --- a/llvm/test/CodeGen/SystemZ/backchain.ll +++ b/llvm/test/CodeGen/SystemZ/backchain.ll @@ -82,3 +82,36 @@ store volatile i8 0, i8 *%array2 ret void } + +; same, but with the kernel backchain +define void @f6(i32 %count1, i32 %count2) #0 { +; CHECK-LABEL: f6: +; CHECK: stmg %r11, %r15, 112(%r15) +; CHECK: lgr %r1, %r15 +; CHECK: aghi %r15, -48 +; CHECK: stg %r1, 152(%r15) +; CHECK: lgr %r11, %r15 +; CHECK-DAG: lgr [[SAVESP:%r[0-9]+]], %r15 +; CHECK-DAG: lg [[BC:%r[0-9]+]], 152(%r15) +; CHECK-DAG: lgr [[NEWSP:%r[0-9]+]], %r15 +; CHECK-DAG: lgr %r15, [[NEWSP]] +; CHECK-DAG: stg [[BC]], 152([[NEWSP]]) +; CHECK-DAG: lg [[BC2:%r[0-9]+]], 152(%r15) +; CHECK-DAG: lgr %r15, [[SAVESP]] +; CHECK-DAG: stg [[BC2]], 152([[SAVESP]]) +; CHECK-DAG: lg [[BC3:%r[0-9]+]], 152(%r15) +; CHECK-DAG: lgr [[NEWSP2:%r[0-9]+]], %r15 +; CHECK-DAG: lgr %r15, [[NEWSP2]] +; CHECK-DAG: stg [[BC3]], 152([[NEWSP2]]) +; CHECK: lmg %r11, %r15, 160(%r11) +; CHECK: br %r14 + %src = call i8 *@llvm.stacksave() + %array1 = alloca i8, i32 %count1 + store volatile i8 0, i8 *%array1 + call void @llvm.stackrestore(i8 *%src) + %array2 = alloca i8, i32 %count2 + store volatile i8 0, i8 *%array2 + ret void +} + +attributes #0 = { "backchain" "packed-stack" "use-soft-float"="true" }