From e256ab847b7621f67e3d24a62e72d493ab7b6d32 Mon Sep 17 00:00:00 2001 From: Momchil Velikov Date: Tue, 17 Apr 2018 08:37:38 +0000 Subject: [PATCH] Fix incorrect choice of callee-saved registers save/restore points Make the shrink wrapping pass pay attention to uses/defs of the stack pointer. Differential revision: https://reviews.llvm.org/D45524 llvm-svn: 330183 --- llvm/lib/CodeGen/ShrinkWrap.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/ShrinkWrap.cpp b/llvm/lib/CodeGen/ShrinkWrap.cpp index eead5f8c1394..e20233917e32 100644 --- a/llvm/lib/CodeGen/ShrinkWrap.cpp +++ b/llvm/lib/CodeGen/ShrinkWrap.cpp @@ -68,6 +68,7 @@ #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/CodeGen/TargetFrameLowering.h" #include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetLowering.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Attributes.h" @@ -138,6 +139,9 @@ class ShrinkWrap : public MachineFunctionPass { /// Current opcode for frame destroy. unsigned FrameDestroyOpcode; + /// Stack pointer register, used by llvm.{savestack,restorestack} + unsigned SP; + /// Entry block. const MachineBasicBlock *Entry; @@ -186,9 +190,11 @@ class ShrinkWrap : public MachineFunctionPass { MBFI = &getAnalysis(); MLI = &getAnalysis(); EntryFreq = MBFI->getEntryFreq(); - const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); + const TargetSubtargetInfo &Subtarget = MF.getSubtarget(); + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); FrameSetupOpcode = TII.getCallFrameSetupOpcode(); FrameDestroyOpcode = TII.getCallFrameDestroyOpcode(); + SP = Subtarget.getTargetLowering()->getStackPointerRegisterToSaveRestore(); Entry = &MF.front(); CurrentCSRs.clear(); MachineFunc = &MF; @@ -262,7 +268,13 @@ bool ShrinkWrap::useOrDefCSROrFI(const MachineInstr &MI, continue; assert(TargetRegisterInfo::isPhysicalRegister(PhysReg) && "Unallocated register?!"); - UseOrDefCSR = RCI.getLastCalleeSavedAlias(PhysReg); + // The stack pointer is not normally described as a callee-saved register + // in calling convention definitions, so we need to watch for it + // separately. An SP mentioned by a call instruction, we can ignore, + // though, as it's harmless and we do not want to effectively disable tail + // calls by forcing the restore point to post-dominate them. + UseOrDefCSR = (!MI.isCall() && PhysReg == SP) || + RCI.getLastCalleeSavedAlias(PhysReg); } else if (MO.isRegMask()) { // Check if this regmask clobbers any of the CSRs. for (unsigned Reg : getCurrentCSRs(RS)) {