diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp --- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp @@ -1501,6 +1501,7 @@ const GCNSubtarget &ST = MF.getSubtarget(); const SIRegisterInfo *TRI = ST.getRegisterInfo(); + MachineInstr *ReturnMI = nullptr; for (MachineBasicBlock &MBB : MF) { for (MachineInstr &MI : MBB) { // WRITELANE instructions used for SGPR spills can overwrite the inactive @@ -1517,6 +1518,19 @@ MFI->allocateWWMSpill(MF, MI.getOperand(0).getReg()); else if (MI.getOpcode() == AMDGPU::V_READLANE_B32) MFI->allocateWWMSpill(MF, MI.getOperand(1).getReg()); + else if (MI.getOpcode() == AMDGPU::SI_RETURN || + MI.getOpcode() == AMDGPU::SI_RETURN_TO_EPILOG) + ReturnMI = &MI; + } + } + + // Remove any VGPRs used in the return value these do not need to be saved. + // This prevents CSR restore from clobbering return VGPRs. + // Note: this assumes all return instructions are of equal. + if (ReturnMI) { + for (auto &Op : ReturnMI->operands()) { + if (Op.isReg()) + SavedVGPRs.reset(Op.getReg()); } }