Index: lib/Target/SystemZ/SystemZFrameLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZFrameLowering.cpp +++ lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -97,6 +97,17 @@ if (MFFrame.hasCalls()) SavedRegs.set(SystemZ::R14D); + // With interprocedural register allocation, saving the CSRs may be skipped + // by TargetFrameLowering if it is considered safe. Make sure in that case + // that the FP and return registers are always restored if clobbered. + if (MF.getTarget().Options.EnableIPRA) { + const MachineRegisterInfo &MRI = MF.getRegInfo(); + if (MRI.isPhysRegModified(SystemZ::R11D)) + SavedRegs.set(SystemZ::R11D); + if (MRI.isPhysRegModified(SystemZ::R14D)) + SavedRegs.set(SystemZ::R14D); + } + // If we are saving GPRs other than the stack pointer, we might as well // save and restore the stack pointer at the same time, via STMG and LMG. // This allows the deallocation to be done by the LMG, rather than needing Index: test/CodeGen/SystemZ/ipra-02.ll =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/ipra-02.ll @@ -0,0 +1,128 @@ +; Test that the return register is saved and restored even when the saving of +; Callee Saved Registers is skipped with interprocedural register allocation. +; +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -enable-ipra < %s \ +; RUN: | FileCheck %s +; +; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -enable-ipra \ +; RUN: -debug-only=ip-regalloc 2>&1 < %s | FileCheck --check-prefix=DBG %s +; + +; DBG: fun3 function optimized for not having CSR +; CHECK-LABEL: fun3 +; CHECK: stmg %r14, %r15, 112(%r15) +; CHECK: lr %r14 +; CHECK: a %r14 +; CHECK: lmg %r14, %r15, 112(%r15) +; CHECK: br %r14 + + +@board = external dso_local local_unnamed_addr global [421 x i8], align 2 +@delta = external dso_local local_unnamed_addr global [8 x i32], align 4 + +; Function Attrs: nounwind +define internal fastcc signext i32 @fun0(i32 signext, i32*, i32 signext, i32 signext) unnamed_addr #0 { + br i1 undef, label %5, label %6 + +;