Index: llvm/lib/CodeGen/PrologEpilogInserter.cpp
--- llvm/lib/CodeGen/PrologEpilogInserter.cpp.orig
+++ llvm/lib/CodeGen/PrologEpilogInserter.cpp
@@ -223,7 +223,11 @@ bool PEIImpl::run(MachineFunction &MF) {
   const Function &F = MF.getFunction();
   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
+  const ReturnProtectorLowering *RPL = TFI->getReturnProtector();
 
+  if (RPL)
+      RPL->setupReturnProtector(MF);
+
   RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : nullptr;
   FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(MF);
 
@@ -264,6 +268,10 @@ bool PEIImpl::run(MachineFunction &MF) {
   if (!F.hasFnAttribute(Attribute::Naked))
     insertPrologEpilogCode(MF);
 
+  // Add Return Protectors if using them
+  if (RPL)
+      RPL->insertReturnProtectors(MF);
+
   // Reinsert stashed debug values at the start of the entry blocks.
   for (auto &I : EntryDbgValues)
     I.first->insert(I.first->begin(), I.second.begin(), I.second.end());
@@ -422,7 +430,9 @@ void PEIImpl::calculateCallFrameInfo(MachineFunction &
 /// Compute the sets of entry and return blocks for saving and restoring
 /// callee-saved registers, and placing prolog and epilog code.
 void PEIImpl::calculateSaveRestoreBlocks(MachineFunction &MF) {
-  const MachineFrameInfo &MFI = MF.getFrameInfo();
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
+  const ReturnProtectorLowering *RPL = TFI->getReturnProtector();
 
   // Even when we do not change any CSR, we still want to insert the
   // prologue and epilogue of the function.
@@ -438,7 +448,18 @@ void PEIImpl::calculateSaveRestoreBlocks(MachineFuncti
     // epilogue.
     if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
       RestoreBlocks.push_back(RestoreBlock);
-    return;
+
+    // If we are adding return protectors ensure we can find a free register
+    if (RPL &&
+       !RPL->determineReturnProtectorRegister(MF, SaveBlocks, RestoreBlocks)) {
+      // Shrinkwrapping will prevent finding a free register
+      SaveBlocks.clear();
+      RestoreBlocks.clear();
+      MFI.setSavePoint(nullptr);
+      MFI.setRestorePoint(nullptr);
+    } else {
+      return;
+    }
   }
 
   // Save refs to entry and return blocks.
@@ -449,6 +470,9 @@ void PEIImpl::calculateSaveRestoreBlocks(MachineFuncti
     if (MBB.isReturnBlock())
       RestoreBlocks.push_back(&MBB);
   }
+
+  if (RPL)
+    RPL->determineReturnProtectorRegister(MF, SaveBlocks, RestoreBlocks);
 }
 
 static void assignCalleeSavedSpillSlots(MachineFunction &F,
@@ -486,6 +510,10 @@ static void assignCalleeSavedSpillSlots(MachineFunctio
 
   const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
   MachineFrameInfo &MFI = F.getFrameInfo();
+
+  if (TFI->getReturnProtector())
+      TFI->getReturnProtector()->saveReturnProtectorRegister(F, CSI);
+
   if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI, MinCSFrameIndex,
                                         MaxCSFrameIndex)) {
     // If target doesn't implement this, use generic code.
@@ -1329,6 +1357,15 @@ void PEIImpl::insertZeroCallUsedRegs(MachineFunction &
        MCPhysReg CSReg = *CSRegs; ++CSRegs)
     for (MCRegister Reg : TRI.sub_and_superregs_inclusive(CSReg))
       RegsToZero.reset(Reg.id());
+
+  // Don't touch the return protector register if it is used
+  const MachineFrameInfo &MFI = MF.getFrameInfo();
+  if (MFI.hasReturnProtectorRegister()) {
+    MCRegister RGReg = MCRegister(MFI.getReturnProtectorRegister());
+    for (MCRegister Reg : TRI.sub_and_superregs_inclusive(RGReg)) {
+      RegsToZero.reset(Reg);
+    }
+  }
 
   const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
   for (MachineBasicBlock &MBB : MF)
