diff --git a/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h b/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h
--- a/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h
+++ b/llvm/include/llvm/CodeGen/DwarfStringPoolEntry.h
@@ -9,7 +9,7 @@
 #ifndef LLVM_CODEGEN_DWARFSTRINGPOOLENTRY_H
 #define LLVM_CODEGEN_DWARFSTRINGPOOLENTRY_H
 
-#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/StringMap.h"
 
 namespace llvm {
@@ -20,45 +20,76 @@
 struct DwarfStringPoolEntry {
   static constexpr unsigned NotIndexed = -1;
 
-  MCSymbol *Symbol;
-  uint64_t Offset;
-  unsigned Index;
+  MCSymbol *Symbol = nullptr;
+  uint64_t Offset = 0;
+  unsigned Index = 0;
 
   bool isIndexed() const { return Index != NotIndexed; }
 };
 
 /// String pool entry reference.
 class DwarfStringPoolEntryRef {
-  const StringMapEntry<DwarfStringPoolEntry> *MapEntry = nullptr;
+  /// Full DwarfStringPoolEntry stored in the StringMapEntry.
+  using StringEntryPtr = const StringMapEntry<DwarfStringPoolEntry> *;
 
-  const StringMapEntry<DwarfStringPoolEntry> *getMapEntry() const {
-    return MapEntry;
-  }
+  /// Pointer to DwarfStringPoolEntry stored in the StringMapEntry.
+  using ShortStringEntryPtr = const StringMapEntry<DwarfStringPoolEntry *> *;
+
+  /// Pointer to the string pool Entry.
+  PointerUnion<StringEntryPtr, ShortStringEntryPtr> MapEntry = nullptr;
 
 public:
   DwarfStringPoolEntryRef() = default;
+
+  // ASSUMPTION: \p Entry mustn`t be reallocated.
   DwarfStringPoolEntryRef(const StringMapEntry<DwarfStringPoolEntry> &Entry)
       : MapEntry(&Entry) {}
 
-  explicit operator bool() const { return getMapEntry(); }
+  // ASSUMPTION: \p Entry mustn`t be reallocated.
+  DwarfStringPoolEntryRef(const StringMapEntry<DwarfStringPoolEntry *> &Entry)
+      : MapEntry(&Entry) {
+    assert(MapEntry.get<ShortStringEntryPtr>()->second != nullptr);
+  }
+
+  explicit operator bool() const { return !MapEntry.isNull(); }
+
+  /// \returns symbol for the dwarf string.
   MCSymbol *getSymbol() const {
-    assert(getMapEntry()->second.Symbol && "No symbol available!");
-    return getMapEntry()->second.Symbol;
+    assert(getEntry().Symbol && "No symbol available!");
+    return getEntry().Symbol;
   }
-  uint64_t getOffset() const { return getMapEntry()->second.Offset; }
+
+  /// \returns offset for the dwarf string.
+  uint64_t getOffset() const { return getEntry().Offset; }
+
+  /// \returns index for the dwarf string.
   unsigned getIndex() const {
-    assert(getMapEntry()->getValue().isIndexed());
-    return getMapEntry()->second.Index;
+    assert(getEntry().isIndexed() && "Index is not set!");
+    return getEntry().Index;
+  }
+
+  /// \returns string.
+  StringRef getString() const {
+    if (MapEntry.is<StringEntryPtr>())
+      return MapEntry.get<StringEntryPtr>()->first();
+    else
+      return MapEntry.get<ShortStringEntryPtr>()->first();
+  }
+
+  /// \returns the entire string pool entry for convenience.
+  const DwarfStringPoolEntry &getEntry() const {
+    if (MapEntry.is<StringEntryPtr>())
+      return MapEntry.get<StringEntryPtr>()->second;
+    else
+      return *MapEntry.get<ShortStringEntryPtr>()->second;
   }
-  StringRef getString() const { return getMapEntry()->first(); }
-  /// Return the entire string pool entry for convenience.
-  DwarfStringPoolEntry getEntry() const { return getMapEntry()->getValue(); }
 
   bool operator==(const DwarfStringPoolEntryRef &X) const {
-    return getMapEntry() == X.getMapEntry();
+    return MapEntry.getOpaqueValue() == X.MapEntry.getOpaqueValue();
   }
+
   bool operator!=(const DwarfStringPoolEntryRef &X) const {
-    return getMapEntry() != X.getMapEntry();
+    return MapEntry.getOpaqueValue() != X.MapEntry.getOpaqueValue();
   }
 };
 
diff --git a/llvm/unittests/CodeGen/CMakeLists.txt b/llvm/unittests/CodeGen/CMakeLists.txt
--- a/llvm/unittests/CodeGen/CMakeLists.txt
+++ b/llvm/unittests/CodeGen/CMakeLists.txt
@@ -21,6 +21,7 @@
   AsmPrinterDwarfTest.cpp
   DIEHashTest.cpp
   DIETest.cpp
+  DwarfStringPoolEntryRefTest.cpp
   InstrRefLDVTest.cpp
   LowLevelTypeTest.cpp
   LexicalScopesTest.cpp
diff --git a/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp b/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp
new file mode 100644
--- /dev/null
+++ b/llvm/unittests/CodeGen/DwarfStringPoolEntryRefTest.cpp
@@ -0,0 +1,117 @@
+//===- llvm/unittest/CodeGen/DwarfStringPoolEntryRefTest.cpp --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CodeGen/DwarfStringPoolEntry.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Testing/Support/Error.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include <string>
+
+using namespace llvm;
+
+TEST(DwarfStringPoolEntryRefTest, TestFullEntry) {
+  BumpPtrAllocator Allocator;
+  StringMapEntry<DwarfStringPoolEntry> *StringEntry1 =
+      StringMapEntry<DwarfStringPoolEntry>::Create(
+          "Key1", Allocator, DwarfStringPoolEntry{nullptr, 0, 0});
+
+  EXPECT_TRUE(StringEntry1->getKey() == "Key1");
+  EXPECT_TRUE(StringEntry1->second.Symbol == nullptr);
+  EXPECT_TRUE(StringEntry1->second.Offset == 0);
+  EXPECT_TRUE(StringEntry1->second.Index == 0);
+
+  DwarfStringPoolEntryRef Ref1(*StringEntry1);
+  EXPECT_TRUE(Ref1.getString() == "Key1");
+  EXPECT_TRUE(Ref1.getOffset() == 0);
+  EXPECT_TRUE(Ref1.getIndex() == 0);
+
+  DwarfStringPoolEntryRef Ref2(*StringEntry1);
+  EXPECT_TRUE(Ref2.getString() == "Key1");
+  EXPECT_TRUE(Ref2.getOffset() == 0);
+  EXPECT_TRUE(Ref2.getIndex() == 0);
+  EXPECT_TRUE(Ref1 == Ref2);
+  EXPECT_FALSE(Ref1 != Ref2);
+
+  StringMapEntry<DwarfStringPoolEntry> *StringEntry2 =
+      StringMapEntry<DwarfStringPoolEntry>::Create(
+          "Key2", Allocator, DwarfStringPoolEntry{nullptr, 0x1000, 1});
+  EXPECT_TRUE(StringEntry2->getKey() == "Key2");
+  EXPECT_TRUE(StringEntry2->second.Symbol == nullptr);
+  EXPECT_TRUE(StringEntry2->second.Offset == 0x1000);
+  EXPECT_TRUE(StringEntry2->second.Index == 1);
+
+  DwarfStringPoolEntryRef Ref3(*StringEntry2);
+  EXPECT_TRUE(Ref3.getString() == "Key2");
+  EXPECT_TRUE(Ref3.getOffset() == 0x1000);
+  EXPECT_TRUE(Ref3.getIndex() == 1);
+  EXPECT_TRUE(Ref1 != Ref3);
+}
+
+TEST(DwarfStringPoolEntryRefTest, TestShortEntry) {
+  BumpPtrAllocator Allocator;
+  DwarfStringPoolEntry DwarfEntry1 = {nullptr, 0, 0};
+  StringMapEntry<DwarfStringPoolEntry *> *StringEntry1 =
+      StringMapEntry<DwarfStringPoolEntry *>::Create("Key1", Allocator,
+                                                     &DwarfEntry1);
+
+  EXPECT_TRUE(StringEntry1->getKey() == "Key1");
+  EXPECT_TRUE(StringEntry1->second->Symbol == nullptr);
+  EXPECT_TRUE(StringEntry1->second->Offset == 0);
+  EXPECT_TRUE(StringEntry1->second->Index == 0);
+
+  DwarfStringPoolEntryRef Ref1(*StringEntry1);
+  EXPECT_TRUE(Ref1.getString() == "Key1");
+  EXPECT_TRUE(Ref1.getOffset() == 0);
+  EXPECT_TRUE(Ref1.getIndex() == 0);
+  EXPECT_TRUE(memcmp(&Ref1.getEntry(), &DwarfEntry1,
+                     sizeof(DwarfStringPoolEntry)) == 0);
+
+  DwarfStringPoolEntryRef Ref2(*StringEntry1);
+  EXPECT_TRUE(Ref2.getString() == "Key1");
+  EXPECT_TRUE(Ref2.getOffset() == 0);
+  EXPECT_TRUE(memcmp(&Ref2.getEntry(), &DwarfEntry1,
+                     sizeof(DwarfStringPoolEntry)) == 0);
+  EXPECT_TRUE(Ref1 == Ref2);
+  EXPECT_FALSE(Ref1 != Ref2);
+
+  DwarfStringPoolEntry DwarfEntry2 = {nullptr, 0x1000, 1};
+  StringMapEntry<DwarfStringPoolEntry *> *StringEntry2 =
+      StringMapEntry<DwarfStringPoolEntry *>::Create("Key2", Allocator,
+                                                     &DwarfEntry2);
+  EXPECT_TRUE(StringEntry2->getKey() == "Key2");
+  EXPECT_TRUE(StringEntry2->second->Symbol == nullptr);
+  EXPECT_TRUE(StringEntry2->second->Offset == 0x1000);
+  EXPECT_TRUE(StringEntry2->second->Index == 1);
+
+  DwarfStringPoolEntryRef Ref3(*StringEntry2);
+  EXPECT_TRUE(Ref3.getString() == "Key2");
+  EXPECT_TRUE(Ref3.getOffset() == 0x1000);
+  EXPECT_TRUE(Ref3.getIndex() == 1);
+  EXPECT_TRUE(memcmp(&Ref3.getEntry(), &DwarfEntry2,
+                     sizeof(DwarfStringPoolEntry)) == 0);
+  EXPECT_TRUE(Ref1 != Ref3);
+}
+
+TEST(DwarfStringPoolEntryRefTest, CompareFullAndShort) {
+  BumpPtrAllocator Allocator;
+
+  DwarfStringPoolEntry DwarfEntry1 = {nullptr, 0, 0};
+  StringMapEntry<DwarfStringPoolEntry *> *StringEntry1 =
+      StringMapEntry<DwarfStringPoolEntry *>::Create("Key1", Allocator,
+                                                     &DwarfEntry1);
+  DwarfStringPoolEntryRef Ref1(*StringEntry1);
+
+  StringMapEntry<DwarfStringPoolEntry> *StringEntry2 =
+      StringMapEntry<DwarfStringPoolEntry>::Create(
+          "Key1", Allocator, DwarfStringPoolEntry{nullptr, 0, 0});
+  DwarfStringPoolEntryRef Ref2(*StringEntry2);
+
+  EXPECT_FALSE(Ref1 == Ref2);
+}