Index: llvm/lib/CodeGen/AsmPrinter/AddressPool.h
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AddressPool.h
+++ llvm/lib/CodeGen/AsmPrinter/AddressPool.h
@@ -17,6 +17,39 @@
 class MCSection;
 class MCSymbol;
 
+/// Pair of a symbol and an offset in number of bytes.
+struct SymbolWithOffset {
+  const MCSymbol *Symbol;
+  int Offset;
+
+  bool operator==(const SymbolWithOffset &O) const {
+    return Symbol == O.Symbol && Offset == O.Offset;
+  }
+};
+
+template <> struct DenseMapInfo<SymbolWithOffset> {
+  using SymbolInfo = DenseMapInfo<const MCSymbol *>;
+  using OffsetInfo = DenseMapInfo<int>;
+  using PairInfo = DenseMapInfo<std::pair<const MCSymbol *, int>>;
+
+  static SymbolWithOffset getEmptyKey() {
+    return {SymbolInfo::getEmptyKey(), OffsetInfo::getEmptyKey()};
+  }
+
+  static SymbolWithOffset getTombstoneKey() {
+    return {SymbolInfo::getTombstoneKey(), OffsetInfo::getTombstoneKey()};
+  }
+
+  static unsigned getHashValue(const SymbolWithOffset &Val) {
+    return PairInfo::getHashValue({Val.Symbol, Val.Offset});
+  }
+
+  static bool isEqual(const SymbolWithOffset &LHS,
+                      const SymbolWithOffset &RHS) {
+    return LHS == RHS;
+  }
+};
+
 // Collection of addresses for this unit and assorted labels.
 // A Symbol->unsigned mapping of addresses used by indirect
 // references.
@@ -27,7 +60,7 @@
 
     AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
   };
-  DenseMap<const MCSymbol *, AddressPoolEntry> Pool;
+  DenseMap<SymbolWithOffset, AddressPoolEntry> Pool;
 
   /// Record whether the AddressPool has been queried for an address index since
   /// the last "resetUsedFlag" call. Used to implement type unit fallback - a
@@ -42,6 +75,10 @@
   /// label/symbol.
   unsigned getIndex(const MCSymbol *Sym, bool TLS = false);
 
+  /// Returns the index into the address pool with the given
+  /// label/symbol and offset.
+  unsigned getIndex(SymbolWithOffset SymWithOffs, bool TLS = false);
+
   void emit(AsmPrinter &Asm, MCSection *AddrSection);
 
   bool isEmpty() { return Pool.empty(); }
Index: llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
+++ llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp
@@ -18,8 +18,15 @@
 
 unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) {
   HasBeenUsed = true;
+  auto IterBool = Pool.insert(
+      {SymbolWithOffset{Sym, 0}, AddressPoolEntry(Pool.size(), TLS)});
+  return IterBool.first->second.Number;
+}
+
+unsigned AddressPool::getIndex(SymbolWithOffset SymWithOffs, bool TLS) {
+  HasBeenUsed = true;
   auto IterBool =
-      Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS)));
+      Pool.insert({SymWithOffs, AddressPoolEntry(Pool.size(), TLS)});
   return IterBool.first->second.Number;
 }
 
@@ -63,11 +70,21 @@
   // Order the address pool entries by ID
   SmallVector<const MCExpr *, 64> Entries(Pool.size());
 
-  for (const auto &I : Pool)
-    Entries[I.second.Number] =
+  for (const auto &I : Pool) {
+    auto &Entry = Entries[I.second.Number] =
         I.second.TLS
-            ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first)
-            : MCSymbolRefExpr::create(I.first, Asm.OutContext);
+            ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first.Symbol)
+            : MCSymbolRefExpr::create(I.first.Symbol, Asm.OutContext);
+    auto Offset = I.first.Offset;
+    if (!Offset)
+      continue;
+    // Create an expression for the addition or subtraction of the offset.
+    auto Op = Offset < 0 ? MCBinaryExpr::Sub : MCBinaryExpr::Add;
+    const auto OffsetExpr =
+        MCConstantExpr::create(std::abs(Offset), Asm.OutContext);
+    const MCExpr *SymbolExpr = Entry;
+    Entry = MCBinaryExpr::create(Op, SymbolExpr, OffsetExpr, Asm.OutContext);
+  }
 
   for (const MCExpr *Entry : Entries)
     Asm.OutStreamer->EmitValue(Entry, Asm.getDataLayout().getPointerSize());