Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp.orig
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -1035,6 +1035,85 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr
       return;
     }
   }
+  case PPC::RETGUARD_LOAD_PC: {
+    unsigned DEST = MI->getOperand(0).getReg();
+    unsigned LR  = MI->getOperand(1).getReg();
+    MCSymbol *HereSym = MI->getOperand(2).getMCSymbol();
+
+    unsigned MTLR = PPC::MTLR;
+    unsigned MFLR = PPC::MFLR;
+    unsigned BL   = PPC::BL;
+    if (Subtarget->isPPC64()) {
+      MTLR = PPC::MTLR8;
+      MFLR = PPC::MFLR8;
+      BL   = PPC::BL8;
+    }
+
+    // Cache the current LR
+    EmitToStreamer(*OutStreamer, MCInstBuilder(MFLR)
+                                 .addReg(LR));
+
+    // Create the BL forward
+    const MCExpr *HereExpr = MCSymbolRefExpr::create(HereSym, OutContext);
+    EmitToStreamer(*OutStreamer, MCInstBuilder(BL)
+                                 .addExpr(HereExpr));
+    OutStreamer->emitLabel(HereSym);
+
+    // Grab the result
+    EmitToStreamer(*OutStreamer, MCInstBuilder(MFLR)
+                                 .addReg(DEST));
+    // Restore LR
+    EmitToStreamer(*OutStreamer, MCInstBuilder(MTLR)
+                                 .addReg(LR));
+    return;
+  }
+  case PPC::RETGUARD_LOAD_GOT: {
+    if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
+      StringRef GOTName = (PL == PICLevel::SmallPIC ?
+                                 "_GLOBAL_OFFSET_TABLE_" : ".LTOC");
+      unsigned DEST     = MI->getOperand(0).getReg();
+      unsigned HERE     = MI->getOperand(1).getReg();
+      MCSymbol *HereSym = MI->getOperand(2).getMCSymbol();
+      MCSymbol *GOTSym  = OutContext.getOrCreateSymbol(GOTName);
+      const MCExpr *HereExpr = MCSymbolRefExpr::create(HereSym, OutContext);
+      const MCExpr *GOTExpr  = MCSymbolRefExpr::create(GOTSym, OutContext);
+
+      // Get offset from Here to GOT
+      const MCExpr *GOTDeltaExpr =
+        MCBinaryExpr::createSub(GOTExpr, HereExpr, OutContext);
+      const MCExpr *GOTDeltaHi =
+        MCSpecifierExpr::create(GOTDeltaExpr, PPC::S_HA, OutContext);
+      const MCExpr *GOTDeltaLo =
+        MCSpecifierExpr::create(GOTDeltaExpr, PPC::S_LO, OutContext);
+
+      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
+                                   .addReg(DEST)
+                                   .addReg(HERE)
+                                   .addExpr(GOTDeltaHi));
+      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
+                                   .addReg(DEST)
+                                   .addReg(DEST)
+                                   .addExpr(GOTDeltaLo));
+    }
+    return;
+  }
+  case PPC::RETGUARD_LOAD_COOKIE: {
+    unsigned DEST       = MI->getOperand(0).getReg();
+    MCSymbol *CookieSym = getSymbol(MI->getOperand(1).getGlobal());
+    const MCExpr *CookieExprHa = MCSymbolRefExpr::create(
+        CookieSym, PPC::S_HIGHA, OutContext);
+    const MCExpr *CookieExprLo = MCSymbolRefExpr::create(
+        CookieSym, PPC::S_LO, OutContext);
+
+    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LIS)
+                                 .addReg(DEST)
+                                 .addExpr(CookieExprHa));
+    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
+                                 .addReg(DEST)
+                                 .addExpr(CookieExprLo)
+                                 .addReg(DEST));
+    return;
+  }
   case PPC::LWZtoc: {
     // Transform %rN = LWZtoc @op1, %r2
     LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
