Index: llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
===================================================================
--- llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
+++ llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
@@ -97,6 +97,7 @@
 #undef R_PPC64_DTPREL16_HIGH
 #undef R_PPC64_DTPREL16_HIGHA
 #undef R_PPC64_REL24_NOTOC
+#undef R_PPC64_PCREL34
 #undef R_PPC64_IRELATIVE
 #undef R_PPC64_REL16
 #undef R_PPC64_REL16_LO
@@ -192,6 +193,7 @@
 ELF_RELOC(R_PPC64_DTPREL16_HIGH,        114)
 ELF_RELOC(R_PPC64_DTPREL16_HIGHA,       115)
 ELF_RELOC(R_PPC64_REL24_NOTOC,          116)
+ELF_RELOC(R_PPC64_PCREL34,              132)
 ELF_RELOC(R_PPC64_IRELATIVE,            248)
 ELF_RELOC(R_PPC64_REL16,                249)
 ELF_RELOC(R_PPC64_REL16_LO,             250)
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -46,6 +46,8 @@
     return Value & 0xffff;
   case PPC::fixup_ppc_half16ds:
     return Value & 0xfffc;
+  case PPC::fixup_ppc_pcrel34:
+    return Value & 0x3ffffffff;
   }
 }
 
@@ -68,6 +70,7 @@
   case PPC::fixup_ppc_br24abs:
   case PPC::fixup_ppc_br24_notoc:
     return 4;
+  case PPC::fixup_ppc_pcrel34:
   case FK_Data_8:
     return 8;
   case PPC::fixup_ppc_nofixup:
@@ -99,6 +102,7 @@
       { "fixup_ppc_brcond14abs", 16,     14,   0 },
       { "fixup_ppc_half16",       0,     16,   0 },
       { "fixup_ppc_half16ds",     0,     14,   0 },
+      { "fixup_ppc_pcrel34",     0,      34,   MCFixupKindInfo::FKF_IsPCRel },
       { "fixup_ppc_nofixup",      0,      0,   0 }
     };
     const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = {
@@ -110,6 +114,7 @@
       { "fixup_ppc_brcond14abs", 2,      14,   0 },
       { "fixup_ppc_half16",      0,      16,   0 },
       { "fixup_ppc_half16ds",    2,      14,   0 },
+      { "fixup_ppc_pcrel34",     0,      34,   MCFixupKindInfo::FKF_IsPCRel },
       { "fixup_ppc_nofixup",     0,       0,   0 }
     };
 
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
@@ -127,6 +127,9 @@
       Target.print(errs());
       errs() << '\n';
       report_fatal_error("Invalid PC-relative half16ds relocation");
+    case PPC::fixup_ppc_pcrel34:
+      Type = ELF::R_PPC64_PCREL34;
+      break;
     case FK_Data_4:
     case FK_PCRel_4:
       Type = ELF::R_PPC_REL32;
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
@@ -40,6 +40,9 @@
   /// instrs like 'std'.
   fixup_ppc_half16ds,
 
+  // A 34-bit fixup corresponding to PC-relative paddi.
+  fixup_ppc_pcrel34,
+
   /// Not a true fixup, but ties a symbol to a call to __tls_get_addr for the
   /// TLS general and local dynamic models, or inserts the thread-pointer
   /// register number.
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -400,9 +400,13 @@
 
 void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo,
                                         raw_ostream &O) {
-  long long Value = MI->getOperand(OpNo).getImm();
-  assert(isInt<34>(Value) && "Invalid s34imm argument!");
-  O << (long long)Value;
+  if (MI->getOperand(OpNo).isImm()) {
+    long long Value = MI->getOperand(OpNo).getImm();
+    assert(isInt<34>(Value) && "Invalid s34imm argument!");
+    O << (long long)Value;
+  }
+  else
+    printOperand(MI, OpNo, O);
 }
 
 void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h
@@ -50,6 +50,9 @@
   unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;
+  unsigned long getImm34Encoding(const MCInst &MI, unsigned OpNo,
+                                 SmallVectorImpl<MCFixup> &Fixups,
+                                 const MCSubtargetInfo &STI) const;
   unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -104,6 +104,20 @@
   return 0;
 }
 
+unsigned long
+PPCMCCodeEmitter::getImm34Encoding(const MCInst &MI, unsigned OpNo,
+                                   SmallVectorImpl<MCFixup> &Fixups,
+                                   const MCSubtargetInfo &STI) const {
+  const MCOperand &MO = MI.getOperand(OpNo);
+  if (MO.isReg() || MO.isImm())
+    return getMachineOpValue(MI, MO, Fixups, STI);
+
+  // Add a fixup for the immediate field.
+  Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 1, MO.getExpr(),
+                                   (MCFixupKind)PPC::fixup_ppc_pcrel34));
+  return 0;
+}
+
 unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
                                             SmallVectorImpl<MCFixup> &Fixups,
                                             const MCSubtargetInfo &STI) const {
@@ -175,6 +189,16 @@
     report_fatal_error("Operand must be 0");
 
   const MCOperand &MO = MI.getOperand(OpNo);
+  if (MO.isExpr()) {
+    const MCExpr *Expr = MO.getExpr();
+    const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(Expr);
+    assert(SRE->getKind() == MCSymbolRefExpr::VK_PCREL &&
+           "VariantKind must be VK_PCREL");
+    Fixups.push_back(
+        MCFixup::create(IsLittleEndian ? 0 : 1, Expr,
+                        static_cast<MCFixupKind>(PPC::fixup_ppc_pcrel34)));
+    return 0;
+  }
   return ((getMachineOpValue(MI, MO, Fixups, STI)) & 0x3FFFFFFFFUL) | RegBits;
 }
 
Index: llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp
===================================================================
--- llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp
+++ llvm/lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp
@@ -68,6 +68,7 @@
   case PPC::fixup_ppc_brcond14:
   case PPC::fixup_ppc_half16:
   case PPC::fixup_ppc_br24:
+  case PPC::fixup_ppc_br24_notoc:
   case FK_Data_4:
     return 2;
   case FK_PCRel_8:
@@ -93,6 +94,7 @@
     default:
       report_fatal_error("Unimplemented fixup kind (relative)");
     case PPC::fixup_ppc_br24:
+    case PPC::fixup_ppc_br24_notoc:
       Type = MachO::PPC_RELOC_BR24; // R_PPC_REL24
       break;
     case PPC::fixup_ppc_brcond14:
Index: llvm/lib/Target/PowerPC/PPC.h
===================================================================
--- llvm/lib/Target/PowerPC/PPC.h
+++ llvm/lib/Target/PowerPC/PPC.h
@@ -98,24 +98,28 @@
     /// the function's picbase, e.g. lo16(symbol-picbase).
     MO_PIC_FLAG = 2,
 
+    /// MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to
+    /// the current instruction address(pc), e.g., var@pcrel. Fixup is VK_PCREL.
+    MO_PCREL_FLAG = 16,
+
     /// The next are not flags but distinct values.
-    MO_ACCESS_MASK = 0xf0,
+    MO_ACCESS_MASK = 0xf00,
 
     /// MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
-    MO_LO = 1 << 4,
-    MO_HA = 2 << 4,
+    MO_LO = 1 << 8,
+    MO_HA = 2 << 8,
 
-    MO_TPREL_LO = 4 << 4,
-    MO_TPREL_HA = 3 << 4,
+    MO_TPREL_LO = 4 << 8,
+    MO_TPREL_HA = 3 << 8,
 
     /// These values identify relocations on immediates folded
     /// into memory operations.
-    MO_DTPREL_LO = 5 << 4,
-    MO_TLSLD_LO = 6 << 4,
-    MO_TOC_LO = 7 << 4,
+    MO_DTPREL_LO = 5 << 8,
+    MO_TLSLD_LO = 6 << 8,
+    MO_TOC_LO = 7 << 8,
 
     // Symbol for VK_PPC_TLS fixup attached to an ADD instruction
-    MO_TLS = 8 << 4
+    MO_TLS = 8 << 8
   };
   } // end namespace PPCII
 
Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -297,6 +297,10 @@
       return true;
     }
 
+    bool SelectPCRelAddr(SDValue N, SDValue &Base) {
+      return PPCLowering->SelectAddressPCRel(N, Base);
+    }
+
     /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
     /// inline asm expressions.  It is always correct to compute the value into
     /// a register.  The case of adding a (possibly relocatable) constant to a
Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -432,6 +432,11 @@
     /// lower (IDX=1) half of v4f32 to v2f64.
     FP_EXTEND_HALF,
 
+    /// MAT_PCREL_ADDR = Materialize a PC Relative address. This can be done
+    /// either through an add like PADDI or through a PC Relative load like
+    /// PLD.
+    MAT_PCREL_ADDR,
+
     /// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a
     /// byte-swapping store instruction.  It byte-swaps the low "Type" bits of
     /// the GPRC input, then stores it through Ptr.  Type can be either i16 or
@@ -734,6 +739,10 @@
     bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index,
                                  SelectionDAG &DAG) const;
 
+    /// SelectAddressPCRel - Represent the specified address as pc relative to
+    /// be represented as [pc+imm]
+    bool SelectAddressPCRel(SDValue N, SDValue &Base) const;
+
     Sched::Preference getSchedulingPreference(SDNode *N) const override;
 
     /// LowerOperation - Provide custom lowering hooks for some operations.
Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1448,6 +1448,7 @@
   case PPCISD::EXTSWSLI:        return "PPCISD::EXTSWSLI";
   case PPCISD::LD_VSX_LH:       return "PPCISD::LD_VSX_LH";
   case PPCISD::FP_EXTEND_HALF:  return "PPCISD::FP_EXTEND_HALF";
+  case PPCISD::MAT_PCREL_ADDR:  return "PPCISD::MAT_PCREL_ADDR";
   case PPCISD::LD_SPLAT:        return "PPCISD::LD_SPLAT";
   }
   return nullptr;
@@ -2314,6 +2315,10 @@
 bool PPCTargetLowering::SelectAddressRegReg(SDValue N, SDValue &Base,
                                             SDValue &Index, SelectionDAG &DAG,
                                             unsigned EncodingAlignment) const {
+  // If this is a PC Relative address do not match it here.
+  if (SelectAddressPCRel(N, Base))
+    return false;
+
   int16_t imm = 0;
   if (N.getOpcode() == ISD::ADD) {
     // Is there any SPE load/store (f64), which can't handle 16bit offset?
@@ -2404,6 +2409,12 @@
                                             unsigned EncodingAlignment) const {
   // FIXME dl should come from parent load or store, not from address
   SDLoc dl(N);
+
+  // If we have a PC Relative target flag don't select as [r+imm]. It will be
+  // a [pc+imm].
+  if (SelectAddressPCRel(N, Base))
+    return false;
+
   // If this can be more profitably realized as r+r, fail.
   if (SelectAddressRegReg(N, Disp, Base, DAG, EncodingAlignment))
     return false;
@@ -2500,6 +2511,11 @@
 bool PPCTargetLowering::SelectAddressRegRegOnly(SDValue N, SDValue &Base,
                                                 SDValue &Index,
                                                 SelectionDAG &DAG) const {
+  // If we have a PC Relative target flag don't select as [r+r]. It will be
+  // a [pc+imm].
+  if (SelectAddressPCRel(N, Base))
+    return false;
+
   // Check to see if we can easily represent this as an [r+r] address.  This
   // will fail if it thinks that the address is more profitably represented as
   // reg+imm, e.g. where imm = 0.
@@ -2527,6 +2543,19 @@
   return true;
 }
 
+bool PPCTargetLowering::SelectAddressPCRel(SDValue N, SDValue &Base) const {
+  ConstantPoolSDNode *ConstPoolNode =
+      dyn_cast<ConstantPoolSDNode>(N.getNode());
+  bool HasFlag = ConstPoolNode &&
+                 ConstPoolNode->getTargetFlags() == PPCII::MO_PCREL_FLAG;
+  bool HasNode = N.getOpcode() == PPCISD::MAT_PCREL_ADDR;
+  if (HasFlag || HasNode) {
+    Base = N;
+    return true;
+  }
+  return false;
+}
+
 /// Returns true if we should use a direct load into vector instruction
 /// (such as lxsd or lfd), instead of a load into gpr + direct move sequence.
 static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget& ST) {
@@ -2732,6 +2761,16 @@
   // 64-bit SVR4 ABI and AIX ABI code are always position-independent.
   // The actual address of the GlobalValue is stored in the TOC.
   if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
+    if (Subtarget.hasPCRelativeMemops()) {
+      SDLoc DL(CP);
+      EVT Ty = getPointerTy(DAG.getDataLayout());
+      SDValue ConstPool = DAG.getTargetConstantPool(C, Ty,
+                                                    CP->getAlignment(),
+                                                    CP->getOffset(),
+                                                    PPCII::MO_PCREL_FLAG);
+      SDValue MatAddr = DAG.getNode(PPCISD::MAT_PCREL_ADDR, DL, Ty, ConstPool);
+      return MatAddr;
+    }
     setUsesTOCBasePtr(DAG);
     SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0);
     return getTOCEntry(DAG, SDLoc(CP), GA);
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -2046,7 +2046,9 @@
 PPCInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
   using namespace PPCII;
   static const std::pair<unsigned, const char *> TargetFlags[] = {
-      {MO_PLT, "ppc-plt"}, {MO_PIC_FLAG, "ppc-pic"}};
+      {MO_PLT, "ppc-plt"},
+      {MO_PIC_FLAG, "ppc-pic"},
+      {MO_PCREL_FLAG, "ppc-pcrel"}};
   return makeArrayRef(TargetFlags);
 }
 
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
===================================================================
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -322,6 +322,9 @@
 def PPCdynalloc   : SDNode<"PPCISD::DYNALLOC", SDTDynOp, [SDNPHasChain]>;
 def PPCdynareaoffset   : SDNode<"PPCISD::DYNAREAOFFSET", SDTDynAreaOp, [SDNPHasChain]>;
 
+// PC Relative Specific Nodes
+def MATpcreladdr : SDNode<"PPCISD::MAT_PCREL_ADDR", SDTIntUnaryOp, []>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific transformation functions and pattern fragments.
 //
@@ -490,6 +493,7 @@
 
 class isPPC64 { bit PPC64 = 1; }
 class isRecordForm   { bit RC = 1; }
+class isPrefixed { bit Prefixed = 1; }
 
 class RegConstraint<string C> {
   string Constraints = C;
@@ -733,6 +737,7 @@
 }
 def s34imm : Operand<i64> {
   let PrintMethod = "printS34ImmOperand";
+  let EncoderMethod = "getImm34Encoding";
   let ParserMatchClass = PPCS34ImmAsmOperand;
   let DecoderMethod = "decodeSImmOperand<34>";
 }
@@ -976,6 +981,9 @@
 /// This is just the offset part of iaddr, used for preinc.
 def iaddroff : ComplexPattern<iPTR, 1, "SelectAddrImmOffs", [], []>;
 
+// PC Relative Address
+def pcreladdr : ComplexPattern<iPTR, 1, "SelectPCRelAddr", [], []>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC Instruction Predicate Definitions.
 def In32BitMode  : Predicate<"!PPCSubTarget->isPPC64()">;
Index: llvm/lib/Target/PowerPC/PPCInstrPrefix.td
===================================================================
--- llvm/lib/Target/PowerPC/PPCInstrPrefix.td
+++ llvm/lib/Target/PowerPC/PPCInstrPrefix.td
@@ -337,3 +337,18 @@
   }
 }
 
+let Predicates = [PCRelativeMemops] in {
+  // tconstpool
+  let AddedComplexity = 400 in {
+    def : Pat<(f32 (load (MATpcreladdr pcreladdr:$cp))), (PLFSpc $cp, 0)>;
+    def : Pat<(f64 (extloadf32 (MATpcreladdr pcreladdr:$cp))),
+              (COPY_TO_REGCLASS (PLFSpc $cp, 0), VSFRC)>;
+    def : Pat<(f64 (load (MATpcreladdr pcreladdr:$cp))), (PLFDpc $cp, 0)>;
+    def : Pat<(v4i32 (load (MATpcreladdr pcreladdr:$cp))), (PLXVpc $cp, 0)>;
+    def : Pat<(v2f64 (load (MATpcreladdr pcreladdr:$cp))), (PLXVpc $cp, 0)>;
+  }
+  def : Pat<(f128 (load (MATpcreladdr pcreladdr:$cp))),
+            (COPY_TO_REGCLASS (PLXVpc $cp, 0), VRRC)>;
+  def : Pat<(MATpcreladdr tconstpool:$cp), (PADDI8pc 0, $cp)>;
+}
+
Index: llvm/lib/Target/PowerPC/PPCMCInstLower.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCMCInstLower.cpp
+++ llvm/lib/Target/PowerPC/PPCMCInstLower.cpp
@@ -78,8 +78,10 @@
       break;
   }
 
- if (MO.getTargetFlags() == PPCII::MO_PLT)
+  if (MO.getTargetFlags() == PPCII::MO_PLT)
     RefKind = MCSymbolRefExpr::VK_PLT;
+  else if (MO.getTargetFlags() == PPCII::MO_PCREL_FLAG)
+    RefKind = MCSymbolRefExpr::VK_PCREL;
 
   const MachineFunction *MF = MO.getParent()->getParent()->getParent();
   const Module *M = MF->getFunction().getParent();
Index: llvm/test/CodeGen/PowerPC/constant-pool.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/constant-pool.ll
@@ -0,0 +1,92 @@
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=future -enable-ppc-quad-precision -ppc-asm-full-reg-names \
+; RUN:   < %s | FileCheck %s
+
+ define float @FloatConstantPool() {
+; CHECK-LABEL: FloatConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plfs f1, .LCPI0_0@PCREL(0), 1
+entry:
+  ret float 0x380FFFF840000000
+}
+
+ define double @DoubleConstantPool() {
+; CHECK-LABEL: DoubleConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plfd f1, .LCPI1_0@PCREL(0), 1
+entry:
+  ret double 2.225070e-308
+}
+
+ define ppc_fp128 @LongDoubleConstantPool() {
+; CHECK-LABEL: LongDoubleConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plfd f1, .LCPI2_0@PCREL(0), 1
+; CHECK-NEXT:    plfd f2, .LCPI2_1@PCREL(0), 1
+entry:
+  ret ppc_fp128 0xM03600000DBA876CC800D16974FD9D27B
+}
+
+ define fp128 @__Float128ConstantPool() {
+; CHECK-LABEL: __Float128ConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI3_0@PCREL(0), 1
+entry:
+  ret fp128 0xL00000000000000003C00FFFFC5D02B3A
+}
+
+ define <16 x i8> @VectorCharConstantPool() {
+; CHECK-LABEL: VectorCharConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI4_0@PCREL(0), 1
+entry:
+  ret <16 x i8> <i8 -128, i8 -127, i8 -126, i8 -125, i8 -124, i8 -123, i8 -122, i8 -121, i8 -120, i8 -119, i8 -118, i8 -117, i8 -116, i8 -115, i8 -114, i8 -113>
+}
+
+ define <8 x i16> @VectorShortConstantPool() {
+; CHECK-LABEL: VectorShortConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI5_0@PCREL(0), 1
+entry:
+  ret <8 x i16> <i16 -32768, i16 -32767, i16 -32766, i16 -32765, i16 -32764, i16 -32763, i16 -32762, i16 -32761>
+}
+
+ define <4 x i32> @VectorIntConstantPool() {
+; CHECK-LABEL: VectorIntConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI6_0@PCREL(0), 1
+entry:
+  ret <4 x i32> <i32 -2147483648, i32 -2147483647, i32 -2147483646, i32 -2147483645>
+}
+
+ define <2 x i64> @VectorLongLongConstantPool() {
+; CHECK-LABEL: VectorLongLongConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI7_0@PCREL(0), 1
+entry:
+  ret <2 x i64> <i64 -9223372036854775808, i64 -9223372036854775807>
+}
+
+ define <1 x i128> @VectorInt128ConstantPool() {
+; CHECK-LABEL: VectorInt128ConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI8_0@PCREL(0), 1
+entry:
+  ret <1 x i128> <i128 -27670116110564327424>
+}
+
+ define <4 x float> @VectorFloatConstantPool() {
+; CHECK-LABEL: VectorFloatConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI9_0@PCREL(0), 1
+entry:
+  ret <4 x float> <float 0x380FFFF840000000, float 0x380FFF57C0000000, float 0x3843FFFB20000000, float 0x3843FF96C0000000>
+}
+
+ define <2 x double> @VectorDoubleConstantPool() {
+; CHECK-LABEL: VectorDoubleConstantPool:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    plxv vs34, .LCPI10_0@PCREL(0), 1
+entry:
+  ret <2 x double> <double 2.225070e-308, double 2.225000e-308>
+}
Index: llvm/test/CodeGen/PowerPC/csr-split.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/csr-split.ll
+++ llvm/test/CodeGen/PowerPC/csr-split.ll
@@ -1,5 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: llc -verify-machineinstrs  -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names \
+; RUN:     -mtriple=powerpc64le-unknown-linux-gnu -mcpu=future < %s | FileCheck %s --check-prefix=CHECK-FUTURE
+; RUN: llc -verify-machineinstrs  -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names \
 ; RUN:     -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-PWR9
 ; RUN: llc -verify-machineinstrs  -ppc-vsr-nums-as-vr -ppc-asm-full-reg-names \
 ; RUN:     -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr8 < %s | FileCheck %s
@@ -9,6 +11,34 @@
 @a = dso_local local_unnamed_addr global i32 0, align 4
 
 define dso_local signext i32 @test1(i32* %b) local_unnamed_addr  {
+; CHECK-FUTURE-LABEL: test1:
+; CHECK-FUTURE:       # %bb.0: # %entry
+; CHECK-FUTURE-NEXT:    mflr r0
+; CHECK-FUTURE-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-FUTURE-NEXT:    .cfi_offset lr, 16
+; CHECK-FUTURE-NEXT:    .cfi_offset r30, -16
+; CHECK-FUTURE-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
+; CHECK-FUTURE-NEXT:    std r0, 16(r1)
+; CHECK-FUTURE-NEXT:    stdu r1, -48(r1)
+; CHECK-FUTURE-NEXT:    addis r4, r2, a@toc@ha
+; CHECK-FUTURE-NEXT:    lwa r4, a@toc@l(r4)
+; CHECK-FUTURE-NEXT:    mr r30, r3
+; CHECK-FUTURE-NEXT:    cmpld r4, r3
+; CHECK-FUTURE-NEXT:    # implicit-def: $r3
+; CHECK-FUTURE-NEXT:    bne cr0, .LBB0_2
+; CHECK-FUTURE-NEXT:  # %bb.1: # %if.then
+; CHECK-FUTURE-NEXT:    bl callVoid
+; CHECK-FUTURE-NEXT:    nop
+; CHECK-FUTURE-NEXT:    mr r3, r30
+; CHECK-FUTURE-NEXT:    bl callNonVoid@notoc
+; CHECK-FUTURE-NEXT:  .LBB0_2: # %if.end
+; CHECK-FUTURE-NEXT:    extsw r3, r3
+; CHECK-FUTURE-NEXT:    addi r1, r1, 48
+; CHECK-FUTURE-NEXT:    ld r0, 16(r1)
+; CHECK-FUTURE-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
+; CHECK-FUTURE-NEXT:    mtlr r0
+; CHECK-FUTURE-NEXT:    blr
+;
 ; CHECK-PWR9-LABEL: test1:
 ; CHECK-PWR9:       # %bb.0: # %entry
 ; CHECK-PWR9-NEXT:    mflr r0
@@ -88,6 +118,37 @@
 declare signext i32 @callNonVoid(i32*) local_unnamed_addr
 
 define dso_local signext i32 @test2(i32* %p1) local_unnamed_addr  {
+; CHECK-FUTURE-LABEL: test2:
+; CHECK-FUTURE:       # %bb.0: # %entry
+; CHECK-FUTURE-NEXT:    mflr r0
+; CHECK-FUTURE-NEXT:    .cfi_def_cfa_offset 48
+; CHECK-FUTURE-NEXT:    .cfi_offset lr, 16
+; CHECK-FUTURE-NEXT:    .cfi_offset r30, -16
+; CHECK-FUTURE-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
+; CHECK-FUTURE-NEXT:    std r0, 16(r1)
+; CHECK-FUTURE-NEXT:    stdu r1, -48(r1)
+; CHECK-FUTURE-NEXT:    mr r30, r3
+; CHECK-FUTURE-NEXT:    cmpldi r3, 0
+; CHECK-FUTURE-NEXT:    li r3, 0
+; CHECK-FUTURE-NEXT:    beq cr0, .LBB1_3
+; CHECK-FUTURE-NEXT:  # %bb.1: # %if.end
+; CHECK-FUTURE-NEXT:    addis r4, r2, a@toc@ha
+; CHECK-FUTURE-NEXT:    lwa r4, a@toc@l(r4)
+; CHECK-FUTURE-NEXT:    cmpld r4, r30
+; CHECK-FUTURE-NEXT:    bne cr0, .LBB1_3
+; CHECK-FUTURE-NEXT:  # %bb.2: # %if.then2
+; CHECK-FUTURE-NEXT:    bl callVoid
+; CHECK-FUTURE-NEXT:    nop
+; CHECK-FUTURE-NEXT:    mr r3, r30
+; CHECK-FUTURE-NEXT:    bl callNonVoid@notoc
+; CHECK-FUTURE-NEXT:  .LBB1_3: # %return
+; CHECK-FUTURE-NEXT:    extsw r3, r3
+; CHECK-FUTURE-NEXT:    addi r1, r1, 48
+; CHECK-FUTURE-NEXT:    ld r0, 16(r1)
+; CHECK-FUTURE-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
+; CHECK-FUTURE-NEXT:    mtlr r0
+; CHECK-FUTURE-NEXT:    blr
+;
 ; CHECK-PWR9-LABEL: test2:
 ; CHECK-PWR9:       # %bb.0: # %entry
 ; CHECK-PWR9-NEXT:    mflr r0
@@ -174,6 +235,36 @@
 
 
 define dso_local i8* @test3(i8** nocapture %p1, i8 zeroext %p2) local_unnamed_addr  {
+; CHECK-FUTURE-LABEL: test3:
+; CHECK-FUTURE:         .localentry test3, 1
+; CHECK-FUTURE-NEXT:  # %bb.0: # %entry
+; CHECK-FUTURE-NEXT:    mflr r0
+; CHECK-FUTURE-NEXT:    .cfi_def_cfa_offset 64
+; CHECK-FUTURE-NEXT:    .cfi_offset lr, 16
+; CHECK-FUTURE-NEXT:    .cfi_offset r29, -24
+; CHECK-FUTURE-NEXT:    .cfi_offset r30, -16
+; CHECK-FUTURE-NEXT:    std r29, -24(r1) # 8-byte Folded Spill
+; CHECK-FUTURE-NEXT:    std r30, -16(r1) # 8-byte Folded Spill
+; CHECK-FUTURE-NEXT:    std r0, 16(r1)
+; CHECK-FUTURE-NEXT:    stdu r1, -64(r1)
+; CHECK-FUTURE-NEXT:    ld r30, 0(r3)
+; CHECK-FUTURE-NEXT:    cmpldi r30, 0
+; CHECK-FUTURE-NEXT:    beq cr0, .LBB2_2
+; CHECK-FUTURE-NEXT:  # %bb.1: # %land.rhs
+; CHECK-FUTURE-NEXT:    mr r29, r3
+; CHECK-FUTURE-NEXT:    clrldi r4, r4, 32
+; CHECK-FUTURE-NEXT:    mr r3, r30
+; CHECK-FUTURE-NEXT:    bl bar@notoc
+; CHECK-FUTURE-NEXT:    std r3, 0(r29)
+; CHECK-FUTURE-NEXT:  .LBB2_2: # %land.end
+; CHECK-FUTURE-NEXT:    mr r3, r30
+; CHECK-FUTURE-NEXT:    addi r1, r1, 64
+; CHECK-FUTURE-NEXT:    ld r0, 16(r1)
+; CHECK-FUTURE-NEXT:    ld r30, -16(r1) # 8-byte Folded Reload
+; CHECK-FUTURE-NEXT:    ld r29, -24(r1) # 8-byte Folded Reload
+; CHECK-FUTURE-NEXT:    mtlr r0
+; CHECK-FUTURE-NEXT:    blr
+;
 ; CHECK-PWR9-LABEL: test3:
 ; CHECK-PWR9:       # %bb.0: # %entry
 ; CHECK-PWR9-NEXT:    mflr r0
Index: llvm/test/CodeGen/PowerPC/pcrel.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/pcrel.ll
@@ -0,0 +1,23 @@
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=future -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr < %s | \
+; RUN:   FileCheck %s --check-prefix=CHECK-S
+; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu \
+; RUN:   -mcpu=future -ppc-asm-full-reg-names -ppc-vsr-nums-as-vr \
+; RUN:   --filetype=obj < %s | \
+; RUN:   llvm-objdump -mcpu=future -dr - | FileCheck %s --check-prefix=CHECK-O
+
+; Constant Pool Index.
+; CHECK-S-LABEL: ConstPool
+; CHECK-S:       plfd f1, .LCPI0_0@PCREL(0), 1
+; CHECK-S:       blr
+
+; CHECK-O-LABEL: ConstPool
+; CHECK-O:       plfd 1, 0(0), 1
+; CHECK-O-NEXT:  R_PPC64_PCREL34  .rodata.cst8
+; CHECK-O:       blr
+define dso_local double @ConstPool() local_unnamed_addr {
+  entry:
+    ret double 0x406ECAB439581062
+}
+
+