[clang] [llvm] [PowerPC] Tune AIX shared library TLS model at function level by heuristic (PR #84132)

Felix via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 18 18:01:29 PDT 2024


https://github.com/orcguru updated https://github.com/llvm/llvm-project/pull/84132

>From c91ba81c06e7c43215952628a61b23aa46fe22f0 Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Wed, 6 Mar 2024 02:51:40 -0500
Subject: [PATCH 1/9] [PowerPC] Rename symbols references by tls-local-dynamic
 model

On AIX, rename those tls-local-dynamic referenced TOC symbols, so that in
following patches we can switch between different TLS models (local-dynamic
or initial-exec) for the same TLS GV in different functions within the same
module.
---
 .../CodeGen/TargetLoweringObjectFileImpl.h    |   5 +-
 llvm/include/llvm/MC/MCContext.h              |   3 +-
 .../llvm/Target/TargetLoweringObjectFile.h    |   6 +-
 llvm/lib/MC/MCContext.cpp                     |   5 +-
 llvm/lib/MC/MCSymbolXCOFF.cpp                 |   6 +-
 .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp  |  15 +-
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |   6 +-
 .../test/CodeGen/PowerPC/aix-tls-gd-double.ll |  12 +-
 llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll   |  12 +-
 .../CodeGen/PowerPC/aix-tls-gd-longlong.ll    |  24 +-
 .../PowerPC/aix-tls-ld-unqualified-symbols.ll | 362 ++++++++++++++++++
 .../CodeGen/PowerPC/aix-tls-local-dynamic.ll  |  39 +-
 12 files changed, 454 insertions(+), 41 deletions(-)
 create mode 100644 llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll

diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 8eef45ce565deb..1aa25e98423afa 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -279,8 +279,9 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
   MCSection *
   getSectionForFunctionDescriptor(const Function *F,
                                   const TargetMachine &TM) const override;
-  MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
-                                   const TargetMachine &TM) const override;
+  MCSection *
+  getSectionForTOCEntry(const MCSymbol *Sym, const TargetMachine &TM,
+                        const MCSymbolRefExpr::VariantKind VK) const override;
 
   /// For external functions, this will always return a function descriptor
   /// csect.
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index ef9833cdf2b070..3708b2dff727e4 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -691,7 +691,8 @@ class MCContext {
       std::optional<XCOFF::CsectProperties> CsectProp = std::nullopt,
       bool MultiSymbolsAllowed = false, const char *BeginSymName = nullptr,
       std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSubtypeFlags =
-          std::nullopt);
+          std::nullopt,
+      StringRef RenamePrefix = StringRef());
 
   // Create and save a copy of STI and return a reference to the copy.
   MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index 0c09cfe684783b..31a466a18d77a2 100644
--- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
 #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
 
+#include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCRegister.h"
 #include <cstdint>
@@ -256,8 +257,9 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
   /// On targets that support TOC entries, return a section for the entry given
   /// the symbol it refers to.
   /// TODO: Implement this interface for existing ELF targets.
-  virtual MCSection *getSectionForTOCEntry(const MCSymbol *S,
-                                           const TargetMachine &TM) const {
+  virtual MCSection *
+  getSectionForTOCEntry(const MCSymbol *S, const TargetMachine &TM,
+                        const MCSymbolRefExpr::VariantKind VK) const {
     return nullptr;
   }
 
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index 3aee96fdf57fc2..b8e96c7b6995d9 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -785,7 +785,8 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
     StringRef Section, SectionKind Kind,
     std::optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed,
     const char *BeginSymName,
-    std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) {
+    std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags,
+    StringRef RenamePrefix) {
   bool IsDwarfSec = DwarfSectionSubtypeFlags.has_value();
   assert((IsDwarfSec != CsectProp.has_value()) && "Invalid XCOFF section!");
 
@@ -811,7 +812,7 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
     QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));
   else
     QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
-        CachedName + "[" +
+        RenamePrefix + CachedName + "[" +
         XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));
 
   MCSymbol *Begin = nullptr;
diff --git a/llvm/lib/MC/MCSymbolXCOFF.cpp b/llvm/lib/MC/MCSymbolXCOFF.cpp
index b4c96a1ffa2333..17f0bcf77745af 100644
--- a/llvm/lib/MC/MCSymbolXCOFF.cpp
+++ b/llvm/lib/MC/MCSymbolXCOFF.cpp
@@ -24,7 +24,11 @@ void MCSymbolXCOFF::setRepresentedCsect(MCSectionXCOFF *C) {
   assert((!RepresentedCsect || RepresentedCsect == C) &&
          "Trying to set a csect that doesn't match the one that this symbol is "
          "already mapped to.");
-  assert(getSymbolTableName().equals(C->getSymbolTableName()) &&
+  // Csect representation related symbols access by using TLS local-dynamic
+  // model have prefix "_$TLSLD." before their names.
+  assert((getSymbolTableName().equals(C->getSymbolTableName()) ||
+          getSymbolTableName().equals(std::string("_$TLSLD.") +
+                                      C->getSymbolTableName().str())) &&
          "SymbolTableNames need to be the same for this symbol and its csect "
          "representation.");
   RepresentedCsect = C;
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index b849b7be7b7be8..0263c3588a2283 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -231,6 +231,20 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
       MCSymbolXCOFF *TCSym =
           cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
               ->getQualNameSymbol();
+
+      // On AIX, symbol accessed using TLS local-dynamic model has been renamed
+      // by adding prefix "_$TLSLD.". Do assert that it has been renamed, and
+      // then emit the .rename with the original symbol name.
+      if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD) {
+        assert(TCSym->hasRename());
+        OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
+           << MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
+        StringRef Lhs, Rhs;
+        std::tie(Lhs, Rhs) = TCSym->getSymbolTableName().split("_$TLSLD.");
+        Streamer.emitXCOFFRenameDirective(TCSym, Rhs);
+        return;
+      }
+
       // On AIX, we have TLS variable offsets (symbol@({gd|ie|le|ld}) depending
       // on the TLS access method (or model). For the general-dynamic access
       // method, we also have region handle (symbol at m) for each variable. For
@@ -242,7 +256,6 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE ||
-          Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML)
         OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
            << MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 6e1002c45d81cb..662aac415f5120 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2956,10 +2956,10 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
       Name += cast<MCSymbolXCOFF>(I.first.first)->getSymbolTableName();
       MCSymbol *S = OutContext.getOrCreateSymbol(Name);
       TCEntry = cast<MCSectionXCOFF>(
-          getObjFileLowering().getSectionForTOCEntry(S, TM));
+          getObjFileLowering().getSectionForTOCEntry(S, TM, I.first.second));
     } else {
-      TCEntry = cast<MCSectionXCOFF>(
-          getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
+      TCEntry = cast<MCSectionXCOFF>(getObjFileLowering().getSectionForTOCEntry(
+          I.first.first, TM, I.first.second));
     }
     OutStreamer->switchSection(TCEntry);
 
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll
index ae41b6b1301064..d84f92b11c9781 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll
@@ -636,7 +636,8 @@ entry:
 ; SMALL32-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL32-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL32-LABEL:  L..C5:
-; SMALL32-NEXT:   .tc TIInit[TC],TIInit[TL]@ld
+; SMALL32-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
+; SMALL32-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
 ; SMALL32-LABEL:  L..C6:
 ; SMALL32-NEXT:   .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL32-LABEL:  L..C7:
@@ -654,7 +655,8 @@ entry:
 ; LARGE32-LABEL:  L..C3:
 ; LARGE32-NEXT:   .tc TGInit[TE],TGInit[TL]@gd
 ; LARGE32-LABEL:  L..C4:
-; LARGE32-NEXT:   .tc TIInit[TE],TIInit[TL]@ld
+; LARGE32-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
+; LARGE32-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
 ; LARGE32-LABEL:  L..C5:
 ; LARGE32-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
@@ -678,7 +680,8 @@ entry:
 ; SMALL64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL64-LABEL:  L..C5:
-; SMALL64-NEXT:  .tc TIInit[TC],TIInit[TL]@ld
+; SMALL64-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
+; SMALL64-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
 ; SMALL64-LABEL:  L..C6:
 ; SMALL64-NEXT:  .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL64-LABEL:  L..C7:
@@ -699,7 +702,8 @@ entry:
 ; LARGE64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64-LABEL:  L..C5:
-; LARGE64-NEXT:  .tc TIInit[TE],TIInit[TL]@ld
+; LARGE64-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
+; LARGE64-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
 ; LARGE64-LABEL:  L..C6:
 ; LARGE64-NEXT:  .tc .TWInit[TE],TWInit[TL]@m
 ; LARGE64-LABEL:  L..C7:
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll
index bbb8e04b67b95e..f9567840a19651 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll
@@ -651,7 +651,8 @@ entry:
 ; SMALL32-NEXT:	 .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL32-NEXT:	 .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL32-LABEL: L..C5:
-; SMALL32-NEXT:	 .tc TIUninit[TC],TIUninit[UL]@ld
+; SMALL32-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
+; SMALL32-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
 ; SMALL32-LABEL: L..C6:
 ; SMALL32-NEXT:	 .tc .TWUninit[TC],TWUninit[TL]@m
 ; SMALL32-LABEL: L..C7:
@@ -669,7 +670,8 @@ entry:
 ; LARGE32-LABEL: L..C3:
 ; LARGE32-NEXT:  .tc TGInit[TE],TGInit[TL]@gd
 ; LARGE32-LABEL: L..C4:
-; LARGE32-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
+; LARGE32-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
+; LARGE32-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
 ; LARGE32-LABEL: L..C5:
 ; LARGE32-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
@@ -693,7 +695,8 @@ entry:
 ; SMALL64-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL64-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL64-LABEL:  L..C5:
-; SMALL64-NEXT:   .tc TIUninit[TC],TIUninit[UL]@ld
+; SMALL64-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
+; SMALL64-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
 ; SMALL64-LABEL:  L..C6:
 ; SMALL64-NEXT:   .tc .TWUninit[TC],TWUninit[TL]@m
 ; SMALL64-LABEL:  L..C7:
@@ -714,7 +717,8 @@ entry:
 ; LARGE64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64-LABEL:  L..C5:
-; LARGE64-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
+; LARGE64-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
+; LARGE64-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
 ; LARGE64-LABEL:  L..C6:
 ; LARGE64-NEXT:  .tc .TWUninit[TE],TWUninit[TL]@m
 ; LARGE64-LABEL:  L..C7:
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll
index ff087a2144488c..06937635bbd183 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll
@@ -687,9 +687,11 @@ entry:
 ; SMALL32-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL32-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL32-LABEL:  L..C3:
-; SMALL32-NEXT:  .tc TIUninit[TC],TIUninit[UL]@ld
+; SMALL32-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
+; SMALL32-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
 ; SMALL32-LABEL:  L..C4:
-; SMALL32-NEXT:  .tc TIInit[TC],TIInit[TL]@ld
+; SMALL32-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
+; SMALL32-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
 ; SMALL32-LABEL:  L..C5:
 ; SMALL32-NEXT:  .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL32-LABEL:  L..C6:
@@ -703,12 +705,14 @@ entry:
 ; LARGE32-LABEL:  L..C1:
 ; LARGE32-NEXT:  .tc TGInit[TE],TGInit[TL]@gd
 ; LARGE32-LABEL:  L..C2:
-; LARGE32-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
+; LARGE32-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
+; LARGE32-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
 ; LARGE32-LABEL:  L..C3:
 ; LARGE32-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE32-LABEL:  L..C4:
-; LARGE32-NEXT:  .tc TIInit[TE],TIInit[TL]@ld
+; LARGE32-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
+; LARGE32-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
 ; LARGE32-LABEL:  L..C5:
 ; LARGE32-NEXT:  .tc .TWInit[TE],TWInit[TL]@m
 ; LARGE32-LABEL:  L..C6:
@@ -725,9 +729,11 @@ entry:
 ; SMALL64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL64-LABEL:  L..C3:
-; SMALL64-NEXT:  .tc TIUninit[TC],TIUninit[UL]@ld
+; SMALL64-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
+; SMALL64-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
 ; SMALL64-LABEL:  L..C4:
-; SMALL64-NEXT:  .tc TIInit[TC],TIInit[TL]@ld
+; SMALL64-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
+; SMALL64-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
 ; SMALL64-LABEL:  L..C5:
 ; SMALL64-NEXT:  .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL64-LABEL:  L..C6:
@@ -744,9 +750,11 @@ entry:
 ; LARGE64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64-LABEL:  L..C3:
-; LARGE64-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
+; LARGE64-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
+; LARGE64-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
 ; LARGE64-LABEL:  L..C4:
-; LARGE64-NEXT:  .tc TIInit[TE],TIInit[TL]@ld
+; LARGE64-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
+; LARGE64-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
 ; LARGE64-LABEL:  L..C5:
 ; LARGE64-NEXT:  .tc .TWInit[TE],TWInit[TL]@m
 ; LARGE64-LABEL:  L..C6:
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll b/llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll
new file mode 100644
index 00000000000000..d92375730a95a7
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll
@@ -0,0 +1,362 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:     --code-model=small < %s | FileCheck %s --check-prefixes=SMALL64,COMMON
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:     --code-model=large < %s | FileCheck %s --check-prefixes=LARGE64,COMMON
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc-ibm-aix-xcoff \
+; RUN:     --code-model=small < %s | FileCheck %s --check-prefixes=SMALL32,COMMON
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc-ibm-aix-xcoff \
+; RUN:     --code-model=large < %s | FileCheck %s --check-prefixes=LARGE32,COMMON
+
+ at _$TLSLD. = thread_local(localdynamic) global i32 42, align 4
+ at _$TLSLD.a = thread_local(localdynamic) global i32 42, align 4
+ at __$TLSLD. = internal thread_local(localdynamic) global i32 42, align 4
+ at _$TLSLD._$TLSLD. = internal thread_local(localdynamic) global i32 42, align 4
+
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
+
+define i32 @loadSym1() {
+; SMALL64-LABEL: loadSym1:
+; SMALL64:       # %bb.0: # %entry
+; SMALL64-NEXT:    mflr 0
+; SMALL64-NEXT:    stdu 1, -48(1)
+; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL64-NEXT:    std 0, 64(1)
+; SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tlsld) @"_$TLSLD."
+; SMALL64-NEXT:    lwzx 3, 3, 4
+; SMALL64-NEXT:    addi 1, 1, 48
+; SMALL64-NEXT:    ld 0, 16(1)
+; SMALL64-NEXT:    mtlr 0
+; SMALL64-NEXT:    blr
+;
+; LARGE64-LABEL: loadSym1:
+; LARGE64:       # %bb.0: # %entry
+; LARGE64-NEXT:    mflr 0
+; LARGE64-NEXT:    stdu 1, -48(1)
+; LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; LARGE64-NEXT:    addis 6, L..C1 at u(2)
+; LARGE64-NEXT:    std 0, 64(1)
+; LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; LARGE64-NEXT:    ld 4, L..C1 at l(6)
+; LARGE64-NEXT:    lwzx 3, 3, 4
+; LARGE64-NEXT:    addi 1, 1, 48
+; LARGE64-NEXT:    ld 0, 16(1)
+; LARGE64-NEXT:    mtlr 0
+; LARGE64-NEXT:    blr
+;
+; SMALL32-LABEL: loadSym1:
+; SMALL32:       # %bb.0: # %entry
+; SMALL32-NEXT:    mflr 0
+; SMALL32-NEXT:    stwu 1, -32(1)
+; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL32-NEXT:    stw 0, 40(1)
+; SMALL32-NEXT:    bla .__tls_get_mod[PR]
+; SMALL32-NEXT:    lwz 4, L..C1(2) # target-flags(ppc-tlsld) @"_$TLSLD."
+; SMALL32-NEXT:    lwzx 3, 3, 4
+; SMALL32-NEXT:    addi 1, 1, 32
+; SMALL32-NEXT:    lwz 0, 8(1)
+; SMALL32-NEXT:    mtlr 0
+; SMALL32-NEXT:    blr
+;
+; LARGE32-LABEL: loadSym1:
+; LARGE32:       # %bb.0: # %entry
+; LARGE32-NEXT:    mflr 0
+; LARGE32-NEXT:    stwu 1, -32(1)
+; LARGE32-NEXT:    stw 0, 40(1)
+; LARGE32-NEXT:    addis 6, L..C0 at u(2)
+; LARGE32-NEXT:    addis 3, L..C1 at u(2)
+; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
+; LARGE32-NEXT:    bla .__tls_get_mod[PR]
+; LARGE32-NEXT:    lwz 4, L..C0 at l(6)
+; LARGE32-NEXT:    lwzx 3, 3, 4
+; LARGE32-NEXT:    addi 1, 1, 32
+; LARGE32-NEXT:    lwz 0, 8(1)
+; LARGE32-NEXT:    mtlr 0
+; LARGE32-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_$TLSLD.)
+  %1 = load i32, ptr %0, align 4
+  ret i32 %1
+}
+
+define i32 @loadSym2() {
+; SMALL64-LABEL: loadSym2:
+; SMALL64:       # %bb.0: # %entry
+; SMALL64-NEXT:    mflr 0
+; SMALL64-NEXT:    stdu 1, -48(1)
+; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL64-NEXT:    std 0, 64(1)
+; SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @"_$TLSLD.a"
+; SMALL64-NEXT:    lwzx 3, 3, 4
+; SMALL64-NEXT:    addi 1, 1, 48
+; SMALL64-NEXT:    ld 0, 16(1)
+; SMALL64-NEXT:    mtlr 0
+; SMALL64-NEXT:    blr
+;
+; LARGE64-LABEL: loadSym2:
+; LARGE64:       # %bb.0: # %entry
+; LARGE64-NEXT:    mflr 0
+; LARGE64-NEXT:    stdu 1, -48(1)
+; LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; LARGE64-NEXT:    addis 6, L..C2 at u(2)
+; LARGE64-NEXT:    std 0, 64(1)
+; LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; LARGE64-NEXT:    ld 4, L..C2 at l(6)
+; LARGE64-NEXT:    lwzx 3, 3, 4
+; LARGE64-NEXT:    addi 1, 1, 48
+; LARGE64-NEXT:    ld 0, 16(1)
+; LARGE64-NEXT:    mtlr 0
+; LARGE64-NEXT:    blr
+;
+; SMALL32-LABEL: loadSym2:
+; SMALL32:       # %bb.0: # %entry
+; SMALL32-NEXT:    mflr 0
+; SMALL32-NEXT:    stwu 1, -32(1)
+; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL32-NEXT:    stw 0, 40(1)
+; SMALL32-NEXT:    bla .__tls_get_mod[PR]
+; SMALL32-NEXT:    lwz 4, L..C2(2) # target-flags(ppc-tlsld) @"_$TLSLD.a"
+; SMALL32-NEXT:    lwzx 3, 3, 4
+; SMALL32-NEXT:    addi 1, 1, 32
+; SMALL32-NEXT:    lwz 0, 8(1)
+; SMALL32-NEXT:    mtlr 0
+; SMALL32-NEXT:    blr
+;
+; LARGE32-LABEL: loadSym2:
+; LARGE32:       # %bb.0: # %entry
+; LARGE32-NEXT:    mflr 0
+; LARGE32-NEXT:    stwu 1, -32(1)
+; LARGE32-NEXT:    stw 0, 40(1)
+; LARGE32-NEXT:    addis 6, L..C2 at u(2)
+; LARGE32-NEXT:    addis 3, L..C1 at u(2)
+; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
+; LARGE32-NEXT:    bla .__tls_get_mod[PR]
+; LARGE32-NEXT:    lwz 4, L..C2 at l(6)
+; LARGE32-NEXT:    lwzx 3, 3, 4
+; LARGE32-NEXT:    addi 1, 1, 32
+; LARGE32-NEXT:    lwz 0, 8(1)
+; LARGE32-NEXT:    mtlr 0
+; LARGE32-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_$TLSLD.a)
+  %1 = load i32, ptr %0, align 4
+  ret i32 %1
+}
+
+define i32 @loadSym3() {
+; SMALL64-LABEL: loadSym3:
+; SMALL64:       # %bb.0: # %entry
+; SMALL64-NEXT:    mflr 0
+; SMALL64-NEXT:    stdu 1, -48(1)
+; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL64-NEXT:    std 0, 64(1)
+; SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @"__$TLSLD."
+; SMALL64-NEXT:    lwzx 3, 3, 4
+; SMALL64-NEXT:    addi 1, 1, 48
+; SMALL64-NEXT:    ld 0, 16(1)
+; SMALL64-NEXT:    mtlr 0
+; SMALL64-NEXT:    blr
+;
+; LARGE64-LABEL: loadSym3:
+; LARGE64:       # %bb.0: # %entry
+; LARGE64-NEXT:    mflr 0
+; LARGE64-NEXT:    stdu 1, -48(1)
+; LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; LARGE64-NEXT:    addis 6, L..C3 at u(2)
+; LARGE64-NEXT:    std 0, 64(1)
+; LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; LARGE64-NEXT:    ld 4, L..C3 at l(6)
+; LARGE64-NEXT:    lwzx 3, 3, 4
+; LARGE64-NEXT:    addi 1, 1, 48
+; LARGE64-NEXT:    ld 0, 16(1)
+; LARGE64-NEXT:    mtlr 0
+; LARGE64-NEXT:    blr
+;
+; SMALL32-LABEL: loadSym3:
+; SMALL32:       # %bb.0: # %entry
+; SMALL32-NEXT:    mflr 0
+; SMALL32-NEXT:    stwu 1, -32(1)
+; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL32-NEXT:    stw 0, 40(1)
+; SMALL32-NEXT:    bla .__tls_get_mod[PR]
+; SMALL32-NEXT:    lwz 4, L..C3(2) # target-flags(ppc-tlsld) @"__$TLSLD."
+; SMALL32-NEXT:    lwzx 3, 3, 4
+; SMALL32-NEXT:    addi 1, 1, 32
+; SMALL32-NEXT:    lwz 0, 8(1)
+; SMALL32-NEXT:    mtlr 0
+; SMALL32-NEXT:    blr
+;
+; LARGE32-LABEL: loadSym3:
+; LARGE32:       # %bb.0: # %entry
+; LARGE32-NEXT:    mflr 0
+; LARGE32-NEXT:    stwu 1, -32(1)
+; LARGE32-NEXT:    stw 0, 40(1)
+; LARGE32-NEXT:    addis 6, L..C3 at u(2)
+; LARGE32-NEXT:    addis 3, L..C1 at u(2)
+; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
+; LARGE32-NEXT:    bla .__tls_get_mod[PR]
+; LARGE32-NEXT:    lwz 4, L..C3 at l(6)
+; LARGE32-NEXT:    lwzx 3, 3, 4
+; LARGE32-NEXT:    addi 1, 1, 32
+; LARGE32-NEXT:    lwz 0, 8(1)
+; LARGE32-NEXT:    mtlr 0
+; LARGE32-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @__$TLSLD.)
+  %1 = load i32, ptr %0, align 4
+  ret i32 %1
+}
+
+define i32 @loadSym4() {
+; SMALL64-LABEL: loadSym4:
+; SMALL64:       # %bb.0: # %entry
+; SMALL64-NEXT:    mflr 0
+; SMALL64-NEXT:    stdu 1, -48(1)
+; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL64-NEXT:    std 0, 64(1)
+; SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @"_$TLSLD._$TLSLD."
+; SMALL64-NEXT:    lwzx 3, 3, 4
+; SMALL64-NEXT:    addi 1, 1, 48
+; SMALL64-NEXT:    ld 0, 16(1)
+; SMALL64-NEXT:    mtlr 0
+; SMALL64-NEXT:    blr
+;
+; LARGE64-LABEL: loadSym4:
+; LARGE64:       # %bb.0: # %entry
+; LARGE64-NEXT:    mflr 0
+; LARGE64-NEXT:    stdu 1, -48(1)
+; LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; LARGE64-NEXT:    addis 6, L..C4 at u(2)
+; LARGE64-NEXT:    std 0, 64(1)
+; LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; LARGE64-NEXT:    ld 4, L..C4 at l(6)
+; LARGE64-NEXT:    lwzx 3, 3, 4
+; LARGE64-NEXT:    addi 1, 1, 48
+; LARGE64-NEXT:    ld 0, 16(1)
+; LARGE64-NEXT:    mtlr 0
+; LARGE64-NEXT:    blr
+;
+; SMALL32-LABEL: loadSym4:
+; SMALL32:       # %bb.0: # %entry
+; SMALL32-NEXT:    mflr 0
+; SMALL32-NEXT:    stwu 1, -32(1)
+; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; SMALL32-NEXT:    stw 0, 40(1)
+; SMALL32-NEXT:    bla .__tls_get_mod[PR]
+; SMALL32-NEXT:    lwz 4, L..C4(2) # target-flags(ppc-tlsld) @"_$TLSLD._$TLSLD."
+; SMALL32-NEXT:    lwzx 3, 3, 4
+; SMALL32-NEXT:    addi 1, 1, 32
+; SMALL32-NEXT:    lwz 0, 8(1)
+; SMALL32-NEXT:    mtlr 0
+; SMALL32-NEXT:    blr
+;
+; LARGE32-LABEL: loadSym4:
+; LARGE32:       # %bb.0: # %entry
+; LARGE32-NEXT:    mflr 0
+; LARGE32-NEXT:    stwu 1, -32(1)
+; LARGE32-NEXT:    stw 0, 40(1)
+; LARGE32-NEXT:    addis 6, L..C4 at u(2)
+; LARGE32-NEXT:    addis 3, L..C1 at u(2)
+; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
+; LARGE32-NEXT:    bla .__tls_get_mod[PR]
+; LARGE32-NEXT:    lwz 4, L..C4 at l(6)
+; LARGE32-NEXT:    lwzx 3, 3, 4
+; LARGE32-NEXT:    addi 1, 1, 32
+; LARGE32-NEXT:    lwz 0, 8(1)
+; LARGE32-NEXT:    mtlr 0
+; LARGE32-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_$TLSLD._$TLSLD.)
+  %1 = load i32, ptr %0, align 4
+  ret i32 %1
+}
+
+; COMMON:      .csect _Renamed..5f24__TLSLD.[TL],2
+; COMMON-NEXT: .globl  _Renamed..5f24__TLSLD.[TL]      # @"_$TLSLD."
+; COMMON-NEXT: .rename _Renamed..5f24__TLSLD.[TL],"_$TLSLD."
+; COMMON:      .csect _Renamed..5f24__TLSLD.a[TL],2
+; COMMON-NEXT: .globl  _Renamed..5f24__TLSLD.a[TL]     # @"_$TLSLD.a"
+; COMMON-NEXT: .rename _Renamed..5f24__TLSLD.a[TL],"_$TLSLD.a"
+; COMMON:      .csect _Renamed..5f5f24___TLSLD.[TL],2
+; COMMON-NEXT: .lglobl _Renamed..5f5f24___TLSLD.[TL]   # @"__$TLSLD."
+; COMMON-NEXT: .rename _Renamed..5f5f24___TLSLD.[TL],"__$TLSLD."
+; COMMON:      .csect _Renamed..5f245f24__TLSLD.__TLSLD.[TL],2
+; COMMON-NEXT: .lglobl _Renamed..5f245f24__TLSLD.__TLSLD.[TL] # @"_$TLSLD._$TLSLD."
+; COMMON-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TL],"_$TLSLD._$TLSLD."
+
+; SMALL64-LABEL: .toc
+; SMALL64-LABEL: L..C0:
+; SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; SMALL64-LABEL: L..C1:
+; SMALL64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TC],_Renamed..5f24__TLSLD.[TL]@ld
+; SMALL64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TC],"_$TLSLD."
+; SMALL64-LABEL: L..C2:
+; SMALL64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],_Renamed..5f24__TLSLD.a[TL]@ld
+; SMALL64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],"_$TLSLD.a"
+; SMALL64-LABEL: L..C3:
+; SMALL64-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],_Renamed..5f5f24___TLSLD.[TL]@ld
+; SMALL64-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],"__$TLSLD."
+; SMALL64-LABEL: L..C4:
+; SMALL64-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
+; SMALL64-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],"_$TLSLD._$TLSLD."
+
+; LARGE64-LABEL: .toc
+; LARGE64-LABEL: L..C0:
+; LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; LARGE64-LABEL: L..C1:
+; LARGE64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TE],_Renamed..5f24__TLSLD.[TL]@ld
+; LARGE64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TE],"_$TLSLD."
+; LARGE64-LABEL: L..C2:
+; LARGE64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],_Renamed..5f24__TLSLD.a[TL]@ld
+; LARGE64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],"_$TLSLD.a"
+; LARGE64-LABEL: L..C3:
+; LARGE64-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],_Renamed..5f5f24___TLSLD.[TL]@ld
+; LARGE64-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],"__$TLSLD."
+; LARGE64-LABEL: L..C4:
+; LARGE64-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
+; LARGE64-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],"_$TLSLD._$TLSLD."
+
+; SMALL32-LABEL: .toc
+; SMALL32-LABEL: L..C0:
+; SMALL32-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; SMALL32-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; SMALL32-LABEL: L..C1:
+; SMALL32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TC],_Renamed..5f24__TLSLD.[TL]@ld
+; SMALL32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TC],"_$TLSLD."
+; SMALL32-LABEL: L..C2:
+; SMALL32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],_Renamed..5f24__TLSLD.a[TL]@ld
+; SMALL32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],"_$TLSLD.a"
+; SMALL32-LABEL: L..C3:
+; SMALL32-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],_Renamed..5f5f24___TLSLD.[TL]@ld
+; SMALL32-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],"__$TLSLD."
+; SMALL32-LABEL: L..C4:
+; SMALL32-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
+; SMALL32-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],"_$TLSLD._$TLSLD."
+
+; LARGE32-LABEL: .toc
+; LARGE32-LABEL: L..C0:
+; LARGE32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TE],_Renamed..5f24__TLSLD.[TL]@ld
+; LARGE32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TE],"_$TLSLD."
+; LARGE32-LABEL: L..C1:
+; LARGE32-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; LARGE32-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; LARGE32-LABEL: L..C2:
+; LARGE32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],_Renamed..5f24__TLSLD.a[TL]@ld
+; LARGE32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],"_$TLSLD.a"
+; LARGE32-LABEL: L..C3:
+; LARGE32-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],_Renamed..5f5f24___TLSLD.[TL]@ld
+; LARGE32-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],"__$TLSLD."
+; LARGE32-LABEL: L..C4:
+; LARGE32-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
+; LARGE32-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],"_$TLSLD._$TLSLD."
+
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll b/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll
index 22349337f18908..d5dc7e57d36328 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll
@@ -358,39 +358,52 @@ entry:
 ; SMALL-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL:        [[TGInitL]]:
-; SMALL-NEXT:   .tc TGInit[TC],TGInit[TL]@ld
+; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TGInit[TC],TGInit[TL]@ld
+; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TGInit[TC],"TGInit"
 ; SMALL:        [[TGUninitL]]:
-; SMALL-NEXT:   .tc TGUninit[TC],TGUninit[TL]@ld
+; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TGUninit[TC],TGUninit[TL]@ld
+; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TGUninit[TC],"TGUninit"
 ; SMALL:        [[TIInitL]]:
-; SMALL-NEXT:   .tc TIInit[TC],TIInit[TL]@ld
+; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
+; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
 ; SMALL:        [[TIUninitL]]:
-; SMALL-NEXT:   .tc TIUninit[TC],TIUninit[UL]@ld
+; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
+; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
 ; SMALL:        [[TWInitL]]:
-; SMALL-NEXT:   .tc TWInit[TC],TWInit[TL]@ld
+; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TWInit[TC],TWInit[TL]@ld
+; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TWInit[TC],"TWInit"
 ; SMALL:        [[TWUninitL]]:
-; SMALL-NEXT:   .tc TWUninit[TC],TWUninit[TL]@ld
+; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TWUninit[TC],TWUninit[TL]@ld
+; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TWUninit[TC],"TWUninit"
 
 ; LARGE64:        [[ModuleHandleL]]:
 ; LARGE64-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64:        [[TGInitL]]:
-; LARGE64-NEXT:   .tc TGInit[TE],TGInit[TL]@ld
+; LARGE64-NEXT:   .tc _Renamed..5f24__TLSLD.TGInit[TE],TGInit[TL]@ld
+; LARGE64-NEXT:   .rename _Renamed..5f24__TLSLD.TGInit[TE],"TGInit"
 ;
 ; LARGE32:        [[TGInitL]]:
-; LARGE32-NEXT:   .tc TGInit[TE],TGInit[TL]@ld
+; LARGE32-NEXT:   .tc _Renamed..5f24__TLSLD.TGInit[TE],TGInit[TL]@ld
+; LARGE32-NEXT:   .rename _Renamed..5f24__TLSLD.TGInit[TE],"TGInit"
 ; LARGE32:        [[ModuleHandleL]]:
 ; LARGE32-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ;
 ; LARGE:        [[TGUninitL]]:
-; LARGE-NEXT:   .tc TGUninit[TE],TGUninit[TL]@ld
+; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TGUninit[TE],TGUninit[TL]@ld
+; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TGUninit[TE],"TGUninit"
 ; LARGE:        [[TIInitL]]:
-; LARGE-NEXT:   .tc TIInit[TE],TIInit[TL]@ld
+; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
+; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
 ; LARGE:        [[TIUninitL]]:
-; LARGE-NEXT:   .tc TIUninit[TE],TIUninit[UL]@ld
+; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
+; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
 ; LARGE:        [[TWInitL]]:
-; LARGE-NEXT:   .tc TWInit[TE],TWInit[TL]@ld
+; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TWInit[TE],TWInit[TL]@ld
+; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TWInit[TE],"TWInit"
 ; LARGE:        [[TWUninitL]]:
-; LARGE-NEXT:   .tc TWUninit[TE],TWUninit[TL]@ld
+; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TWUninit[TE],TWUninit[TL]@ld
+; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TWUninit[TE],"TWUninit"
 
 declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)

>From 7bfa476b52906073629fa5f291e52cbbd7767ada Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Thu, 7 Mar 2024 00:05:03 -0500
Subject: [PATCH 2/9] [NFC] Update comment.

---
 llvm/lib/MC/MCContext.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index b8e96c7b6995d9..ad903657716c64 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -811,6 +811,7 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
   if (IsDwarfSec)
     QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));
   else
+    // For TLS local-dynamic model RenamePrefix is "_$TLSLD.", otherwise empty.
     QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
         RenamePrefix + CachedName + "[" +
         XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));

>From 78c7c14a1ca8e77c888ec621a473cfb304d57e40 Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Thu, 14 Mar 2024 01:41:50 -0400
Subject: [PATCH 3/9] WIP: need check assert

---
 clang/lib/Basic/Targets/PPC.cpp               |  5 +++
 clang/lib/Basic/Targets/PPC.h                 |  1 +
 llvm/lib/Target/PowerPC/PPC.td                |  4 ++
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |  7 ++++
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   | 40 +++++++++++++++++++
 .../Target/PowerPC/PPCMachineFunctionInfo.h   | 12 ++++++
 6 files changed, 69 insertions(+)

diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index aebe51bfa4daad..12eb61aae34441 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -89,6 +89,9 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       IsISA3_1 = true;
     } else if (Feature == "+quadword-atomics") {
       HasQuadwordAtomics = true;
+    } else if (Feature == "+aix-use-tls-initial-exec-for-local-dynamic-in-"
+                          "shared-library") {
+      HasAIXUseTLSIEForLDInSharedLibrary = true;
     }
     // TODO: Finish this list and add an assert that we've handled them
     // all.
@@ -718,6 +721,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
       .Case("isa-v30-instructions", IsISA3_0)
       .Case("isa-v31-instructions", IsISA3_1)
       .Case("quadword-atomics", HasQuadwordAtomics)
+      .Case("aix-use-tls-initial-exec-for-local-dynamic-in-shared-library",
+            HasAIXUseTLSIEForLDInSharedLibrary)
       .Default(false);
 }
 
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index fa2f442e25846d..d583ce9f24185d 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -80,6 +80,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
   bool IsISA3_0 = false;
   bool IsISA3_1 = false;
   bool HasQuadwordAtomics = false;
+  bool HasAIXUseTLSIEForLDInSharedLibrary = false;
 
 protected:
   std::string ABI;
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index b962ed28d72000..36260c73b3ebce 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -338,6 +338,10 @@ def FeatureAIXLocalDynamicTLS :
                    "true", "Produce a faster local-dynamic TLS sequence for this "
                    "function for 64-bit AIX">;
 
+def FeatureAIXUseTLSInitialExecForLocalDynamicInSharedLibraries :
+  SubtargetFeature<"aix-use-tls-initial-exec-for-local-dynamic-in-shared-library", "HasAIXUseTLSIEForLDInSharedLibrary", "true",
+                   "Use TLS initial-exec model for TLS local-dynamic accesses in shared libraries loaded with the main function">;
+
 def FeaturePredictableSelectIsExpensive :
   SubtargetFeature<"predictable-select-expensive",
                    "PredictableSelectIsExpensive",
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 662aac415f5120..b5ffb4094dcdf9 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -878,6 +878,13 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
       if (Model == TLSModel::InitialExec)
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
+      // On AIX, TLS-LD heuristic may have turned LD access into IE access.
+      PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
+      if (Model == TLSModel::LocalDynamic && FuncInfo->isAIXFuncUseTLSIE()) {
+        LLVM_DEBUG(
+            dbgs() << "Current function use IE access for default LD vars.\n");
+        return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
+      }
       llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
     }
     // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d27932f2915fbb..4fbb17d7d10c30 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3374,6 +3374,46 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
   EVT PtrVT = getPointerTy(DAG.getDataLayout());
   bool Is64Bit = Subtarget.isPPC64();
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+  // Initialize heuristic setting lazily:
+  // (1) Use initial-exec for single TLS var reference within current function.
+  // (2) Use local-dynamic for multiple TLS var references within current func.
+  PPCFunctionInfo *FuncInfo =
+      DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
+  if (Subtarget.hasAIXUseTLSIEForLDInSharedLibrary() &&
+      !FuncInfo->isAIXFuncUseInitDone()) {
+    std::set<const GlobalValue *> TLSGV;
+    for (SDNode &Node : DAG.allnodes()) {
+      SDNode *N = &Node;
+      if (N->getOpcode() == ISD::GlobalTLSAddress) {
+        if (GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N)) {
+          const GlobalValue *GV = GA->getGlobal();
+          TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+          if (Model == TLSModel::InitialExec ||
+              Model == TLSModel::LocalDynamic) {
+            TLSGV.insert(GV);
+          }
+        }
+      }
+    }
+    LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGV.size()));
+    if (TLSGV.size() == 1) {
+      FuncInfo->setAIXFuncUseTLSIE();
+    } else if (TLSGV.size() > 1) {
+      FuncInfo->setAIXFuncUseTLSLD();
+    }
+    FuncInfo->setAIXFuncUseInitDone();
+  }
+
+  if (FuncInfo->isAIXFuncUseTLSLD()) {
+    LLVM_DEBUG(dbgs() << DAG.getMachineFunction().getName()
+                      << " function use TLS-LD model for TLS IE/LD vars.\n");
+    Model = TLSModel::LocalDynamic;
+  } else if (FuncInfo->isAIXFuncUseTLSIE()) {
+    LLVM_DEBUG(dbgs() << DAG.getMachineFunction().getName()
+                      << " function use TLS-IE model for TLS IE/LD vars.\n");
+    Model = TLSModel::InitialExec;
+  }
+
   bool IsTLSLocalExecModel = Model == TLSModel::LocalExec;
 
   if (IsTLSLocalExecModel || Model == TLSModel::InitialExec) {
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index df655a3be9512b..03136743358ec0 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -150,6 +150,11 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   /// to use SExt/ZExt flags in later optimization.
   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
 
+  /// FIXME: Flags for heuristic.
+  bool AIXFuncUseTLSLD = false;
+  bool AIXFuncUseTLSIE = false;
+  bool AIXFuncUseInitDone = false;
+
 public:
   explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
 
@@ -221,6 +226,13 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   void setHasFastCall() { HasFastCall = true; }
   bool hasFastCall() const { return HasFastCall;}
 
+  void setAIXFuncUseInitDone() { AIXFuncUseInitDone = true; }
+  bool isAIXFuncUseInitDone() const { return AIXFuncUseInitDone; }
+  void setAIXFuncUseTLSLD() { AIXFuncUseTLSLD = true; }
+  bool isAIXFuncUseTLSLD() const { return AIXFuncUseTLSLD; }
+  void setAIXFuncUseTLSIE() { AIXFuncUseTLSIE = true; }
+  bool isAIXFuncUseTLSIE() const { return AIXFuncUseTLSIE; }
+
   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
 

>From b09a2aa4f658c01e0805a8eef4d62bbc537a0c3d Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Fri, 15 Mar 2024 02:02:52 -0400
Subject: [PATCH 4/9] Reset to try another approach

---
 clang/lib/Basic/Targets/PPC.cpp               |   5 -
 clang/lib/Basic/Targets/PPC.h                 |   1 -
 .../CodeGen/TargetLoweringObjectFileImpl.h    |   5 +-
 llvm/include/llvm/MC/MCContext.h              |   3 +-
 .../llvm/Target/TargetLoweringObjectFile.h    |   6 +-
 llvm/lib/MC/MCContext.cpp                     |   6 +-
 llvm/lib/MC/MCSymbolXCOFF.cpp                 |   6 +-
 .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp  |  15 +-
 llvm/lib/Target/PowerPC/PPC.td                |   4 -
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |  13 +-
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   |  40 --
 .../Target/PowerPC/PPCMachineFunctionInfo.h   |  12 -
 .../test/CodeGen/PowerPC/aix-tls-gd-double.ll |  12 +-
 llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll   |  12 +-
 .../CodeGen/PowerPC/aix-tls-gd-longlong.ll    |  24 +-
 .../PowerPC/aix-tls-ld-unqualified-symbols.ll | 362 ------------------
 .../CodeGen/PowerPC/aix-tls-local-dynamic.ll  |  39 +-
 17 files changed, 41 insertions(+), 524 deletions(-)
 delete mode 100644 llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll

diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 12eb61aae34441..aebe51bfa4daad 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -89,9 +89,6 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       IsISA3_1 = true;
     } else if (Feature == "+quadword-atomics") {
       HasQuadwordAtomics = true;
-    } else if (Feature == "+aix-use-tls-initial-exec-for-local-dynamic-in-"
-                          "shared-library") {
-      HasAIXUseTLSIEForLDInSharedLibrary = true;
     }
     // TODO: Finish this list and add an assert that we've handled them
     // all.
@@ -721,8 +718,6 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
       .Case("isa-v30-instructions", IsISA3_0)
       .Case("isa-v31-instructions", IsISA3_1)
       .Case("quadword-atomics", HasQuadwordAtomics)
-      .Case("aix-use-tls-initial-exec-for-local-dynamic-in-shared-library",
-            HasAIXUseTLSIEForLDInSharedLibrary)
       .Default(false);
 }
 
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index d583ce9f24185d..fa2f442e25846d 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -80,7 +80,6 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
   bool IsISA3_0 = false;
   bool IsISA3_1 = false;
   bool HasQuadwordAtomics = false;
-  bool HasAIXUseTLSIEForLDInSharedLibrary = false;
 
 protected:
   std::string ABI;
diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 1aa25e98423afa..8eef45ce565deb 100644
--- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -279,9 +279,8 @@ class TargetLoweringObjectFileXCOFF : public TargetLoweringObjectFile {
   MCSection *
   getSectionForFunctionDescriptor(const Function *F,
                                   const TargetMachine &TM) const override;
-  MCSection *
-  getSectionForTOCEntry(const MCSymbol *Sym, const TargetMachine &TM,
-                        const MCSymbolRefExpr::VariantKind VK) const override;
+  MCSection *getSectionForTOCEntry(const MCSymbol *Sym,
+                                   const TargetMachine &TM) const override;
 
   /// For external functions, this will always return a function descriptor
   /// csect.
diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h
index 3708b2dff727e4..ef9833cdf2b070 100644
--- a/llvm/include/llvm/MC/MCContext.h
+++ b/llvm/include/llvm/MC/MCContext.h
@@ -691,8 +691,7 @@ class MCContext {
       std::optional<XCOFF::CsectProperties> CsectProp = std::nullopt,
       bool MultiSymbolsAllowed = false, const char *BeginSymName = nullptr,
       std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSubtypeFlags =
-          std::nullopt,
-      StringRef RenamePrefix = StringRef());
+          std::nullopt);
 
   // Create and save a copy of STI and return a reference to the copy.
   MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI);
diff --git a/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index 31a466a18d77a2..0c09cfe684783b 100644
--- a/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -14,7 +14,6 @@
 #ifndef LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
 #define LLVM_TARGET_TARGETLOWERINGOBJECTFILE_H
 
-#include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCObjectFileInfo.h"
 #include "llvm/MC/MCRegister.h"
 #include <cstdint>
@@ -257,9 +256,8 @@ class TargetLoweringObjectFile : public MCObjectFileInfo {
   /// On targets that support TOC entries, return a section for the entry given
   /// the symbol it refers to.
   /// TODO: Implement this interface for existing ELF targets.
-  virtual MCSection *
-  getSectionForTOCEntry(const MCSymbol *S, const TargetMachine &TM,
-                        const MCSymbolRefExpr::VariantKind VK) const {
+  virtual MCSection *getSectionForTOCEntry(const MCSymbol *S,
+                                           const TargetMachine &TM) const {
     return nullptr;
   }
 
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index ad903657716c64..3aee96fdf57fc2 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -785,8 +785,7 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
     StringRef Section, SectionKind Kind,
     std::optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed,
     const char *BeginSymName,
-    std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags,
-    StringRef RenamePrefix) {
+    std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) {
   bool IsDwarfSec = DwarfSectionSubtypeFlags.has_value();
   assert((IsDwarfSec != CsectProp.has_value()) && "Invalid XCOFF section!");
 
@@ -811,9 +810,8 @@ MCSectionXCOFF *MCContext::getXCOFFSection(
   if (IsDwarfSec)
     QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));
   else
-    // For TLS local-dynamic model RenamePrefix is "_$TLSLD.", otherwise empty.
     QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
-        RenamePrefix + CachedName + "[" +
+        CachedName + "[" +
         XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));
 
   MCSymbol *Begin = nullptr;
diff --git a/llvm/lib/MC/MCSymbolXCOFF.cpp b/llvm/lib/MC/MCSymbolXCOFF.cpp
index 17f0bcf77745af..b4c96a1ffa2333 100644
--- a/llvm/lib/MC/MCSymbolXCOFF.cpp
+++ b/llvm/lib/MC/MCSymbolXCOFF.cpp
@@ -24,11 +24,7 @@ void MCSymbolXCOFF::setRepresentedCsect(MCSectionXCOFF *C) {
   assert((!RepresentedCsect || RepresentedCsect == C) &&
          "Trying to set a csect that doesn't match the one that this symbol is "
          "already mapped to.");
-  // Csect representation related symbols access by using TLS local-dynamic
-  // model have prefix "_$TLSLD." before their names.
-  assert((getSymbolTableName().equals(C->getSymbolTableName()) ||
-          getSymbolTableName().equals(std::string("_$TLSLD.") +
-                                      C->getSymbolTableName().str())) &&
+  assert(getSymbolTableName().equals(C->getSymbolTableName()) &&
          "SymbolTableNames need to be the same for this symbol and its csect "
          "representation.");
   RepresentedCsect = C;
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
index 0263c3588a2283..b849b7be7b7be8 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp
@@ -231,20 +231,6 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
       MCSymbolXCOFF *TCSym =
           cast<MCSectionXCOFF>(Streamer.getCurrentSectionOnly())
               ->getQualNameSymbol();
-
-      // On AIX, symbol accessed using TLS local-dynamic model has been renamed
-      // by adding prefix "_$TLSLD.". Do assert that it has been renamed, and
-      // then emit the .rename with the original symbol name.
-      if (Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD) {
-        assert(TCSym->hasRename());
-        OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
-           << MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
-        StringRef Lhs, Rhs;
-        std::tie(Lhs, Rhs) = TCSym->getSymbolTableName().split("_$TLSLD.");
-        Streamer.emitXCOFFRenameDirective(TCSym, Rhs);
-        return;
-      }
-
       // On AIX, we have TLS variable offsets (symbol@({gd|ie|le|ld}) depending
       // on the TLS access method (or model). For the general-dynamic access
       // method, we also have region handle (symbol at m) for each variable. For
@@ -256,6 +242,7 @@ class PPCTargetAsmStreamer : public PPCTargetStreamer {
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE ||
+          Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD ||
           Kind == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML)
         OS << "\t.tc " << TCSym->getName() << "," << XSym->getName() << "@"
            << MCSymbolRefExpr::getVariantKindName(Kind) << '\n';
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index 36260c73b3ebce..b962ed28d72000 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -338,10 +338,6 @@ def FeatureAIXLocalDynamicTLS :
                    "true", "Produce a faster local-dynamic TLS sequence for this "
                    "function for 64-bit AIX">;
 
-def FeatureAIXUseTLSInitialExecForLocalDynamicInSharedLibraries :
-  SubtargetFeature<"aix-use-tls-initial-exec-for-local-dynamic-in-shared-library", "HasAIXUseTLSIEForLDInSharedLibrary", "true",
-                   "Use TLS initial-exec model for TLS local-dynamic accesses in shared libraries loaded with the main function">;
-
 def FeaturePredictableSelectIsExpensive :
   SubtargetFeature<"predictable-select-expensive",
                    "PredictableSelectIsExpensive",
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index b5ffb4094dcdf9..6e1002c45d81cb 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -878,13 +878,6 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
       if (Model == TLSModel::InitialExec)
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
-      // On AIX, TLS-LD heuristic may have turned LD access into IE access.
-      PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
-      if (Model == TLSModel::LocalDynamic && FuncInfo->isAIXFuncUseTLSIE()) {
-        LLVM_DEBUG(
-            dbgs() << "Current function use IE access for default LD vars.\n");
-        return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
-      }
       llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
     }
     // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
@@ -2963,10 +2956,10 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
       Name += cast<MCSymbolXCOFF>(I.first.first)->getSymbolTableName();
       MCSymbol *S = OutContext.getOrCreateSymbol(Name);
       TCEntry = cast<MCSectionXCOFF>(
-          getObjFileLowering().getSectionForTOCEntry(S, TM, I.first.second));
+          getObjFileLowering().getSectionForTOCEntry(S, TM));
     } else {
-      TCEntry = cast<MCSectionXCOFF>(getObjFileLowering().getSectionForTOCEntry(
-          I.first.first, TM, I.first.second));
+      TCEntry = cast<MCSectionXCOFF>(
+          getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
     }
     OutStreamer->switchSection(TCEntry);
 
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 4fbb17d7d10c30..d27932f2915fbb 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3374,46 +3374,6 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
   EVT PtrVT = getPointerTy(DAG.getDataLayout());
   bool Is64Bit = Subtarget.isPPC64();
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
-  // Initialize heuristic setting lazily:
-  // (1) Use initial-exec for single TLS var reference within current function.
-  // (2) Use local-dynamic for multiple TLS var references within current func.
-  PPCFunctionInfo *FuncInfo =
-      DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
-  if (Subtarget.hasAIXUseTLSIEForLDInSharedLibrary() &&
-      !FuncInfo->isAIXFuncUseInitDone()) {
-    std::set<const GlobalValue *> TLSGV;
-    for (SDNode &Node : DAG.allnodes()) {
-      SDNode *N = &Node;
-      if (N->getOpcode() == ISD::GlobalTLSAddress) {
-        if (GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N)) {
-          const GlobalValue *GV = GA->getGlobal();
-          TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
-          if (Model == TLSModel::InitialExec ||
-              Model == TLSModel::LocalDynamic) {
-            TLSGV.insert(GV);
-          }
-        }
-      }
-    }
-    LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGV.size()));
-    if (TLSGV.size() == 1) {
-      FuncInfo->setAIXFuncUseTLSIE();
-    } else if (TLSGV.size() > 1) {
-      FuncInfo->setAIXFuncUseTLSLD();
-    }
-    FuncInfo->setAIXFuncUseInitDone();
-  }
-
-  if (FuncInfo->isAIXFuncUseTLSLD()) {
-    LLVM_DEBUG(dbgs() << DAG.getMachineFunction().getName()
-                      << " function use TLS-LD model for TLS IE/LD vars.\n");
-    Model = TLSModel::LocalDynamic;
-  } else if (FuncInfo->isAIXFuncUseTLSIE()) {
-    LLVM_DEBUG(dbgs() << DAG.getMachineFunction().getName()
-                      << " function use TLS-IE model for TLS IE/LD vars.\n");
-    Model = TLSModel::InitialExec;
-  }
-
   bool IsTLSLocalExecModel = Model == TLSModel::LocalExec;
 
   if (IsTLSLocalExecModel || Model == TLSModel::InitialExec) {
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index 03136743358ec0..df655a3be9512b 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -150,11 +150,6 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   /// to use SExt/ZExt flags in later optimization.
   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
 
-  /// FIXME: Flags for heuristic.
-  bool AIXFuncUseTLSLD = false;
-  bool AIXFuncUseTLSIE = false;
-  bool AIXFuncUseInitDone = false;
-
 public:
   explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
 
@@ -226,13 +221,6 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   void setHasFastCall() { HasFastCall = true; }
   bool hasFastCall() const { return HasFastCall;}
 
-  void setAIXFuncUseInitDone() { AIXFuncUseInitDone = true; }
-  bool isAIXFuncUseInitDone() const { return AIXFuncUseInitDone; }
-  void setAIXFuncUseTLSLD() { AIXFuncUseTLSLD = true; }
-  bool isAIXFuncUseTLSLD() const { return AIXFuncUseTLSLD; }
-  void setAIXFuncUseTLSIE() { AIXFuncUseTLSIE = true; }
-  bool isAIXFuncUseTLSIE() const { return AIXFuncUseTLSIE; }
-
   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
 
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll
index d84f92b11c9781..ae41b6b1301064 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-double.ll
@@ -636,8 +636,7 @@ entry:
 ; SMALL32-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL32-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL32-LABEL:  L..C5:
-; SMALL32-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
-; SMALL32-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
+; SMALL32-NEXT:   .tc TIInit[TC],TIInit[TL]@ld
 ; SMALL32-LABEL:  L..C6:
 ; SMALL32-NEXT:   .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL32-LABEL:  L..C7:
@@ -655,8 +654,7 @@ entry:
 ; LARGE32-LABEL:  L..C3:
 ; LARGE32-NEXT:   .tc TGInit[TE],TGInit[TL]@gd
 ; LARGE32-LABEL:  L..C4:
-; LARGE32-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
-; LARGE32-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
+; LARGE32-NEXT:   .tc TIInit[TE],TIInit[TL]@ld
 ; LARGE32-LABEL:  L..C5:
 ; LARGE32-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
@@ -680,8 +678,7 @@ entry:
 ; SMALL64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL64-LABEL:  L..C5:
-; SMALL64-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
-; SMALL64-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
+; SMALL64-NEXT:  .tc TIInit[TC],TIInit[TL]@ld
 ; SMALL64-LABEL:  L..C6:
 ; SMALL64-NEXT:  .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL64-LABEL:  L..C7:
@@ -702,8 +699,7 @@ entry:
 ; LARGE64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64-LABEL:  L..C5:
-; LARGE64-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
-; LARGE64-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
+; LARGE64-NEXT:  .tc TIInit[TE],TIInit[TL]@ld
 ; LARGE64-LABEL:  L..C6:
 ; LARGE64-NEXT:  .tc .TWInit[TE],TWInit[TL]@m
 ; LARGE64-LABEL:  L..C7:
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll
index f9567840a19651..bbb8e04b67b95e 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-int.ll
@@ -651,8 +651,7 @@ entry:
 ; SMALL32-NEXT:	 .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL32-NEXT:	 .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL32-LABEL: L..C5:
-; SMALL32-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
-; SMALL32-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
+; SMALL32-NEXT:	 .tc TIUninit[TC],TIUninit[UL]@ld
 ; SMALL32-LABEL: L..C6:
 ; SMALL32-NEXT:	 .tc .TWUninit[TC],TWUninit[TL]@m
 ; SMALL32-LABEL: L..C7:
@@ -670,8 +669,7 @@ entry:
 ; LARGE32-LABEL: L..C3:
 ; LARGE32-NEXT:  .tc TGInit[TE],TGInit[TL]@gd
 ; LARGE32-LABEL: L..C4:
-; LARGE32-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
-; LARGE32-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
+; LARGE32-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
 ; LARGE32-LABEL: L..C5:
 ; LARGE32-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
@@ -695,8 +693,7 @@ entry:
 ; SMALL64-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL64-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL64-LABEL:  L..C5:
-; SMALL64-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
-; SMALL64-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
+; SMALL64-NEXT:   .tc TIUninit[TC],TIUninit[UL]@ld
 ; SMALL64-LABEL:  L..C6:
 ; SMALL64-NEXT:   .tc .TWUninit[TC],TWUninit[TL]@m
 ; SMALL64-LABEL:  L..C7:
@@ -717,8 +714,7 @@ entry:
 ; LARGE64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64-LABEL:  L..C5:
-; LARGE64-NEXT:	 .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
-; LARGE64-NEXT:	 .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
+; LARGE64-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
 ; LARGE64-LABEL:  L..C6:
 ; LARGE64-NEXT:  .tc .TWUninit[TE],TWUninit[TL]@m
 ; LARGE64-LABEL:  L..C7:
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll b/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll
index 06937635bbd183..ff087a2144488c 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll
@@ -687,11 +687,9 @@ entry:
 ; SMALL32-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL32-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL32-LABEL:  L..C3:
-; SMALL32-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
-; SMALL32-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
+; SMALL32-NEXT:  .tc TIUninit[TC],TIUninit[UL]@ld
 ; SMALL32-LABEL:  L..C4:
-; SMALL32-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
-; SMALL32-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
+; SMALL32-NEXT:  .tc TIInit[TC],TIInit[TL]@ld
 ; SMALL32-LABEL:  L..C5:
 ; SMALL32-NEXT:  .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL32-LABEL:  L..C6:
@@ -705,14 +703,12 @@ entry:
 ; LARGE32-LABEL:  L..C1:
 ; LARGE32-NEXT:  .tc TGInit[TE],TGInit[TL]@gd
 ; LARGE32-LABEL:  L..C2:
-; LARGE32-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
-; LARGE32-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
+; LARGE32-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
 ; LARGE32-LABEL:  L..C3:
 ; LARGE32-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE32-LABEL:  L..C4:
-; LARGE32-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
-; LARGE32-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
+; LARGE32-NEXT:  .tc TIInit[TE],TIInit[TL]@ld
 ; LARGE32-LABEL:  L..C5:
 ; LARGE32-NEXT:  .tc .TWInit[TE],TWInit[TL]@m
 ; LARGE32-LABEL:  L..C6:
@@ -729,11 +725,9 @@ entry:
 ; SMALL64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL64-LABEL:  L..C3:
-; SMALL64-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
-; SMALL64-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
+; SMALL64-NEXT:  .tc TIUninit[TC],TIUninit[UL]@ld
 ; SMALL64-LABEL:  L..C4:
-; SMALL64-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
-; SMALL64-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
+; SMALL64-NEXT:  .tc TIInit[TC],TIInit[TL]@ld
 ; SMALL64-LABEL:  L..C5:
 ; SMALL64-NEXT:  .tc .TWInit[TC],TWInit[TL]@m
 ; SMALL64-LABEL:  L..C6:
@@ -750,11 +744,9 @@ entry:
 ; LARGE64-NEXT:  .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:  .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64-LABEL:  L..C3:
-; LARGE64-NEXT:  .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
-; LARGE64-NEXT:  .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
+; LARGE64-NEXT:  .tc TIUninit[TE],TIUninit[UL]@ld
 ; LARGE64-LABEL:  L..C4:
-; LARGE64-NEXT:  .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
-; LARGE64-NEXT:  .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
+; LARGE64-NEXT:  .tc TIInit[TE],TIInit[TL]@ld
 ; LARGE64-LABEL:  L..C5:
 ; LARGE64-NEXT:  .tc .TWInit[TE],TWInit[TL]@m
 ; LARGE64-LABEL:  L..C6:
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll b/llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll
deleted file mode 100644
index d92375730a95a7..00000000000000
--- a/llvm/test/CodeGen/PowerPC/aix-tls-ld-unqualified-symbols.ll
+++ /dev/null
@@ -1,362 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:     --code-model=small < %s | FileCheck %s --check-prefixes=SMALL64,COMMON
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:     --code-model=large < %s | FileCheck %s --check-prefixes=LARGE64,COMMON
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc-ibm-aix-xcoff \
-; RUN:     --code-model=small < %s | FileCheck %s --check-prefixes=SMALL32,COMMON
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc-ibm-aix-xcoff \
-; RUN:     --code-model=large < %s | FileCheck %s --check-prefixes=LARGE32,COMMON
-
- at _$TLSLD. = thread_local(localdynamic) global i32 42, align 4
- at _$TLSLD.a = thread_local(localdynamic) global i32 42, align 4
- at __$TLSLD. = internal thread_local(localdynamic) global i32 42, align 4
- at _$TLSLD._$TLSLD. = internal thread_local(localdynamic) global i32 42, align 4
-
-declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
-
-define i32 @loadSym1() {
-; SMALL64-LABEL: loadSym1:
-; SMALL64:       # %bb.0: # %entry
-; SMALL64-NEXT:    mflr 0
-; SMALL64-NEXT:    stdu 1, -48(1)
-; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL64-NEXT:    std 0, 64(1)
-; SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tlsld) @"_$TLSLD."
-; SMALL64-NEXT:    lwzx 3, 3, 4
-; SMALL64-NEXT:    addi 1, 1, 48
-; SMALL64-NEXT:    ld 0, 16(1)
-; SMALL64-NEXT:    mtlr 0
-; SMALL64-NEXT:    blr
-;
-; LARGE64-LABEL: loadSym1:
-; LARGE64:       # %bb.0: # %entry
-; LARGE64-NEXT:    mflr 0
-; LARGE64-NEXT:    stdu 1, -48(1)
-; LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; LARGE64-NEXT:    addis 6, L..C1 at u(2)
-; LARGE64-NEXT:    std 0, 64(1)
-; LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; LARGE64-NEXT:    ld 4, L..C1 at l(6)
-; LARGE64-NEXT:    lwzx 3, 3, 4
-; LARGE64-NEXT:    addi 1, 1, 48
-; LARGE64-NEXT:    ld 0, 16(1)
-; LARGE64-NEXT:    mtlr 0
-; LARGE64-NEXT:    blr
-;
-; SMALL32-LABEL: loadSym1:
-; SMALL32:       # %bb.0: # %entry
-; SMALL32-NEXT:    mflr 0
-; SMALL32-NEXT:    stwu 1, -32(1)
-; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL32-NEXT:    stw 0, 40(1)
-; SMALL32-NEXT:    bla .__tls_get_mod[PR]
-; SMALL32-NEXT:    lwz 4, L..C1(2) # target-flags(ppc-tlsld) @"_$TLSLD."
-; SMALL32-NEXT:    lwzx 3, 3, 4
-; SMALL32-NEXT:    addi 1, 1, 32
-; SMALL32-NEXT:    lwz 0, 8(1)
-; SMALL32-NEXT:    mtlr 0
-; SMALL32-NEXT:    blr
-;
-; LARGE32-LABEL: loadSym1:
-; LARGE32:       # %bb.0: # %entry
-; LARGE32-NEXT:    mflr 0
-; LARGE32-NEXT:    stwu 1, -32(1)
-; LARGE32-NEXT:    stw 0, 40(1)
-; LARGE32-NEXT:    addis 6, L..C0 at u(2)
-; LARGE32-NEXT:    addis 3, L..C1 at u(2)
-; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
-; LARGE32-NEXT:    bla .__tls_get_mod[PR]
-; LARGE32-NEXT:    lwz 4, L..C0 at l(6)
-; LARGE32-NEXT:    lwzx 3, 3, 4
-; LARGE32-NEXT:    addi 1, 1, 32
-; LARGE32-NEXT:    lwz 0, 8(1)
-; LARGE32-NEXT:    mtlr 0
-; LARGE32-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_$TLSLD.)
-  %1 = load i32, ptr %0, align 4
-  ret i32 %1
-}
-
-define i32 @loadSym2() {
-; SMALL64-LABEL: loadSym2:
-; SMALL64:       # %bb.0: # %entry
-; SMALL64-NEXT:    mflr 0
-; SMALL64-NEXT:    stdu 1, -48(1)
-; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL64-NEXT:    std 0, 64(1)
-; SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @"_$TLSLD.a"
-; SMALL64-NEXT:    lwzx 3, 3, 4
-; SMALL64-NEXT:    addi 1, 1, 48
-; SMALL64-NEXT:    ld 0, 16(1)
-; SMALL64-NEXT:    mtlr 0
-; SMALL64-NEXT:    blr
-;
-; LARGE64-LABEL: loadSym2:
-; LARGE64:       # %bb.0: # %entry
-; LARGE64-NEXT:    mflr 0
-; LARGE64-NEXT:    stdu 1, -48(1)
-; LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; LARGE64-NEXT:    addis 6, L..C2 at u(2)
-; LARGE64-NEXT:    std 0, 64(1)
-; LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; LARGE64-NEXT:    ld 4, L..C2 at l(6)
-; LARGE64-NEXT:    lwzx 3, 3, 4
-; LARGE64-NEXT:    addi 1, 1, 48
-; LARGE64-NEXT:    ld 0, 16(1)
-; LARGE64-NEXT:    mtlr 0
-; LARGE64-NEXT:    blr
-;
-; SMALL32-LABEL: loadSym2:
-; SMALL32:       # %bb.0: # %entry
-; SMALL32-NEXT:    mflr 0
-; SMALL32-NEXT:    stwu 1, -32(1)
-; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL32-NEXT:    stw 0, 40(1)
-; SMALL32-NEXT:    bla .__tls_get_mod[PR]
-; SMALL32-NEXT:    lwz 4, L..C2(2) # target-flags(ppc-tlsld) @"_$TLSLD.a"
-; SMALL32-NEXT:    lwzx 3, 3, 4
-; SMALL32-NEXT:    addi 1, 1, 32
-; SMALL32-NEXT:    lwz 0, 8(1)
-; SMALL32-NEXT:    mtlr 0
-; SMALL32-NEXT:    blr
-;
-; LARGE32-LABEL: loadSym2:
-; LARGE32:       # %bb.0: # %entry
-; LARGE32-NEXT:    mflr 0
-; LARGE32-NEXT:    stwu 1, -32(1)
-; LARGE32-NEXT:    stw 0, 40(1)
-; LARGE32-NEXT:    addis 6, L..C2 at u(2)
-; LARGE32-NEXT:    addis 3, L..C1 at u(2)
-; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
-; LARGE32-NEXT:    bla .__tls_get_mod[PR]
-; LARGE32-NEXT:    lwz 4, L..C2 at l(6)
-; LARGE32-NEXT:    lwzx 3, 3, 4
-; LARGE32-NEXT:    addi 1, 1, 32
-; LARGE32-NEXT:    lwz 0, 8(1)
-; LARGE32-NEXT:    mtlr 0
-; LARGE32-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_$TLSLD.a)
-  %1 = load i32, ptr %0, align 4
-  ret i32 %1
-}
-
-define i32 @loadSym3() {
-; SMALL64-LABEL: loadSym3:
-; SMALL64:       # %bb.0: # %entry
-; SMALL64-NEXT:    mflr 0
-; SMALL64-NEXT:    stdu 1, -48(1)
-; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL64-NEXT:    std 0, 64(1)
-; SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @"__$TLSLD."
-; SMALL64-NEXT:    lwzx 3, 3, 4
-; SMALL64-NEXT:    addi 1, 1, 48
-; SMALL64-NEXT:    ld 0, 16(1)
-; SMALL64-NEXT:    mtlr 0
-; SMALL64-NEXT:    blr
-;
-; LARGE64-LABEL: loadSym3:
-; LARGE64:       # %bb.0: # %entry
-; LARGE64-NEXT:    mflr 0
-; LARGE64-NEXT:    stdu 1, -48(1)
-; LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; LARGE64-NEXT:    addis 6, L..C3 at u(2)
-; LARGE64-NEXT:    std 0, 64(1)
-; LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; LARGE64-NEXT:    ld 4, L..C3 at l(6)
-; LARGE64-NEXT:    lwzx 3, 3, 4
-; LARGE64-NEXT:    addi 1, 1, 48
-; LARGE64-NEXT:    ld 0, 16(1)
-; LARGE64-NEXT:    mtlr 0
-; LARGE64-NEXT:    blr
-;
-; SMALL32-LABEL: loadSym3:
-; SMALL32:       # %bb.0: # %entry
-; SMALL32-NEXT:    mflr 0
-; SMALL32-NEXT:    stwu 1, -32(1)
-; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL32-NEXT:    stw 0, 40(1)
-; SMALL32-NEXT:    bla .__tls_get_mod[PR]
-; SMALL32-NEXT:    lwz 4, L..C3(2) # target-flags(ppc-tlsld) @"__$TLSLD."
-; SMALL32-NEXT:    lwzx 3, 3, 4
-; SMALL32-NEXT:    addi 1, 1, 32
-; SMALL32-NEXT:    lwz 0, 8(1)
-; SMALL32-NEXT:    mtlr 0
-; SMALL32-NEXT:    blr
-;
-; LARGE32-LABEL: loadSym3:
-; LARGE32:       # %bb.0: # %entry
-; LARGE32-NEXT:    mflr 0
-; LARGE32-NEXT:    stwu 1, -32(1)
-; LARGE32-NEXT:    stw 0, 40(1)
-; LARGE32-NEXT:    addis 6, L..C3 at u(2)
-; LARGE32-NEXT:    addis 3, L..C1 at u(2)
-; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
-; LARGE32-NEXT:    bla .__tls_get_mod[PR]
-; LARGE32-NEXT:    lwz 4, L..C3 at l(6)
-; LARGE32-NEXT:    lwzx 3, 3, 4
-; LARGE32-NEXT:    addi 1, 1, 32
-; LARGE32-NEXT:    lwz 0, 8(1)
-; LARGE32-NEXT:    mtlr 0
-; LARGE32-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @__$TLSLD.)
-  %1 = load i32, ptr %0, align 4
-  ret i32 %1
-}
-
-define i32 @loadSym4() {
-; SMALL64-LABEL: loadSym4:
-; SMALL64:       # %bb.0: # %entry
-; SMALL64-NEXT:    mflr 0
-; SMALL64-NEXT:    stdu 1, -48(1)
-; SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL64-NEXT:    std 0, 64(1)
-; SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @"_$TLSLD._$TLSLD."
-; SMALL64-NEXT:    lwzx 3, 3, 4
-; SMALL64-NEXT:    addi 1, 1, 48
-; SMALL64-NEXT:    ld 0, 16(1)
-; SMALL64-NEXT:    mtlr 0
-; SMALL64-NEXT:    blr
-;
-; LARGE64-LABEL: loadSym4:
-; LARGE64:       # %bb.0: # %entry
-; LARGE64-NEXT:    mflr 0
-; LARGE64-NEXT:    stdu 1, -48(1)
-; LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; LARGE64-NEXT:    addis 6, L..C4 at u(2)
-; LARGE64-NEXT:    std 0, 64(1)
-; LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; LARGE64-NEXT:    ld 4, L..C4 at l(6)
-; LARGE64-NEXT:    lwzx 3, 3, 4
-; LARGE64-NEXT:    addi 1, 1, 48
-; LARGE64-NEXT:    ld 0, 16(1)
-; LARGE64-NEXT:    mtlr 0
-; LARGE64-NEXT:    blr
-;
-; SMALL32-LABEL: loadSym4:
-; SMALL32:       # %bb.0: # %entry
-; SMALL32-NEXT:    mflr 0
-; SMALL32-NEXT:    stwu 1, -32(1)
-; SMALL32-NEXT:    lwz 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; SMALL32-NEXT:    stw 0, 40(1)
-; SMALL32-NEXT:    bla .__tls_get_mod[PR]
-; SMALL32-NEXT:    lwz 4, L..C4(2) # target-flags(ppc-tlsld) @"_$TLSLD._$TLSLD."
-; SMALL32-NEXT:    lwzx 3, 3, 4
-; SMALL32-NEXT:    addi 1, 1, 32
-; SMALL32-NEXT:    lwz 0, 8(1)
-; SMALL32-NEXT:    mtlr 0
-; SMALL32-NEXT:    blr
-;
-; LARGE32-LABEL: loadSym4:
-; LARGE32:       # %bb.0: # %entry
-; LARGE32-NEXT:    mflr 0
-; LARGE32-NEXT:    stwu 1, -32(1)
-; LARGE32-NEXT:    stw 0, 40(1)
-; LARGE32-NEXT:    addis 6, L..C4 at u(2)
-; LARGE32-NEXT:    addis 3, L..C1 at u(2)
-; LARGE32-NEXT:    lwz 3, L..C1 at l(3)
-; LARGE32-NEXT:    bla .__tls_get_mod[PR]
-; LARGE32-NEXT:    lwz 4, L..C4 at l(6)
-; LARGE32-NEXT:    lwzx 3, 3, 4
-; LARGE32-NEXT:    addi 1, 1, 32
-; LARGE32-NEXT:    lwz 0, 8(1)
-; LARGE32-NEXT:    mtlr 0
-; LARGE32-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @_$TLSLD._$TLSLD.)
-  %1 = load i32, ptr %0, align 4
-  ret i32 %1
-}
-
-; COMMON:      .csect _Renamed..5f24__TLSLD.[TL],2
-; COMMON-NEXT: .globl  _Renamed..5f24__TLSLD.[TL]      # @"_$TLSLD."
-; COMMON-NEXT: .rename _Renamed..5f24__TLSLD.[TL],"_$TLSLD."
-; COMMON:      .csect _Renamed..5f24__TLSLD.a[TL],2
-; COMMON-NEXT: .globl  _Renamed..5f24__TLSLD.a[TL]     # @"_$TLSLD.a"
-; COMMON-NEXT: .rename _Renamed..5f24__TLSLD.a[TL],"_$TLSLD.a"
-; COMMON:      .csect _Renamed..5f5f24___TLSLD.[TL],2
-; COMMON-NEXT: .lglobl _Renamed..5f5f24___TLSLD.[TL]   # @"__$TLSLD."
-; COMMON-NEXT: .rename _Renamed..5f5f24___TLSLD.[TL],"__$TLSLD."
-; COMMON:      .csect _Renamed..5f245f24__TLSLD.__TLSLD.[TL],2
-; COMMON-NEXT: .lglobl _Renamed..5f245f24__TLSLD.__TLSLD.[TL] # @"_$TLSLD._$TLSLD."
-; COMMON-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TL],"_$TLSLD._$TLSLD."
-
-; SMALL64-LABEL: .toc
-; SMALL64-LABEL: L..C0:
-; SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; SMALL64-LABEL: L..C1:
-; SMALL64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TC],_Renamed..5f24__TLSLD.[TL]@ld
-; SMALL64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TC],"_$TLSLD."
-; SMALL64-LABEL: L..C2:
-; SMALL64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],_Renamed..5f24__TLSLD.a[TL]@ld
-; SMALL64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],"_$TLSLD.a"
-; SMALL64-LABEL: L..C3:
-; SMALL64-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],_Renamed..5f5f24___TLSLD.[TL]@ld
-; SMALL64-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],"__$TLSLD."
-; SMALL64-LABEL: L..C4:
-; SMALL64-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
-; SMALL64-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],"_$TLSLD._$TLSLD."
-
-; LARGE64-LABEL: .toc
-; LARGE64-LABEL: L..C0:
-; LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; LARGE64-LABEL: L..C1:
-; LARGE64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TE],_Renamed..5f24__TLSLD.[TL]@ld
-; LARGE64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TE],"_$TLSLD."
-; LARGE64-LABEL: L..C2:
-; LARGE64-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],_Renamed..5f24__TLSLD.a[TL]@ld
-; LARGE64-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],"_$TLSLD.a"
-; LARGE64-LABEL: L..C3:
-; LARGE64-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],_Renamed..5f5f24___TLSLD.[TL]@ld
-; LARGE64-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],"__$TLSLD."
-; LARGE64-LABEL: L..C4:
-; LARGE64-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
-; LARGE64-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],"_$TLSLD._$TLSLD."
-
-; SMALL32-LABEL: .toc
-; SMALL32-LABEL: L..C0:
-; SMALL32-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; SMALL32-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; SMALL32-LABEL: L..C1:
-; SMALL32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TC],_Renamed..5f24__TLSLD.[TL]@ld
-; SMALL32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TC],"_$TLSLD."
-; SMALL32-LABEL: L..C2:
-; SMALL32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],_Renamed..5f24__TLSLD.a[TL]@ld
-; SMALL32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TC],"_$TLSLD.a"
-; SMALL32-LABEL: L..C3:
-; SMALL32-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],_Renamed..5f5f24___TLSLD.[TL]@ld
-; SMALL32-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TC],"__$TLSLD."
-; SMALL32-LABEL: L..C4:
-; SMALL32-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
-; SMALL32-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TC],"_$TLSLD._$TLSLD."
-
-; LARGE32-LABEL: .toc
-; LARGE32-LABEL: L..C0:
-; LARGE32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.[TE],_Renamed..5f24__TLSLD.[TL]@ld
-; LARGE32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.[TE],"_$TLSLD."
-; LARGE32-LABEL: L..C1:
-; LARGE32-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; LARGE32-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; LARGE32-LABEL: L..C2:
-; LARGE32-NEXT: .tc _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],_Renamed..5f24__TLSLD.a[TL]@ld
-; LARGE32-NEXT: .rename _Renamed..5f245f24__TLSLD.__TLSLD.a[TE],"_$TLSLD.a"
-; LARGE32-LABEL: L..C3:
-; LARGE32-NEXT: .tc _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],_Renamed..5f5f24___TLSLD.[TL]@ld
-; LARGE32-NEXT: .rename _Renamed..5f245f5f24__TLSLD.___TLSLD.[TE],"__$TLSLD."
-; LARGE32-LABEL: L..C4:
-; LARGE32-NEXT: .tc _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],_Renamed..5f245f24__TLSLD.__TLSLD.[TL]@ld
-; LARGE32-NEXT: .rename _Renamed..5f245f245f24__TLSLD.__TLSLD.__TLSLD.[TE],"_$TLSLD._$TLSLD."
-
diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll b/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll
index d5dc7e57d36328..22349337f18908 100644
--- a/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-tls-local-dynamic.ll
@@ -358,52 +358,39 @@ entry:
 ; SMALL-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; SMALL-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; SMALL:        [[TGInitL]]:
-; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TGInit[TC],TGInit[TL]@ld
-; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TGInit[TC],"TGInit"
+; SMALL-NEXT:   .tc TGInit[TC],TGInit[TL]@ld
 ; SMALL:        [[TGUninitL]]:
-; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TGUninit[TC],TGUninit[TL]@ld
-; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TGUninit[TC],"TGUninit"
+; SMALL-NEXT:   .tc TGUninit[TC],TGUninit[TL]@ld
 ; SMALL:        [[TIInitL]]:
-; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TC],TIInit[TL]@ld
-; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TC],"TIInit"
+; SMALL-NEXT:   .tc TIInit[TC],TIInit[TL]@ld
 ; SMALL:        [[TIUninitL]]:
-; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TIUninit[TC],TIUninit[UL]@ld
-; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TIUninit[TC],"TIUninit"
+; SMALL-NEXT:   .tc TIUninit[TC],TIUninit[UL]@ld
 ; SMALL:        [[TWInitL]]:
-; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TWInit[TC],TWInit[TL]@ld
-; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TWInit[TC],"TWInit"
+; SMALL-NEXT:   .tc TWInit[TC],TWInit[TL]@ld
 ; SMALL:        [[TWUninitL]]:
-; SMALL-NEXT:   .tc _Renamed..5f24__TLSLD.TWUninit[TC],TWUninit[TL]@ld
-; SMALL-NEXT:   .rename _Renamed..5f24__TLSLD.TWUninit[TC],"TWUninit"
+; SMALL-NEXT:   .tc TWUninit[TC],TWUninit[TL]@ld
 
 ; LARGE64:        [[ModuleHandleL]]:
 ; LARGE64-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE64-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ; LARGE64:        [[TGInitL]]:
-; LARGE64-NEXT:   .tc _Renamed..5f24__TLSLD.TGInit[TE],TGInit[TL]@ld
-; LARGE64-NEXT:   .rename _Renamed..5f24__TLSLD.TGInit[TE],"TGInit"
+; LARGE64-NEXT:   .tc TGInit[TE],TGInit[TL]@ld
 ;
 ; LARGE32:        [[TGInitL]]:
-; LARGE32-NEXT:   .tc _Renamed..5f24__TLSLD.TGInit[TE],TGInit[TL]@ld
-; LARGE32-NEXT:   .rename _Renamed..5f24__TLSLD.TGInit[TE],"TGInit"
+; LARGE32-NEXT:   .tc TGInit[TE],TGInit[TL]@ld
 ; LARGE32:        [[ModuleHandleL]]:
 ; LARGE32-NEXT:   .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; LARGE32-NEXT:   .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
 ;
 ; LARGE:        [[TGUninitL]]:
-; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TGUninit[TE],TGUninit[TL]@ld
-; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TGUninit[TE],"TGUninit"
+; LARGE-NEXT:   .tc TGUninit[TE],TGUninit[TL]@ld
 ; LARGE:        [[TIInitL]]:
-; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TIInit[TE],TIInit[TL]@ld
-; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TIInit[TE],"TIInit"
+; LARGE-NEXT:   .tc TIInit[TE],TIInit[TL]@ld
 ; LARGE:        [[TIUninitL]]:
-; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TIUninit[TE],TIUninit[UL]@ld
-; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TIUninit[TE],"TIUninit"
+; LARGE-NEXT:   .tc TIUninit[TE],TIUninit[UL]@ld
 ; LARGE:        [[TWInitL]]:
-; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TWInit[TE],TWInit[TL]@ld
-; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TWInit[TE],"TWInit"
+; LARGE-NEXT:   .tc TWInit[TE],TWInit[TL]@ld
 ; LARGE:        [[TWUninitL]]:
-; LARGE-NEXT:   .tc _Renamed..5f24__TLSLD.TWUninit[TE],TWUninit[TL]@ld
-; LARGE-NEXT:   .rename _Renamed..5f24__TLSLD.TWUninit[TE],"TWUninit"
+; LARGE-NEXT:   .tc TWUninit[TE],TWUninit[TL]@ld
 
 declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)

>From c5e76a2af248e6bd568721adcc246e64d2ffa071 Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Fri, 15 Mar 2024 04:41:09 -0400
Subject: [PATCH 5/9] Initial commit for aix-shared-library-tls-model-heuristic

---
 clang/include/clang/Driver/Options.td         |   4 +
 clang/lib/Basic/Targets/PPC.cpp               |   7 +
 clang/lib/Basic/Targets/PPC.h                 |   1 +
 llvm/lib/Target/PowerPC/PPC.td                |   6 +
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |  14 +-
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   |  42 ++
 .../Target/PowerPC/PPCMachineFunctionInfo.h   |  13 +
 llvm/lib/Target/PowerPC/PPCSubtarget.cpp      |   5 +
 .../aix-shared-library-tls-model-heuristic.ll | 405 ++++++++++++++++++
 ...ary-tls-model-heuristic-opt-IRattribute.ll |  21 +
 ...-shared-library-tls-model-heuristic-opt.ll |  22 +
 11 files changed, 539 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll
 create mode 100644 llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll
 create mode 100644 llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e24626913add76..8b422237a89654 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5029,6 +5029,10 @@ def maix_small_local_exec_tls : Flag<["-"], "maix-small-local-exec-tls">,
            "where the offset from the TLS base is encoded as an "
            "immediate operand (AIX 64-bit only). "
            "This access sequence is not used for variables larger than 32KB.">;
+def maix_shared_library_tls_model_heuristic : Flag<["-"], "maix-shared-library-tls-model-heuristic">,
+  Group<m_ppc_Features_Group>,
+  HelpText<"For shared library loaded with the main program, use heuristic to "
+           "tune TLS model at function level (AIX 64-bit only).">;
 def maix_struct_return : Flag<["-"], "maix-struct-return">,
   Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
   HelpText<"Return all structs in memory (PPC32 only)">,
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index aebe51bfa4daad..32efe2b159fda0 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -89,6 +89,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       IsISA3_1 = true;
     } else if (Feature == "+quadword-atomics") {
       HasQuadwordAtomics = true;
+    } else if (Feature == "+aix-shared-library-tls-model-heuristic") {
+      HasAIXShLibTLSModelHeuristic = true;
     }
     // TODO: Finish this list and add an assert that we've handled them
     // all.
@@ -577,6 +579,9 @@ bool PPCTargetInfo::initFeatureMap(
   // off by default.
   Features["aix-small-local-exec-tls"] = false;
 
+  // Turn off TLS model heuristic by default.
+  Features["aix-shared-library-tls-model-heuristic"] = false;
+
   Features["spe"] = llvm::StringSwitch<bool>(CPU)
                         .Case("8548", true)
                         .Case("e500", true)
@@ -718,6 +723,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
       .Case("isa-v30-instructions", IsISA3_0)
       .Case("isa-v31-instructions", IsISA3_1)
       .Case("quadword-atomics", HasQuadwordAtomics)
+      .Case("aix-shared-library-tls-model-heuristic",
+            HasAIXShLibTLSModelHeuristic)
       .Default(false);
 }
 
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index fa2f442e25846d..4a53d1c95aa3b5 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -80,6 +80,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
   bool IsISA3_0 = false;
   bool IsISA3_1 = false;
   bool HasQuadwordAtomics = false;
+  bool HasAIXShLibTLSModelHeuristic = false;
 
 protected:
   std::string ABI;
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index b962ed28d72000..15f43f9f34a752 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -338,6 +338,12 @@ def FeatureAIXLocalDynamicTLS :
                    "true", "Produce a faster local-dynamic TLS sequence for this "
                    "function for 64-bit AIX">;
 
+def FeatureAIXSharedLibraryTLSModelHeuristic :
+  SubtargetFeature<"aix-shared-library-tls-model-heuristic",
+                   "HasAIXShLibTLSModelHeuristic", "true",
+                   "Tune TLS model at function level in shared library loaded "
+                   "with the main program (for 64-bit AIX only)">;
+
 def FeaturePredictableSelectIsExpensive :
   SubtargetFeature<"predictable-select-expensive",
                    "PredictableSelectIsExpensive",
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 6e1002c45d81cb..d02764f41d9ea1 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -878,6 +878,14 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
       if (Model == TLSModel::InitialExec)
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
+      // On AIX, TLS model heuristic may have turned local-dynamic access into
+      // initial-exec access.
+      PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
+      if (Model == TLSModel::LocalDynamic && FuncInfo->isAIXFuncUseTLSIE()) {
+        LLVM_DEBUG(
+            dbgs() << "Current function use IE access for default LD vars.\n");
+        return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
+      }
       llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
     }
     // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
@@ -2949,7 +2957,11 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
     // Setup the csect for the current TC entry. If the variant kind is
     // VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a
     // new symbol to prefix the name with a dot.
-    if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) {
+    // If TLS model heuristic is turned on, create a new symbol to prefix the
+    // name with a dot.
+    if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
+        (Subtarget->hasAIXShLibTLSModelHeuristic() &&
+         I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD)) {
       SmallString<128> Name;
       StringRef Prefix = ".";
       Name += Prefix;
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index d27932f2915fbb..4e31651e3e762f 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3374,6 +3374,48 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
   EVT PtrVT = getPointerTy(DAG.getDataLayout());
   bool Is64Bit = Subtarget.isPPC64();
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+  // Initialize heuristic setting lazily:
+  // (1) Use initial-exec for single TLS var reference within current function.
+  // (2) Use local-dynamic for multiple TLS var references within current func.
+  PPCFunctionInfo *FuncInfo =
+      DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
+  if (Subtarget.hasAIXShLibTLSModelHeuristic() &&
+      !FuncInfo->isAIXFuncUseInitDone()) {
+    std::set<const GlobalValue *> TLSGV;
+    for (SDNode &Node : DAG.allnodes()) {
+      SDNode *N = &Node;
+      if (N->getOpcode() == ISD::GlobalTLSAddress) {
+        if (GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N)) {
+          const GlobalValue *GV = GA->getGlobal();
+          TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+          if (Model == TLSModel::InitialExec ||
+              Model == TLSModel::LocalDynamic) {
+            TLSGV.insert(GV);
+          }
+        }
+      }
+    }
+    LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGV.size()));
+    if (TLSGV.size() == 1) {
+      FuncInfo->setAIXFuncUseTLSIE();
+    } else if (TLSGV.size() > 1) {
+      FuncInfo->setAIXFuncUseTLSLD();
+    }
+    FuncInfo->setAIXFuncUseInitDone();
+  }
+
+  if (FuncInfo->isAIXFuncUseTLSLD()) {
+    LLVM_DEBUG(
+        dbgs() << DAG.getMachineFunction().getName()
+               << " function use TLS-LD model for TLS IE/LD accesses.\n");
+    Model = TLSModel::LocalDynamic;
+  } else if (FuncInfo->isAIXFuncUseTLSIE()) {
+    LLVM_DEBUG(
+        dbgs() << DAG.getMachineFunction().getName()
+               << " function use TLS-IE model for TLS IE/LD accesses.\n");
+    Model = TLSModel::InitialExec;
+  }
+
   bool IsTLSLocalExecModel = Model == TLSModel::LocalExec;
 
   if (IsTLSLocalExecModel || Model == TLSModel::InitialExec) {
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index df655a3be9512b..aa640e8ef65e0f 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -150,6 +150,12 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   /// to use SExt/ZExt flags in later optimization.
   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
 
+  /// Flags for aix-shared-library-tls-model-heuristic, will be lazily
+  /// initialized for each function.
+  bool AIXFuncUseTLSLD = false;
+  bool AIXFuncUseTLSIE = false;
+  bool AIXFuncUseInitDone = false;
+
 public:
   explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
 
@@ -221,6 +227,13 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   void setHasFastCall() { HasFastCall = true; }
   bool hasFastCall() const { return HasFastCall;}
 
+  void setAIXFuncUseInitDone() { AIXFuncUseInitDone = true; }
+  bool isAIXFuncUseInitDone() const { return AIXFuncUseInitDone; }
+  void setAIXFuncUseTLSLD() { AIXFuncUseTLSLD = true; }
+  bool isAIXFuncUseTLSLD() const { return AIXFuncUseTLSLD; }
+  void setAIXFuncUseTLSIE() { AIXFuncUseTLSIE = true; }
+  bool isAIXFuncUseTLSIE() const { return AIXFuncUseTLSIE; }
+
   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
 
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
index d1722555f1fcb3..cb3fafa303c0d2 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -141,6 +141,11 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
                          "-data-sections.\n",
                          false);
   }
+
+  if (HasAIXShLibTLSModelHeuristic && (!TargetTriple.isOSAIX() || !IsPPC64))
+    report_fatal_error("The aix-shared-library-tls-model-heuristic attribute "
+                       "is only supported on AIX in 64-bit mode.\n",
+                       false);
 }
 
 bool PPCSubtarget::enableMachineScheduler() const { return true; }
diff --git a/llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll b/llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll
new file mode 100644
index 00000000000000..b78822dc65f1d2
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll
@@ -0,0 +1,405 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      --code-model=small < %s | FileCheck %s --check-prefixes=DEFAULT_SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      --code-model=large < %s | FileCheck %s --check-prefixes=DEFAULT_LARGE64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-library-tls-model-heuristic --code-model=small < %s | FileCheck %s --check-prefixes=HEURISTIC_SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-library-tls-model-heuristic --code-model=large < %s | FileCheck %s --check-prefixes=HEURISTIC_LARGE64
+
+ at VarTLSIE1 = internal thread_local(initialexec) global i32 42, align 4
+ at VarTLSIE2 = internal thread_local(initialexec) global i32 0, align 4
+ at VarTLSLD1 = internal thread_local(localdynamic) global i32 42, align 4
+ at VarTLSLD2 = internal thread_local(localdynamic) global i32 0, align 4
+
+; Heuristic to tune function level TLS model settings:
+; Use initial-exec when we have a function accessing only one TLS variable.
+; Use local-dynamic when we have a function accessing a handful or more different TLS variables.
+
+define i32 @Single_IE_USE_IE() {
+; DEFAULT_SMALL64-LABEL: Single_IE_USE_IE:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Single_IE_USE_IE:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; HEURISTIC_SMALL64-LABEL: Single_IE_USE_IE:
+; HEURISTIC_SMALL64:       # %bb.0: # %entry
+; HEURISTIC_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; HEURISTIC_SMALL64-NEXT:    lwzx 3, 13, 3
+; HEURISTIC_SMALL64-NEXT:    blr
+;
+; HEURISTIC_LARGE64-LABEL: Single_IE_USE_IE:
+; HEURISTIC_LARGE64:       # %bb.0: # %entry
+; HEURISTIC_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; HEURISTIC_LARGE64-NEXT:    lwzx 3, 13, 3
+; HEURISTIC_LARGE64-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %1 = load i32, ptr %0, align 4
+  ret i32 %1
+}
+
+define i32 @Single_LD_USE_IE() {
+; DEFAULT_SMALL64-LABEL: Single_LD_USE_IE:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    mflr 0
+; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
+; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_SMALL64-NEXT:    ld 5, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    lwzx 4, 3, 5
+; DEFAULT_SMALL64-NEXT:    addi 6, 4, 42
+; DEFAULT_SMALL64-NEXT:    stwx 6, 3, 5
+; DEFAULT_SMALL64-NEXT:    mr 3, 4
+; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
+; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
+; DEFAULT_SMALL64-NEXT:    mtlr 0
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Single_LD_USE_IE:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    mflr 0
+; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 6, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_LARGE64-NEXT:    ld 5, L..C2 at l(6)
+; DEFAULT_LARGE64-NEXT:    lwzx 4, 3, 5
+; DEFAULT_LARGE64-NEXT:    addi 6, 4, 42
+; DEFAULT_LARGE64-NEXT:    stwx 6, 3, 5
+; DEFAULT_LARGE64-NEXT:    mr 3, 4
+; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
+; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
+; DEFAULT_LARGE64-NEXT:    mtlr 0
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; HEURISTIC_SMALL64-LABEL: Single_LD_USE_IE:
+; HEURISTIC_SMALL64:       # %bb.0: # %entry
+; HEURISTIC_SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD1
+; HEURISTIC_SMALL64-NEXT:    lwzx 3, 13, 4
+; HEURISTIC_SMALL64-NEXT:    addi 5, 3, 42
+; HEURISTIC_SMALL64-NEXT:    stwx 5, 13, 4
+; HEURISTIC_SMALL64-NEXT:    blr
+;
+; HEURISTIC_LARGE64-LABEL: Single_LD_USE_IE:
+; HEURISTIC_LARGE64:       # %bb.0: # %entry
+; HEURISTIC_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 4, L..C1 at l(3)
+; HEURISTIC_LARGE64-NEXT:    lwzx 3, 13, 4
+; HEURISTIC_LARGE64-NEXT:    addi 5, 3, 42
+; HEURISTIC_LARGE64-NEXT:    stwx 5, 13, 4
+; HEURISTIC_LARGE64-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %1 = load i32, ptr %0, align 4
+  %2 = add nsw i32 42, %1
+  store i32 %2, ptr %0, align 4
+  ret i32 %1
+}
+
+define i32 @Multiple_IE_USE_LD() {
+; DEFAULT_SMALL64-LABEL: Multiple_IE_USE_LD:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tprel) @VarTLSIE2
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_SMALL64-NEXT:    lwzx 4, 13, 4
+; DEFAULT_SMALL64-NEXT:    add 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Multiple_IE_USE_LD:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 4, L..C3 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C3 at l(4)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_LARGE64-NEXT:    lwzx 4, 13, 4
+; DEFAULT_LARGE64-NEXT:    add 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; HEURISTIC_SMALL64-LABEL: Multiple_IE_USE_LD:
+; HEURISTIC_SMALL64:       # %bb.0: # %entry
+; HEURISTIC_SMALL64-NEXT:    mflr 0
+; HEURISTIC_SMALL64-NEXT:    stdu 1, -48(1)
+; HEURISTIC_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; HEURISTIC_SMALL64-NEXT:    std 0, 64(1)
+; HEURISTIC_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; HEURISTIC_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSIE1
+; HEURISTIC_SMALL64-NEXT:    ld 5, L..C4(2) # target-flags(ppc-tlsld) @VarTLSIE2
+; HEURISTIC_SMALL64-NEXT:    lwzx 4, 3, 4
+; HEURISTIC_SMALL64-NEXT:    lwzx 3, 3, 5
+; HEURISTIC_SMALL64-NEXT:    add 3, 4, 3
+; HEURISTIC_SMALL64-NEXT:    addi 1, 1, 48
+; HEURISTIC_SMALL64-NEXT:    ld 0, 16(1)
+; HEURISTIC_SMALL64-NEXT:    mtlr 0
+; HEURISTIC_SMALL64-NEXT:    blr
+;
+; HEURISTIC_LARGE64-LABEL: Multiple_IE_USE_LD:
+; HEURISTIC_LARGE64:       # %bb.0: # %entry
+; HEURISTIC_LARGE64-NEXT:    mflr 0
+; HEURISTIC_LARGE64-NEXT:    stdu 1, -48(1)
+; HEURISTIC_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; HEURISTIC_LARGE64-NEXT:    std 0, 64(1)
+; HEURISTIC_LARGE64-NEXT:    addis 6, L..C3 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; HEURISTIC_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; HEURISTIC_LARGE64-NEXT:    addis 5, L..C4 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 4, L..C3 at l(6)
+; HEURISTIC_LARGE64-NEXT:    ld 5, L..C4 at l(5)
+; HEURISTIC_LARGE64-NEXT:    lwzx 4, 3, 4
+; HEURISTIC_LARGE64-NEXT:    lwzx 3, 3, 5
+; HEURISTIC_LARGE64-NEXT:    add 3, 4, 3
+; HEURISTIC_LARGE64-NEXT:    addi 1, 1, 48
+; HEURISTIC_LARGE64-NEXT:    ld 0, 16(1)
+; HEURISTIC_LARGE64-NEXT:    mtlr 0
+; HEURISTIC_LARGE64-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %1 = load i32, ptr %0, align 4
+  %2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE2)
+  %3 = load i32, ptr %2, align 4
+  %add = add nsw i32 %1, %3
+  ret i32 %add
+}
+
+define i32 @Multiple_LD_USE_LD() {
+; DEFAULT_SMALL64-LABEL: Multiple_LD_USE_LD:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    mflr 0
+; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
+; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    ld 5, L..C4(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; DEFAULT_SMALL64-NEXT:    lwzx 4, 3, 4
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 5
+; DEFAULT_SMALL64-NEXT:    add 3, 4, 3
+; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
+; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
+; DEFAULT_SMALL64-NEXT:    mtlr 0
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Multiple_LD_USE_LD:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    mflr 0
+; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
+; DEFAULT_LARGE64-NEXT:    addis 6, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_LARGE64-NEXT:    addis 5, L..C4 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(6)
+; DEFAULT_LARGE64-NEXT:    ld 5, L..C4 at l(5)
+; DEFAULT_LARGE64-NEXT:    lwzx 4, 3, 4
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 5
+; DEFAULT_LARGE64-NEXT:    add 3, 4, 3
+; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
+; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
+; DEFAULT_LARGE64-NEXT:    mtlr 0
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; HEURISTIC_SMALL64-LABEL: Multiple_LD_USE_LD:
+; HEURISTIC_SMALL64:       # %bb.0: # %entry
+; HEURISTIC_SMALL64-NEXT:    mflr 0
+; HEURISTIC_SMALL64-NEXT:    stdu 1, -48(1)
+; HEURISTIC_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; HEURISTIC_SMALL64-NEXT:    std 0, 64(1)
+; HEURISTIC_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; HEURISTIC_SMALL64-NEXT:    ld 4, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; HEURISTIC_SMALL64-NEXT:    ld 5, L..C6(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; HEURISTIC_SMALL64-NEXT:    lwzx 4, 3, 4
+; HEURISTIC_SMALL64-NEXT:    lwzx 3, 3, 5
+; HEURISTIC_SMALL64-NEXT:    add 3, 4, 3
+; HEURISTIC_SMALL64-NEXT:    addi 1, 1, 48
+; HEURISTIC_SMALL64-NEXT:    ld 0, 16(1)
+; HEURISTIC_SMALL64-NEXT:    mtlr 0
+; HEURISTIC_SMALL64-NEXT:    blr
+;
+; HEURISTIC_LARGE64-LABEL: Multiple_LD_USE_LD:
+; HEURISTIC_LARGE64:       # %bb.0: # %entry
+; HEURISTIC_LARGE64-NEXT:    mflr 0
+; HEURISTIC_LARGE64-NEXT:    stdu 1, -48(1)
+; HEURISTIC_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; HEURISTIC_LARGE64-NEXT:    std 0, 64(1)
+; HEURISTIC_LARGE64-NEXT:    addis 6, L..C5 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; HEURISTIC_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; HEURISTIC_LARGE64-NEXT:    addis 5, L..C6 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 4, L..C5 at l(6)
+; HEURISTIC_LARGE64-NEXT:    ld 5, L..C6 at l(5)
+; HEURISTIC_LARGE64-NEXT:    lwzx 4, 3, 4
+; HEURISTIC_LARGE64-NEXT:    lwzx 3, 3, 5
+; HEURISTIC_LARGE64-NEXT:    add 3, 4, 3
+; HEURISTIC_LARGE64-NEXT:    addi 1, 1, 48
+; HEURISTIC_LARGE64-NEXT:    ld 0, 16(1)
+; HEURISTIC_LARGE64-NEXT:    mtlr 0
+; HEURISTIC_LARGE64-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %1 = load i32, ptr %0, align 4
+  %2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD2)
+  %3 = load i32, ptr %2, align 4
+  %add = add nsw i32 %1, %3
+  ret i32 %add
+}
+
+define i32 @Multiple_MIX_USE_LD() {
+; DEFAULT_SMALL64-LABEL: Multiple_MIX_USE_LD:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    mflr 0
+; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
+; DEFAULT_SMALL64-NEXT:    lwzx 6, 13, 3
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    add 3, 6, 3
+; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
+; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
+; DEFAULT_SMALL64-NEXT:    mtlr 0
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Multiple_MIX_USE_LD:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    mflr 0
+; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
+; DEFAULT_LARGE64-NEXT:    addis 7, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; DEFAULT_LARGE64-NEXT:    lwzx 6, 13, 3
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(7)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    add 3, 6, 3
+; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
+; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
+; DEFAULT_LARGE64-NEXT:    mtlr 0
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; HEURISTIC_SMALL64-LABEL: Multiple_MIX_USE_LD:
+; HEURISTIC_SMALL64:       # %bb.0: # %entry
+; HEURISTIC_SMALL64-NEXT:    mflr 0
+; HEURISTIC_SMALL64-NEXT:    stdu 1, -48(1)
+; HEURISTIC_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; HEURISTIC_SMALL64-NEXT:    std 0, 64(1)
+; HEURISTIC_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; HEURISTIC_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSIE1
+; HEURISTIC_SMALL64-NEXT:    ld 5, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; HEURISTIC_SMALL64-NEXT:    lwzx 4, 3, 4
+; HEURISTIC_SMALL64-NEXT:    lwzx 3, 3, 5
+; HEURISTIC_SMALL64-NEXT:    add 3, 4, 3
+; HEURISTIC_SMALL64-NEXT:    addi 1, 1, 48
+; HEURISTIC_SMALL64-NEXT:    ld 0, 16(1)
+; HEURISTIC_SMALL64-NEXT:    mtlr 0
+; HEURISTIC_SMALL64-NEXT:    blr
+;
+; HEURISTIC_LARGE64-LABEL: Multiple_MIX_USE_LD:
+; HEURISTIC_LARGE64:       # %bb.0: # %entry
+; HEURISTIC_LARGE64-NEXT:    mflr 0
+; HEURISTIC_LARGE64-NEXT:    stdu 1, -48(1)
+; HEURISTIC_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; HEURISTIC_LARGE64-NEXT:    std 0, 64(1)
+; HEURISTIC_LARGE64-NEXT:    addis 6, L..C3 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; HEURISTIC_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; HEURISTIC_LARGE64-NEXT:    addis 5, L..C5 at u(2)
+; HEURISTIC_LARGE64-NEXT:    ld 4, L..C3 at l(6)
+; HEURISTIC_LARGE64-NEXT:    ld 5, L..C5 at l(5)
+; HEURISTIC_LARGE64-NEXT:    lwzx 4, 3, 4
+; HEURISTIC_LARGE64-NEXT:    lwzx 3, 3, 5
+; HEURISTIC_LARGE64-NEXT:    add 3, 4, 3
+; HEURISTIC_LARGE64-NEXT:    addi 1, 1, 48
+; HEURISTIC_LARGE64-NEXT:    ld 0, 16(1)
+; HEURISTIC_LARGE64-NEXT:    mtlr 0
+; HEURISTIC_LARGE64-NEXT:    blr
+entry:
+  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %1 = load i32, ptr %0, align 4
+  %2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %3 = load i32, ptr %2, align 4
+  %add = add nsw i32 %1, %3
+  ret i32 %add
+}
+
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
+
+; DEFAULT_SMALL64-LABEL: .toc
+; DEFAULT_SMALL64-LABEL: L..C0:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
+; DEFAULT_SMALL64-LABEL: L..C1:
+; DEFAULT_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; DEFAULT_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; DEFAULT_SMALL64-LABEL: L..C2:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ld
+; DEFAULT_SMALL64-LABEL: L..C3:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSIE2[TC],VarTLSIE2[UL]@ie
+; DEFAULT_SMALL64-LABEL: L..C4:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSLD2[TC],VarTLSLD2[UL]@ld
+
+; DEFAULT_LARGE64-LABEL: .toc
+; DEFAULT_LARGE64-LABEL: L..C0:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
+; DEFAULT_LARGE64-LABEL: L..C1:
+; DEFAULT_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; DEFAULT_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; DEFAULT_LARGE64-LABEL: L..C2:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ld
+; DEFAULT_LARGE64-LABEL: L..C3:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSIE2[TE],VarTLSIE2[UL]@ie
+; DEFAULT_LARGE64-LABEL: L..C4:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSLD2[TE],VarTLSLD2[UL]@ld
+
+; HEURISTIC_SMALL64-LABEL: .toc
+; HEURISTIC_SMALL64-LABEL: L..C0:
+; HEURISTIC_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
+; HEURISTIC_SMALL64-LABEL: L..C1:
+; HEURISTIC_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ie
+; HEURISTIC_SMALL64-LABEL: L..C2:
+; HEURISTIC_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; HEURISTIC_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; HEURISTIC_SMALL64-LABEL: L..C3:
+; HEURISTIC_SMALL64-NEXT: .tc .VarTLSIE1[TC],VarTLSIE1[TL]@ld
+; HEURISTIC_SMALL64-LABEL: L..C4:
+; HEURISTIC_SMALL64-NEXT: .tc .VarTLSIE2[TC],VarTLSIE2[UL]@ld
+; HEURISTIC_SMALL64-LABEL: L..C5:
+; HEURISTIC_SMALL64-NEXT: .tc .VarTLSLD1[TC],VarTLSLD1[TL]@ld
+; HEURISTIC_SMALL64-LABEL: L..C6:
+; HEURISTIC_SMALL64-NEXT: .tc .VarTLSLD2[TC],VarTLSLD2[UL]@ld
+
+; HEURISTIC_LARGE64-LABEL: .toc
+; HEURISTIC_LARGE64-LABEL: L..C0:
+; HEURISTIC_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
+; HEURISTIC_LARGE64-LABEL: L..C1:
+; HEURISTIC_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ie
+; HEURISTIC_LARGE64-LABEL: L..C2:
+; HEURISTIC_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; HEURISTIC_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; HEURISTIC_LARGE64-LABEL: L..C3:
+; HEURISTIC_LARGE64-NEXT: .tc .VarTLSIE1[TE],VarTLSIE1[TL]@ld
+; HEURISTIC_LARGE64-LABEL: L..C4:
+; HEURISTIC_LARGE64-NEXT: .tc .VarTLSIE2[TE],VarTLSIE2[UL]@ld
+; HEURISTIC_LARGE64-LABEL: L..C5:
+; HEURISTIC_LARGE64-NEXT: .tc .VarTLSLD1[TE],VarTLSLD1[TL]@ld
+; HEURISTIC_LARGE64-LABEL: L..C6:
+; HEURISTIC_LARGE64-NEXT: .tc .VarTLSLD2[TE],VarTLSLD2[UL]@ld
diff --git a/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll b/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll
new file mode 100644
index 00000000000000..154d573671bf5e
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -ppc-asm-full-reg-names \
+; RUN:   < %s | FileCheck %s
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -ppc-asm-full-reg-names \
+; RUN:   < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED
+; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -ppc-asm-full-reg-names \
+; RUN:   < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED
+
+define dso_local signext i32 @testWithIRAttr() #0 {
+entry:
+  ret i32 0
+}
+; Check that the aix-shared-library-tls-model-heuristic attribute is not supported on Linux and AIX (32-bit).
+; CHECK-NOT-SUPPORTED: The aix-shared-library-tls-model-heuristic attribute is only supported on AIX in 64-bit mode.
+
+; Make sure that the test was actually compiled successfully after using the
+; aix-shared-library-tls-model-heuristic attribute.
+; CHECK-LABEL: testWithIRAttr:
+; CHECK:        li r3, 0
+; CHECK-NEXT:   blr
+
+attributes #0 = { "target-features"="+aix-shared-library-tls-model-heuristic" }
diff --git a/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll b/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll
new file mode 100644
index 00000000000000..de85655c998f86
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll
@@ -0,0 +1,22 @@
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mattr=+aix-shared-library-tls-model-heuristic \
+; RUN:   -ppc-asm-full-reg-names < %s | FileCheck %s
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -mattr=+aix-shared-library-tls-model-heuristic \
+; RUN:   -ppc-asm-full-reg-names < %s 2>&1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED
+; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -mattr=+aix-shared-library-tls-model-heuristic \
+; RUN:   -ppc-asm-full-reg-names < %s 2>&1 | \
+; RUN:   FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED
+
+define dso_local signext i32 @testNoIRAttr() {
+entry:
+  ret i32 0
+}
+
+; Check that the aix-shared-library-tls-model-heuristic attribute is not supported on Linux and AIX (32-bit).
+; CHECK-NOT-SUPPORTED: The aix-shared-library-tls-model-heuristic attribute is only supported on AIX in 64-bit mode.
+
+; Make sure that the test was actually compiled successfully after using the
+; aix-shared-library-tls-model-heuristic attribute.
+; CHECK-LABEL: testNoIRAttr:
+; CHECK:        li r3, 0
+; CHECK-NEXT:   blr

>From 457dafbe0aafca0a6348b8bdaf8c2fdbb6e3780e Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Mon, 25 Mar 2024 04:18:17 -0400
Subject: [PATCH 6/9] Fix issue/update according to comments (1) Address issue
 that only the first BB get checked inside `LowerGlobalTLSAddressAIX`, also
 added test case to expose the issue. (2) Change feature name from
 `aix-shared-library-tls-model-heuristic` to `aix-shared-lib-tls-model-opt`.
 (3) Update naming convention in test cases to avoid numbered identifiers. (4)
 Update comments and code simplifications.

---
 clang/include/clang/Driver/Options.td         |   6 +-
 clang/lib/Basic/Targets/PPC.cpp               |  11 +-
 clang/lib/Basic/Targets/PPC.h                 |   2 +-
 llvm/lib/Target/PowerPC/PPC.td                |   6 +-
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |   8 +-
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   |  63 ++-
 llvm/lib/Target/PowerPC/PPCSubtarget.cpp      |   4 +-
 .../PowerPC/aix-shared-lib-tls-model-opt.ll   | 523 ++++++++++++++++++
 .../aix-shared-library-tls-model-heuristic.ll | 405 --------------
 ...x-shared-lib-tls-model-opt-IRattribute.ll} |   8 +-
 ...ck-aix-shared-lib-tls-model-opt-Option.ll} |  12 +-
 11 files changed, 588 insertions(+), 460 deletions(-)
 create mode 100644 llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll
 delete mode 100644 llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll
 rename llvm/test/CodeGen/PowerPC/{check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll => check-aix-shared-lib-tls-model-opt-IRattribute.ll} (63%)
 rename llvm/test/CodeGen/PowerPC/{check-aix-shared-library-tls-model-heuristic-opt.ll => check-aix-shared-lib-tls-model-opt-Option.ll} (64%)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 8b422237a89654..51b37a2ed4d1a3 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5029,10 +5029,10 @@ def maix_small_local_exec_tls : Flag<["-"], "maix-small-local-exec-tls">,
            "where the offset from the TLS base is encoded as an "
            "immediate operand (AIX 64-bit only). "
            "This access sequence is not used for variables larger than 32KB.">;
-def maix_shared_library_tls_model_heuristic : Flag<["-"], "maix-shared-library-tls-model-heuristic">,
+def maix_shared_lib_tls_model_opt : Flag<["-"], "maix-shared-lib-tls-model-opt">,
   Group<m_ppc_Features_Group>,
-  HelpText<"For shared library loaded with the main program, use heuristic to "
-           "tune TLS model at function level (AIX 64-bit only).">;
+  HelpText<"For shared library loaded with the main program, use heuristics to "
+           "tune the TLS model at the function level (AIX 64-bit only).">;
 def maix_struct_return : Flag<["-"], "maix-struct-return">,
   Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
   HelpText<"Return all structs in memory (PPC32 only)">,
diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 32efe2b159fda0..08da2e56694588 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -89,8 +89,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       IsISA3_1 = true;
     } else if (Feature == "+quadword-atomics") {
       HasQuadwordAtomics = true;
-    } else if (Feature == "+aix-shared-library-tls-model-heuristic") {
-      HasAIXShLibTLSModelHeuristic = true;
+    } else if (Feature == "+aix-shared-lib-tls-model-opt") {
+      HasAIXShLibTLSModelOpt = true;
     }
     // TODO: Finish this list and add an assert that we've handled them
     // all.
@@ -579,8 +579,8 @@ bool PPCTargetInfo::initFeatureMap(
   // off by default.
   Features["aix-small-local-exec-tls"] = false;
 
-  // Turn off TLS model heuristic by default.
-  Features["aix-shared-library-tls-model-heuristic"] = false;
+  // Turn off TLS model opt by default.
+  Features["aix-shared-lib-tls-model-opt"] = false;
 
   Features["spe"] = llvm::StringSwitch<bool>(CPU)
                         .Case("8548", true)
@@ -723,8 +723,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
       .Case("isa-v30-instructions", IsISA3_0)
       .Case("isa-v31-instructions", IsISA3_1)
       .Case("quadword-atomics", HasQuadwordAtomics)
-      .Case("aix-shared-library-tls-model-heuristic",
-            HasAIXShLibTLSModelHeuristic)
+      .Case("aix-shared-lib-tls-model-opt", HasAIXShLibTLSModelOpt)
       .Default(false);
 }
 
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index 4a53d1c95aa3b5..1bd150ad6b3af5 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -80,7 +80,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
   bool IsISA3_0 = false;
   bool IsISA3_1 = false;
   bool HasQuadwordAtomics = false;
-  bool HasAIXShLibTLSModelHeuristic = false;
+  bool HasAIXShLibTLSModelOpt = false;
 
 protected:
   std::string ABI;
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index 15f43f9f34a752..639771ab9eabbd 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -338,9 +338,9 @@ def FeatureAIXLocalDynamicTLS :
                    "true", "Produce a faster local-dynamic TLS sequence for this "
                    "function for 64-bit AIX">;
 
-def FeatureAIXSharedLibraryTLSModelHeuristic :
-  SubtargetFeature<"aix-shared-library-tls-model-heuristic",
-                   "HasAIXShLibTLSModelHeuristic", "true",
+def FeatureAIXSharedLibTLSModelOpt :
+  SubtargetFeature<"aix-shared-lib-tls-model-opt",
+                   "HasAIXShLibTLSModelOpt", "true",
                    "Tune TLS model at function level in shared library loaded "
                    "with the main program (for 64-bit AIX only)">;
 
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index d02764f41d9ea1..1267fe5b6ec0e1 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -878,12 +878,12 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
       if (Model == TLSModel::InitialExec)
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
-      // On AIX, TLS model heuristic may have turned local-dynamic access into
-      // initial-exec access.
+      // On AIX, TLS model heuristics may have turned local-dynamic accesses
+      // into initial-exec accesses.
       PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
       if (Model == TLSModel::LocalDynamic && FuncInfo->isAIXFuncUseTLSIE()) {
         LLVM_DEBUG(
-            dbgs() << "Current function use IE access for default LD vars.\n");
+            dbgs() << "Current function uses IE access for default LD vars.\n");
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
       }
       llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
@@ -2960,7 +2960,7 @@ void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
     // If TLS model heuristic is turned on, create a new symbol to prefix the
     // name with a dot.
     if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
-        (Subtarget->hasAIXShLibTLSModelHeuristic() &&
+        (Subtarget->hasAIXShLibTLSModelOpt() &&
          I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD)) {
       SmallString<128> Name;
       StringRef Prefix = ".";
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 4e31651e3e762f..fb4f6d129afe22 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3374,31 +3374,40 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
   EVT PtrVT = getPointerTy(DAG.getDataLayout());
   bool Is64Bit = Subtarget.isPPC64();
   TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
-  // Initialize heuristic setting lazily:
-  // (1) Use initial-exec for single TLS var reference within current function.
-  // (2) Use local-dynamic for multiple TLS var references within current func.
+  // Initialize TLS model opt setting lazily:
+  // (1) Use initial-exec for single TLS var references within current function.
+  // (2) Use local-dynamic for multiple TLS var references within current
+  // function.
   PPCFunctionInfo *FuncInfo =
       DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
-  if (Subtarget.hasAIXShLibTLSModelHeuristic() &&
-      !FuncInfo->isAIXFuncUseInitDone()) {
-    std::set<const GlobalValue *> TLSGV;
-    for (SDNode &Node : DAG.allnodes()) {
-      SDNode *N = &Node;
-      if (N->getOpcode() == ISD::GlobalTLSAddress) {
-        if (GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N)) {
-          const GlobalValue *GV = GA->getGlobal();
-          TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
-          if (Model == TLSModel::InitialExec ||
-              Model == TLSModel::LocalDynamic) {
-            TLSGV.insert(GV);
-          }
-        }
-      }
-    }
-    LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGV.size()));
-    if (TLSGV.size() == 1) {
+  if (Subtarget.hasAIXShLibTLSModelOpt() && !FuncInfo->isAIXFuncUseInitDone()) {
+    SmallPtrSet<const GlobalValue *, 8> TLSGV;
+    // Iterate over all instructions within current function, collect all TLS
+    // global variables (global variables taken as the first parameter to
+    // Intrinsic::threadlocal_address).
+    const Function &Func = DAG.getMachineFunction().getFunction();
+    for (Function::const_iterator BI = Func.begin(), BE = Func.end(); BI != BE;
+         ++BI)
+      for (BasicBlock::const_iterator II = BI->begin(), IE = BI->end();
+           II != IE; ++II)
+        if (II->getOpcode() == Instruction::Call)
+          if (const CallInst *CI = dyn_cast<const CallInst>(&*II))
+            if (Function *CF = CI->getCalledFunction())
+              if (CF->isDeclaration() &&
+                  CF->getIntrinsicID() == Intrinsic::threadlocal_address)
+                if (const GlobalValue *GV =
+                        dyn_cast<GlobalValue>(II->getOperand(0))) {
+                  TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+                  if (Model == TLSModel::InitialExec ||
+                      Model == TLSModel::LocalDynamic)
+                    TLSGV.insert(GV);
+                }
+
+    unsigned TLSGVCnt = TLSGV.size();
+    LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGVCnt));
+    if (TLSGVCnt == 1) {
       FuncInfo->setAIXFuncUseTLSIE();
-    } else if (TLSGV.size() > 1) {
+    } else if (TLSGVCnt > 1) {
       FuncInfo->setAIXFuncUseTLSLD();
     }
     FuncInfo->setAIXFuncUseInitDone();
@@ -3406,13 +3415,15 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
 
   if (FuncInfo->isAIXFuncUseTLSLD()) {
     LLVM_DEBUG(
-        dbgs() << DAG.getMachineFunction().getName()
-               << " function use TLS-LD model for TLS IE/LD accesses.\n");
+        dbgs()
+        << DAG.getMachineFunction().getName()
+        << " function is using the TLS-LD model for TLS IE/LD accesses.\n");
     Model = TLSModel::LocalDynamic;
   } else if (FuncInfo->isAIXFuncUseTLSIE()) {
     LLVM_DEBUG(
-        dbgs() << DAG.getMachineFunction().getName()
-               << " function use TLS-IE model for TLS IE/LD accesses.\n");
+        dbgs()
+        << DAG.getMachineFunction().getName()
+        << " function is using the TLS-IE model for TLS IE/LD accesses.\n");
     Model = TLSModel::InitialExec;
   }
 
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
index cb3fafa303c0d2..0628fbb26245ce 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -142,8 +142,8 @@ void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
                          false);
   }
 
-  if (HasAIXShLibTLSModelHeuristic && (!TargetTriple.isOSAIX() || !IsPPC64))
-    report_fatal_error("The aix-shared-library-tls-model-heuristic attribute "
+  if (HasAIXShLibTLSModelOpt && (!TargetTriple.isOSAIX() || !IsPPC64))
+    report_fatal_error("The aix-shared-lib-tls-model-opt attribute "
                        "is only supported on AIX in 64-bit mode.\n",
                        false);
 }
diff --git a/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll b/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll
new file mode 100644
index 00000000000000..9db3c2b8256847
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll
@@ -0,0 +1,523 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      --code-model=small < %s | FileCheck %s --check-prefixes=DEFAULT_SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      --code-model=large < %s | FileCheck %s --check-prefixes=DEFAULT_LARGE64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-lib-tls-model-opt --code-model=small < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-lib-tls-model-opt --code-model=large < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_LARGE64
+
+ at VarTLSIE1 = internal thread_local(initialexec) global i32 42, align 4
+ at VarTLSIE2 = internal thread_local(initialexec) global i32 0, align 4
+ at VarTLSLD1 = internal thread_local(localdynamic) global i32 42, align 4
+ at VarTLSLD2 = internal thread_local(localdynamic) global i32 0, align 4
+
+; Tune function level TLS model settings:
+; Use initial-exec when we have a function accessing only one TLS variable.
+; Use local-dynamic when we have a function accessing a handful or more different TLS variables.
+
+define i32 @Single_IE_USE_IE(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Single_IE_USE_IE:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    and 4, 3, 4
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; DEFAULT_SMALL64-NEXT:    cmpwi 4, -1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Single_IE_USE_IE:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    and 4, 3, 4
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; DEFAULT_LARGE64-NEXT:    cmpwi 4, -1
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_SMALL64-LABEL: Single_IE_USE_IE:
+; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_SMALL64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LARGE64-LABEL: Single_IE_USE_IE:
+; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LARGE64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+entry:
+  %a = icmp slt i32 %P, 0
+  %b = icmp slt i32 %Q, 0
+  %c = and i1 %a, %b
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %load1 = load i32, ptr %tls1, align 4
+  br i1 %c, label %bb1, label %return
+
+bb1:
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %load2 = load i32, ptr %tls2, align 4
+  ret i32 %load2
+
+return:
+  ret i32 %load1
+}
+
+define i32 @Single_LD_USE_IE(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Single_LD_USE_IE:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    mflr 0
+; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
+; DEFAULT_SMALL64-NEXT:    and 6, 3, 4
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
+; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    cmpwi 6, -1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
+; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
+; DEFAULT_SMALL64-NEXT:    mtlr 0
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Single_LD_USE_IE:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    mflr 0
+; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
+; DEFAULT_LARGE64-NEXT:    and 6, 3, 4
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 7, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
+; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(7)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    cmpwi 6, -1
+; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
+; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
+; DEFAULT_LARGE64-NEXT:    mtlr 0
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_SMALL64-LABEL: Single_LD_USE_IE:
+; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_SMALL64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LARGE64-LABEL: Single_LD_USE_IE:
+; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LARGE64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+entry:
+  %a = icmp slt i32 %P, 0
+  %b = icmp slt i32 %Q, 0
+  %c = and i1 %a, %b
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %load1 = load i32, ptr %tls1, align 4
+  br i1 %c, label %bb1, label %return
+
+bb1:
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %load2 = load i32, ptr %tls2, align 4
+  ret i32 %load2
+
+return:
+  ret i32 %load1
+}
+
+define i32 @Multiple_IE_USE_LD(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Multiple_IE_USE_LD:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    and 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    cmpwi 3, -1
+; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB2_2
+; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C3(2) # target-flags(ppc-tprel) @VarTLSIE2
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_SMALL64-NEXT:    blr
+; DEFAULT_SMALL64-NEXT:  L..BB2_2: # %return
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Multiple_IE_USE_LD:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    and 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    cmpwi 3, -1
+; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB2_2
+; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C3 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C3 at l(3)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_LARGE64-NEXT:    blr
+; DEFAULT_LARGE64-NEXT:  L..BB2_2: # %return
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_SMALL64-LABEL: Multiple_IE_USE_LD:
+; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_SMALL64-NEXT:    mflr 0
+; TLS_MODEL_OPT_SMALL64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; TLS_MODEL_OPT_SMALL64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB2_2
+; TLS_MODEL_OPT_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSIE2
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB2_3
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @VarTLSIE1
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB2_3: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LARGE64-LABEL: Multiple_IE_USE_LD:
+; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LARGE64-NEXT:    mflr 0
+; TLS_MODEL_OPT_LARGE64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB2_2
+; TLS_MODEL_OPT_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C3 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C3 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB2_3
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C4 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C4 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB2_3: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+entry:
+  %a = icmp slt i32 %P, 0
+  %b = icmp slt i32 %Q, 0
+  %c = and i1 %a, %b
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %load1 = load i32, ptr %tls1, align 4
+  br i1 %c, label %bb1, label %return
+
+bb1:
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE2)
+  %load2 = load i32, ptr %tls2, align 4
+  ret i32 %load2
+
+return:
+  ret i32 %load1
+}
+
+define i32 @Multiple_LD_USE_LD(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Multiple_LD_USE_LD:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    mflr 0
+; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
+; DEFAULT_SMALL64-NEXT:    and 6, 3, 4
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
+; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_SMALL64-NEXT:    cmpwi 6, -1
+; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB3_2
+; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    b L..BB3_3
+; DEFAULT_SMALL64-NEXT:  L..BB3_2: # %return
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_SMALL64-NEXT:  L..BB3_3: # %bb1
+; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
+; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
+; DEFAULT_SMALL64-NEXT:    mtlr 0
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Multiple_LD_USE_LD:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    mflr 0
+; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
+; DEFAULT_LARGE64-NEXT:    and 6, 3, 4
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_LARGE64-NEXT:    cmpwi 6, -1
+; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB3_2
+; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_LARGE64-NEXT:    addis 4, L..C4 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C4 at l(4)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    b L..BB3_3
+; DEFAULT_LARGE64-NEXT:  L..BB3_2: # %return
+; DEFAULT_LARGE64-NEXT:    addis 4, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(4)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:  L..BB3_3: # %bb1
+; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
+; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
+; DEFAULT_LARGE64-NEXT:    mtlr 0
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_SMALL64-LABEL: Multiple_LD_USE_LD:
+; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_SMALL64-NEXT:    mflr 0
+; TLS_MODEL_OPT_SMALL64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; TLS_MODEL_OPT_SMALL64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB3_2
+; TLS_MODEL_OPT_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB3_3
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB3_2: # %return
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C6(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB3_3: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LARGE64-LABEL: Multiple_LD_USE_LD:
+; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LARGE64-NEXT:    mflr 0
+; TLS_MODEL_OPT_LARGE64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB3_2
+; TLS_MODEL_OPT_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C5 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C5 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB3_3
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB3_2: # %return
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C6 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C6 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB3_3: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+entry:
+  %a = icmp slt i32 %P, 0
+  %b = icmp slt i32 %Q, 0
+  %c = and i1 %a, %b
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %load1 = load i32, ptr %tls1, align 4
+  br i1 %c, label %bb1, label %return
+
+bb1:
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD2)
+  %load2 = load i32, ptr %tls2, align 4
+  ret i32 %load2
+
+return:
+  ret i32 %load1
+}
+
+define i32 @Multiple_MIX_USE_LD(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Multiple_MIX_USE_LD:
+; DEFAULT_SMALL64:       # %bb.0: # %entry
+; DEFAULT_SMALL64-NEXT:    and 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    cmpwi 3, -1
+; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB4_2
+; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_SMALL64-NEXT:    mflr 0
+; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
+; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
+; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
+; DEFAULT_SMALL64-NEXT:    mtlr 0
+; DEFAULT_SMALL64-NEXT:    blr
+; DEFAULT_SMALL64-NEXT:  L..BB4_2: # %return
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_SMALL64-NEXT:    blr
+;
+; DEFAULT_LARGE64-LABEL: Multiple_MIX_USE_LD:
+; DEFAULT_LARGE64:       # %bb.0: # %entry
+; DEFAULT_LARGE64-NEXT:    and 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    cmpwi 3, -1
+; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB4_2
+; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_LARGE64-NEXT:    mflr 0
+; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 6, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(6)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
+; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
+; DEFAULT_LARGE64-NEXT:    mtlr 0
+; DEFAULT_LARGE64-NEXT:    blr
+; DEFAULT_LARGE64-NEXT:  L..BB4_2: # %return
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
+; DEFAULT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_SMALL64-LABEL: Multiple_MIX_USE_LD:
+; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_SMALL64-NEXT:    mflr 0
+; TLS_MODEL_OPT_SMALL64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; TLS_MODEL_OPT_SMALL64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB4_2
+; TLS_MODEL_OPT_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C6(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB4_3
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB4_2: # %return
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @VarTLSIE1
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB4_3: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_SMALL64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LARGE64-LABEL: Multiple_MIX_USE_LD:
+; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LARGE64-NEXT:    mflr 0
+; TLS_MODEL_OPT_LARGE64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB4_2
+; TLS_MODEL_OPT_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C6 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C6 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB4_3
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB4_2: # %return
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C4 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C4 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB4_3: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_LARGE64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+entry:
+  %a = icmp slt i32 %P, 0
+  %b = icmp slt i32 %Q, 0
+  %c = and i1 %a, %b
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %load1 = load i32, ptr %tls1, align 4
+  br i1 %c, label %bb1, label %return
+
+bb1:
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %load2 = load i32, ptr %tls2, align 4
+  ret i32 %load2
+
+return:
+  ret i32 %load1
+}
+
+declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
+
+; DEFAULT_SMALL64-LABEL: .toc
+; DEFAULT_SMALL64-LABEL: L..C0:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
+; DEFAULT_SMALL64-LABEL: L..C1:
+; DEFAULT_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; DEFAULT_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; DEFAULT_SMALL64-LABEL: L..C2:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ld
+; DEFAULT_SMALL64-LABEL: L..C3:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSIE2[TC],VarTLSIE2[UL]@ie
+; DEFAULT_SMALL64-LABEL: L..C4:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSLD2[TC],VarTLSLD2[UL]@ld
+
+; DEFAULT_LARGE64-LABEL: .toc
+; DEFAULT_LARGE64-LABEL: L..C0:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
+; DEFAULT_LARGE64-LABEL: L..C1:
+; DEFAULT_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; DEFAULT_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; DEFAULT_LARGE64-LABEL: L..C2:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ld
+; DEFAULT_LARGE64-LABEL: L..C3:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSIE2[TE],VarTLSIE2[UL]@ie
+; DEFAULT_LARGE64-LABEL: L..C4:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSLD2[TE],VarTLSLD2[UL]@ld
+
+; TLS_MODEL_OPT_SMALL64-LABEL: .toc
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C0:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C1:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ie
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C2:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; TLS_MODEL_OPT_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C3:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSIE2[TC],VarTLSIE2[UL]@ld
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C4:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSIE1[TC],VarTLSIE1[TL]@ld
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C5:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSLD2[TC],VarTLSLD2[UL]@ld
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C6:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSLD1[TC],VarTLSLD1[TL]@ld
+
+; TLS_MODEL_OPT_LARGE64-LABEL: .toc
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C0:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C1:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ie
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C2:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; TLS_MODEL_OPT_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C3:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSIE2[TE],VarTLSIE2[UL]@ld
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C4:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSIE1[TE],VarTLSIE1[TL]@ld
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C5:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSLD2[TE],VarTLSLD2[UL]@ld
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C6:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSLD1[TE],VarTLSLD1[TL]@ld
diff --git a/llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll b/llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll
deleted file mode 100644
index b78822dc65f1d2..00000000000000
--- a/llvm/test/CodeGen/PowerPC/aix-shared-library-tls-model-heuristic.ll
+++ /dev/null
@@ -1,405 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:      --code-model=small < %s | FileCheck %s --check-prefixes=DEFAULT_SMALL64
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:      --code-model=large < %s | FileCheck %s --check-prefixes=DEFAULT_LARGE64
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:      -mattr=+aix-shared-library-tls-model-heuristic --code-model=small < %s | FileCheck %s --check-prefixes=HEURISTIC_SMALL64
-; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
-; RUN:      -mattr=+aix-shared-library-tls-model-heuristic --code-model=large < %s | FileCheck %s --check-prefixes=HEURISTIC_LARGE64
-
- at VarTLSIE1 = internal thread_local(initialexec) global i32 42, align 4
- at VarTLSIE2 = internal thread_local(initialexec) global i32 0, align 4
- at VarTLSLD1 = internal thread_local(localdynamic) global i32 42, align 4
- at VarTLSLD2 = internal thread_local(localdynamic) global i32 0, align 4
-
-; Heuristic to tune function level TLS model settings:
-; Use initial-exec when we have a function accessing only one TLS variable.
-; Use local-dynamic when we have a function accessing a handful or more different TLS variables.
-
-define i32 @Single_IE_USE_IE() {
-; DEFAULT_SMALL64-LABEL: Single_IE_USE_IE:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_SMALL64-NEXT:    blr
-;
-; DEFAULT_LARGE64-LABEL: Single_IE_USE_IE:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_LARGE64-NEXT:    blr
-;
-; HEURISTIC_SMALL64-LABEL: Single_IE_USE_IE:
-; HEURISTIC_SMALL64:       # %bb.0: # %entry
-; HEURISTIC_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; HEURISTIC_SMALL64-NEXT:    lwzx 3, 13, 3
-; HEURISTIC_SMALL64-NEXT:    blr
-;
-; HEURISTIC_LARGE64-LABEL: Single_IE_USE_IE:
-; HEURISTIC_LARGE64:       # %bb.0: # %entry
-; HEURISTIC_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; HEURISTIC_LARGE64-NEXT:    lwzx 3, 13, 3
-; HEURISTIC_LARGE64-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
-  %1 = load i32, ptr %0, align 4
-  ret i32 %1
-}
-
-define i32 @Single_LD_USE_IE() {
-; DEFAULT_SMALL64-LABEL: Single_LD_USE_IE:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    mflr 0
-; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
-; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_SMALL64-NEXT:    ld 5, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
-; DEFAULT_SMALL64-NEXT:    lwzx 4, 3, 5
-; DEFAULT_SMALL64-NEXT:    addi 6, 4, 42
-; DEFAULT_SMALL64-NEXT:    stwx 6, 3, 5
-; DEFAULT_SMALL64-NEXT:    mr 3, 4
-; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
-; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
-; DEFAULT_SMALL64-NEXT:    mtlr 0
-; DEFAULT_SMALL64-NEXT:    blr
-;
-; DEFAULT_LARGE64-LABEL: Single_LD_USE_IE:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    mflr 0
-; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; DEFAULT_LARGE64-NEXT:    addis 6, L..C2 at u(2)
-; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
-; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_LARGE64-NEXT:    ld 5, L..C2 at l(6)
-; DEFAULT_LARGE64-NEXT:    lwzx 4, 3, 5
-; DEFAULT_LARGE64-NEXT:    addi 6, 4, 42
-; DEFAULT_LARGE64-NEXT:    stwx 6, 3, 5
-; DEFAULT_LARGE64-NEXT:    mr 3, 4
-; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
-; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
-; DEFAULT_LARGE64-NEXT:    mtlr 0
-; DEFAULT_LARGE64-NEXT:    blr
-;
-; HEURISTIC_SMALL64-LABEL: Single_LD_USE_IE:
-; HEURISTIC_SMALL64:       # %bb.0: # %entry
-; HEURISTIC_SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD1
-; HEURISTIC_SMALL64-NEXT:    lwzx 3, 13, 4
-; HEURISTIC_SMALL64-NEXT:    addi 5, 3, 42
-; HEURISTIC_SMALL64-NEXT:    stwx 5, 13, 4
-; HEURISTIC_SMALL64-NEXT:    blr
-;
-; HEURISTIC_LARGE64-LABEL: Single_LD_USE_IE:
-; HEURISTIC_LARGE64:       # %bb.0: # %entry
-; HEURISTIC_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 4, L..C1 at l(3)
-; HEURISTIC_LARGE64-NEXT:    lwzx 3, 13, 4
-; HEURISTIC_LARGE64-NEXT:    addi 5, 3, 42
-; HEURISTIC_LARGE64-NEXT:    stwx 5, 13, 4
-; HEURISTIC_LARGE64-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
-  %1 = load i32, ptr %0, align 4
-  %2 = add nsw i32 42, %1
-  store i32 %2, ptr %0, align 4
-  ret i32 %1
-}
-
-define i32 @Multiple_IE_USE_LD() {
-; DEFAULT_SMALL64-LABEL: Multiple_IE_USE_LD:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tprel) @VarTLSIE2
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_SMALL64-NEXT:    lwzx 4, 13, 4
-; DEFAULT_SMALL64-NEXT:    add 3, 3, 4
-; DEFAULT_SMALL64-NEXT:    blr
-;
-; DEFAULT_LARGE64-LABEL: Multiple_IE_USE_LD:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; DEFAULT_LARGE64-NEXT:    addis 4, L..C3 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; DEFAULT_LARGE64-NEXT:    ld 4, L..C3 at l(4)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_LARGE64-NEXT:    lwzx 4, 13, 4
-; DEFAULT_LARGE64-NEXT:    add 3, 3, 4
-; DEFAULT_LARGE64-NEXT:    blr
-;
-; HEURISTIC_SMALL64-LABEL: Multiple_IE_USE_LD:
-; HEURISTIC_SMALL64:       # %bb.0: # %entry
-; HEURISTIC_SMALL64-NEXT:    mflr 0
-; HEURISTIC_SMALL64-NEXT:    stdu 1, -48(1)
-; HEURISTIC_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; HEURISTIC_SMALL64-NEXT:    std 0, 64(1)
-; HEURISTIC_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; HEURISTIC_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSIE1
-; HEURISTIC_SMALL64-NEXT:    ld 5, L..C4(2) # target-flags(ppc-tlsld) @VarTLSIE2
-; HEURISTIC_SMALL64-NEXT:    lwzx 4, 3, 4
-; HEURISTIC_SMALL64-NEXT:    lwzx 3, 3, 5
-; HEURISTIC_SMALL64-NEXT:    add 3, 4, 3
-; HEURISTIC_SMALL64-NEXT:    addi 1, 1, 48
-; HEURISTIC_SMALL64-NEXT:    ld 0, 16(1)
-; HEURISTIC_SMALL64-NEXT:    mtlr 0
-; HEURISTIC_SMALL64-NEXT:    blr
-;
-; HEURISTIC_LARGE64-LABEL: Multiple_IE_USE_LD:
-; HEURISTIC_LARGE64:       # %bb.0: # %entry
-; HEURISTIC_LARGE64-NEXT:    mflr 0
-; HEURISTIC_LARGE64-NEXT:    stdu 1, -48(1)
-; HEURISTIC_LARGE64-NEXT:    addis 3, L..C2 at u(2)
-; HEURISTIC_LARGE64-NEXT:    std 0, 64(1)
-; HEURISTIC_LARGE64-NEXT:    addis 6, L..C3 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 3, L..C2 at l(3)
-; HEURISTIC_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; HEURISTIC_LARGE64-NEXT:    addis 5, L..C4 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 4, L..C3 at l(6)
-; HEURISTIC_LARGE64-NEXT:    ld 5, L..C4 at l(5)
-; HEURISTIC_LARGE64-NEXT:    lwzx 4, 3, 4
-; HEURISTIC_LARGE64-NEXT:    lwzx 3, 3, 5
-; HEURISTIC_LARGE64-NEXT:    add 3, 4, 3
-; HEURISTIC_LARGE64-NEXT:    addi 1, 1, 48
-; HEURISTIC_LARGE64-NEXT:    ld 0, 16(1)
-; HEURISTIC_LARGE64-NEXT:    mtlr 0
-; HEURISTIC_LARGE64-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
-  %1 = load i32, ptr %0, align 4
-  %2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE2)
-  %3 = load i32, ptr %2, align 4
-  %add = add nsw i32 %1, %3
-  ret i32 %add
-}
-
-define i32 @Multiple_LD_USE_LD() {
-; DEFAULT_SMALL64-LABEL: Multiple_LD_USE_LD:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    mflr 0
-; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
-; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
-; DEFAULT_SMALL64-NEXT:    ld 5, L..C4(2) # target-flags(ppc-tlsld) @VarTLSLD2
-; DEFAULT_SMALL64-NEXT:    lwzx 4, 3, 4
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 5
-; DEFAULT_SMALL64-NEXT:    add 3, 4, 3
-; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
-; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
-; DEFAULT_SMALL64-NEXT:    mtlr 0
-; DEFAULT_SMALL64-NEXT:    blr
-;
-; DEFAULT_LARGE64-LABEL: Multiple_LD_USE_LD:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    mflr 0
-; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
-; DEFAULT_LARGE64-NEXT:    addis 6, L..C2 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
-; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_LARGE64-NEXT:    addis 5, L..C4 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(6)
-; DEFAULT_LARGE64-NEXT:    ld 5, L..C4 at l(5)
-; DEFAULT_LARGE64-NEXT:    lwzx 4, 3, 4
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 5
-; DEFAULT_LARGE64-NEXT:    add 3, 4, 3
-; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
-; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
-; DEFAULT_LARGE64-NEXT:    mtlr 0
-; DEFAULT_LARGE64-NEXT:    blr
-;
-; HEURISTIC_SMALL64-LABEL: Multiple_LD_USE_LD:
-; HEURISTIC_SMALL64:       # %bb.0: # %entry
-; HEURISTIC_SMALL64-NEXT:    mflr 0
-; HEURISTIC_SMALL64-NEXT:    stdu 1, -48(1)
-; HEURISTIC_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; HEURISTIC_SMALL64-NEXT:    std 0, 64(1)
-; HEURISTIC_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; HEURISTIC_SMALL64-NEXT:    ld 4, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD1
-; HEURISTIC_SMALL64-NEXT:    ld 5, L..C6(2) # target-flags(ppc-tlsld) @VarTLSLD2
-; HEURISTIC_SMALL64-NEXT:    lwzx 4, 3, 4
-; HEURISTIC_SMALL64-NEXT:    lwzx 3, 3, 5
-; HEURISTIC_SMALL64-NEXT:    add 3, 4, 3
-; HEURISTIC_SMALL64-NEXT:    addi 1, 1, 48
-; HEURISTIC_SMALL64-NEXT:    ld 0, 16(1)
-; HEURISTIC_SMALL64-NEXT:    mtlr 0
-; HEURISTIC_SMALL64-NEXT:    blr
-;
-; HEURISTIC_LARGE64-LABEL: Multiple_LD_USE_LD:
-; HEURISTIC_LARGE64:       # %bb.0: # %entry
-; HEURISTIC_LARGE64-NEXT:    mflr 0
-; HEURISTIC_LARGE64-NEXT:    stdu 1, -48(1)
-; HEURISTIC_LARGE64-NEXT:    addis 3, L..C2 at u(2)
-; HEURISTIC_LARGE64-NEXT:    std 0, 64(1)
-; HEURISTIC_LARGE64-NEXT:    addis 6, L..C5 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 3, L..C2 at l(3)
-; HEURISTIC_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; HEURISTIC_LARGE64-NEXT:    addis 5, L..C6 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 4, L..C5 at l(6)
-; HEURISTIC_LARGE64-NEXT:    ld 5, L..C6 at l(5)
-; HEURISTIC_LARGE64-NEXT:    lwzx 4, 3, 4
-; HEURISTIC_LARGE64-NEXT:    lwzx 3, 3, 5
-; HEURISTIC_LARGE64-NEXT:    add 3, 4, 3
-; HEURISTIC_LARGE64-NEXT:    addi 1, 1, 48
-; HEURISTIC_LARGE64-NEXT:    ld 0, 16(1)
-; HEURISTIC_LARGE64-NEXT:    mtlr 0
-; HEURISTIC_LARGE64-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
-  %1 = load i32, ptr %0, align 4
-  %2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD2)
-  %3 = load i32, ptr %2, align 4
-  %add = add nsw i32 %1, %3
-  ret i32 %add
-}
-
-define i32 @Multiple_MIX_USE_LD() {
-; DEFAULT_SMALL64-LABEL: Multiple_MIX_USE_LD:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    mflr 0
-; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
-; DEFAULT_SMALL64-NEXT:    lwzx 6, 13, 3
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
-; DEFAULT_SMALL64-NEXT:    add 3, 6, 3
-; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
-; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
-; DEFAULT_SMALL64-NEXT:    mtlr 0
-; DEFAULT_SMALL64-NEXT:    blr
-;
-; DEFAULT_LARGE64-LABEL: Multiple_MIX_USE_LD:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    mflr 0
-; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
-; DEFAULT_LARGE64-NEXT:    addis 7, L..C2 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; DEFAULT_LARGE64-NEXT:    lwzx 6, 13, 3
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
-; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(7)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
-; DEFAULT_LARGE64-NEXT:    add 3, 6, 3
-; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
-; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
-; DEFAULT_LARGE64-NEXT:    mtlr 0
-; DEFAULT_LARGE64-NEXT:    blr
-;
-; HEURISTIC_SMALL64-LABEL: Multiple_MIX_USE_LD:
-; HEURISTIC_SMALL64:       # %bb.0: # %entry
-; HEURISTIC_SMALL64-NEXT:    mflr 0
-; HEURISTIC_SMALL64-NEXT:    stdu 1, -48(1)
-; HEURISTIC_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; HEURISTIC_SMALL64-NEXT:    std 0, 64(1)
-; HEURISTIC_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; HEURISTIC_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSIE1
-; HEURISTIC_SMALL64-NEXT:    ld 5, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD1
-; HEURISTIC_SMALL64-NEXT:    lwzx 4, 3, 4
-; HEURISTIC_SMALL64-NEXT:    lwzx 3, 3, 5
-; HEURISTIC_SMALL64-NEXT:    add 3, 4, 3
-; HEURISTIC_SMALL64-NEXT:    addi 1, 1, 48
-; HEURISTIC_SMALL64-NEXT:    ld 0, 16(1)
-; HEURISTIC_SMALL64-NEXT:    mtlr 0
-; HEURISTIC_SMALL64-NEXT:    blr
-;
-; HEURISTIC_LARGE64-LABEL: Multiple_MIX_USE_LD:
-; HEURISTIC_LARGE64:       # %bb.0: # %entry
-; HEURISTIC_LARGE64-NEXT:    mflr 0
-; HEURISTIC_LARGE64-NEXT:    stdu 1, -48(1)
-; HEURISTIC_LARGE64-NEXT:    addis 3, L..C2 at u(2)
-; HEURISTIC_LARGE64-NEXT:    std 0, 64(1)
-; HEURISTIC_LARGE64-NEXT:    addis 6, L..C3 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 3, L..C2 at l(3)
-; HEURISTIC_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; HEURISTIC_LARGE64-NEXT:    addis 5, L..C5 at u(2)
-; HEURISTIC_LARGE64-NEXT:    ld 4, L..C3 at l(6)
-; HEURISTIC_LARGE64-NEXT:    ld 5, L..C5 at l(5)
-; HEURISTIC_LARGE64-NEXT:    lwzx 4, 3, 4
-; HEURISTIC_LARGE64-NEXT:    lwzx 3, 3, 5
-; HEURISTIC_LARGE64-NEXT:    add 3, 4, 3
-; HEURISTIC_LARGE64-NEXT:    addi 1, 1, 48
-; HEURISTIC_LARGE64-NEXT:    ld 0, 16(1)
-; HEURISTIC_LARGE64-NEXT:    mtlr 0
-; HEURISTIC_LARGE64-NEXT:    blr
-entry:
-  %0 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
-  %1 = load i32, ptr %0, align 4
-  %2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
-  %3 = load i32, ptr %2, align 4
-  %add = add nsw i32 %1, %3
-  ret i32 %add
-}
-
-declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
-
-; DEFAULT_SMALL64-LABEL: .toc
-; DEFAULT_SMALL64-LABEL: L..C0:
-; DEFAULT_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
-; DEFAULT_SMALL64-LABEL: L..C1:
-; DEFAULT_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; DEFAULT_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; DEFAULT_SMALL64-LABEL: L..C2:
-; DEFAULT_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ld
-; DEFAULT_SMALL64-LABEL: L..C3:
-; DEFAULT_SMALL64-NEXT: .tc VarTLSIE2[TC],VarTLSIE2[UL]@ie
-; DEFAULT_SMALL64-LABEL: L..C4:
-; DEFAULT_SMALL64-NEXT: .tc VarTLSLD2[TC],VarTLSLD2[UL]@ld
-
-; DEFAULT_LARGE64-LABEL: .toc
-; DEFAULT_LARGE64-LABEL: L..C0:
-; DEFAULT_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
-; DEFAULT_LARGE64-LABEL: L..C1:
-; DEFAULT_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; DEFAULT_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; DEFAULT_LARGE64-LABEL: L..C2:
-; DEFAULT_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ld
-; DEFAULT_LARGE64-LABEL: L..C3:
-; DEFAULT_LARGE64-NEXT: .tc VarTLSIE2[TE],VarTLSIE2[UL]@ie
-; DEFAULT_LARGE64-LABEL: L..C4:
-; DEFAULT_LARGE64-NEXT: .tc VarTLSLD2[TE],VarTLSLD2[UL]@ld
-
-; HEURISTIC_SMALL64-LABEL: .toc
-; HEURISTIC_SMALL64-LABEL: L..C0:
-; HEURISTIC_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
-; HEURISTIC_SMALL64-LABEL: L..C1:
-; HEURISTIC_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ie
-; HEURISTIC_SMALL64-LABEL: L..C2:
-; HEURISTIC_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; HEURISTIC_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; HEURISTIC_SMALL64-LABEL: L..C3:
-; HEURISTIC_SMALL64-NEXT: .tc .VarTLSIE1[TC],VarTLSIE1[TL]@ld
-; HEURISTIC_SMALL64-LABEL: L..C4:
-; HEURISTIC_SMALL64-NEXT: .tc .VarTLSIE2[TC],VarTLSIE2[UL]@ld
-; HEURISTIC_SMALL64-LABEL: L..C5:
-; HEURISTIC_SMALL64-NEXT: .tc .VarTLSLD1[TC],VarTLSLD1[TL]@ld
-; HEURISTIC_SMALL64-LABEL: L..C6:
-; HEURISTIC_SMALL64-NEXT: .tc .VarTLSLD2[TC],VarTLSLD2[UL]@ld
-
-; HEURISTIC_LARGE64-LABEL: .toc
-; HEURISTIC_LARGE64-LABEL: L..C0:
-; HEURISTIC_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
-; HEURISTIC_LARGE64-LABEL: L..C1:
-; HEURISTIC_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ie
-; HEURISTIC_LARGE64-LABEL: L..C2:
-; HEURISTIC_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
-; HEURISTIC_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; HEURISTIC_LARGE64-LABEL: L..C3:
-; HEURISTIC_LARGE64-NEXT: .tc .VarTLSIE1[TE],VarTLSIE1[TL]@ld
-; HEURISTIC_LARGE64-LABEL: L..C4:
-; HEURISTIC_LARGE64-NEXT: .tc .VarTLSIE2[TE],VarTLSIE2[UL]@ld
-; HEURISTIC_LARGE64-LABEL: L..C5:
-; HEURISTIC_LARGE64-NEXT: .tc .VarTLSLD1[TE],VarTLSLD1[TL]@ld
-; HEURISTIC_LARGE64-LABEL: L..C6:
-; HEURISTIC_LARGE64-NEXT: .tc .VarTLSLD2[TE],VarTLSLD2[UL]@ld
diff --git a/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll b/llvm/test/CodeGen/PowerPC/check-aix-shared-lib-tls-model-opt-IRattribute.ll
similarity index 63%
rename from llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll
rename to llvm/test/CodeGen/PowerPC/check-aix-shared-lib-tls-model-opt-IRattribute.ll
index 154d573671bf5e..15fac2d0c0ad99 100644
--- a/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt-IRattribute.ll
+++ b/llvm/test/CodeGen/PowerPC/check-aix-shared-lib-tls-model-opt-IRattribute.ll
@@ -9,13 +9,13 @@ define dso_local signext i32 @testWithIRAttr() #0 {
 entry:
   ret i32 0
 }
-; Check that the aix-shared-library-tls-model-heuristic attribute is not supported on Linux and AIX (32-bit).
-; CHECK-NOT-SUPPORTED: The aix-shared-library-tls-model-heuristic attribute is only supported on AIX in 64-bit mode.
+; Check that the aix-shared-lib-tls-model-opt attribute is not supported on Linux and AIX (32-bit).
+; CHECK-NOT-SUPPORTED: The aix-shared-lib-tls-model-opt attribute is only supported on AIX in 64-bit mode.
 
 ; Make sure that the test was actually compiled successfully after using the
-; aix-shared-library-tls-model-heuristic attribute.
+; aix-shared-lib-tls-model-opt attribute.
 ; CHECK-LABEL: testWithIRAttr:
 ; CHECK:        li r3, 0
 ; CHECK-NEXT:   blr
 
-attributes #0 = { "target-features"="+aix-shared-library-tls-model-heuristic" }
+attributes #0 = { "target-features"="+aix-shared-lib-tls-model-opt" }
diff --git a/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll b/llvm/test/CodeGen/PowerPC/check-aix-shared-lib-tls-model-opt-Option.ll
similarity index 64%
rename from llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll
rename to llvm/test/CodeGen/PowerPC/check-aix-shared-lib-tls-model-opt-Option.ll
index de85655c998f86..36f8bc78c77a55 100644
--- a/llvm/test/CodeGen/PowerPC/check-aix-shared-library-tls-model-heuristic-opt.ll
+++ b/llvm/test/CodeGen/PowerPC/check-aix-shared-lib-tls-model-opt-Option.ll
@@ -1,9 +1,9 @@
-; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mattr=+aix-shared-library-tls-model-heuristic \
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff -mattr=+aix-shared-lib-tls-model-opt \
 ; RUN:   -ppc-asm-full-reg-names < %s | FileCheck %s
-; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -mattr=+aix-shared-library-tls-model-heuristic \
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff -mattr=+aix-shared-lib-tls-model-opt \
 ; RUN:   -ppc-asm-full-reg-names < %s 2>&1 | \
 ; RUN:   FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED
-; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -mattr=+aix-shared-library-tls-model-heuristic \
+; RUN: not llc -mtriple powerpc64le-unknown-linux-gnu -mattr=+aix-shared-lib-tls-model-opt \
 ; RUN:   -ppc-asm-full-reg-names < %s 2>&1 | \
 ; RUN:   FileCheck %s --check-prefix=CHECK-NOT-SUPPORTED
 
@@ -12,11 +12,11 @@ entry:
   ret i32 0
 }
 
-; Check that the aix-shared-library-tls-model-heuristic attribute is not supported on Linux and AIX (32-bit).
-; CHECK-NOT-SUPPORTED: The aix-shared-library-tls-model-heuristic attribute is only supported on AIX in 64-bit mode.
+; Check that the aix-shared-lib-tls-model-opt attribute is not supported on Linux and AIX (32-bit).
+; CHECK-NOT-SUPPORTED: The aix-shared-lib-tls-model-opt attribute is only supported on AIX in 64-bit mode.
 
 ; Make sure that the test was actually compiled successfully after using the
-; aix-shared-library-tls-model-heuristic attribute.
+; aix-shared-lib-tls-model-opt attribute.
 ; CHECK-LABEL: testNoIRAttr:
 ; CHECK:        li r3, 0
 ; CHECK-NEXT:   blr

>From 485d0b9e45dabfd956b2857caed03baa20dc69f1 Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Tue, 9 Apr 2024 01:21:02 -0400
Subject: [PATCH 7/9] Pull out logic as static function guarded by
 `Subtarget.hasAIXShLibTLSModelOpt()`.

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 43 +++++++++++++--------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index fb4f6d129afe22..076d4d4683ca7a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3362,25 +3362,18 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
   return LowerGlobalTLSAddressLinux(Op, DAG);
 }
 
-SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
-                                                    SelectionDAG &DAG) const {
-  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
-
-  if (DAG.getTarget().useEmulatedTLS())
-    report_fatal_error("Emulated TLS is not yet supported on AIX");
-
-  SDLoc dl(GA);
-  const GlobalValue *GV = GA->getGlobal();
-  EVT PtrVT = getPointerTy(DAG.getDataLayout());
-  bool Is64Bit = Subtarget.isPPC64();
-  TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+/// updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings,
+/// and then apply the update.
+static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model,
+                                         SelectionDAG &DAG,
+                                         const TargetMachine &TM) {
   // Initialize TLS model opt setting lazily:
   // (1) Use initial-exec for single TLS var references within current function.
   // (2) Use local-dynamic for multiple TLS var references within current
   // function.
   PPCFunctionInfo *FuncInfo =
       DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
-  if (Subtarget.hasAIXShLibTLSModelOpt() && !FuncInfo->isAIXFuncUseInitDone()) {
+  if (!FuncInfo->isAIXFuncUseInitDone()) {
     SmallPtrSet<const GlobalValue *, 8> TLSGV;
     // Iterate over all instructions within current function, collect all TLS
     // global variables (global variables taken as the first parameter to
@@ -3397,9 +3390,9 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
                   CF->getIntrinsicID() == Intrinsic::threadlocal_address)
                 if (const GlobalValue *GV =
                         dyn_cast<GlobalValue>(II->getOperand(0))) {
-                  TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
-                  if (Model == TLSModel::InitialExec ||
-                      Model == TLSModel::LocalDynamic)
+                  TLSModel::Model GVModel = TM.getTLSModel(GV);
+                  if (GVModel == TLSModel::InitialExec ||
+                      GVModel == TLSModel::LocalDynamic)
                     TLSGV.insert(GV);
                 }
 
@@ -3426,6 +3419,24 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
         << " function is using the TLS-IE model for TLS IE/LD accesses.\n");
     Model = TLSModel::InitialExec;
   }
+}
+
+SDValue PPCTargetLowering::LowerGlobalTLSAddressAIX(SDValue Op,
+                                                    SelectionDAG &DAG) const {
+  GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
+
+  if (DAG.getTarget().useEmulatedTLS())
+    report_fatal_error("Emulated TLS is not yet supported on AIX");
+
+  SDLoc dl(GA);
+  const GlobalValue *GV = GA->getGlobal();
+  EVT PtrVT = getPointerTy(DAG.getDataLayout());
+  bool Is64Bit = Subtarget.isPPC64();
+  TLSModel::Model Model = getTargetMachine().getTLSModel(GV);
+
+  // Apply update to the TLS model.
+  if (Subtarget.hasAIXShLibTLSModelOpt())
+    updateForAIXShLibTLSModelOpt(Model, DAG, getTargetMachine());
 
   bool IsTLSLocalExecModel = Model == TLSModel::LocalExec;
 

>From e23a03b09fc9546f0cf37bccef1fc4fe3cbf630d Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Wed, 10 Apr 2024 20:47:29 -0400
Subject: [PATCH 8/9] [NFC] address comment

---
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 076d4d4683ca7a..4460e3484df255 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -3398,11 +3398,10 @@ static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model,
 
     unsigned TLSGVCnt = TLSGV.size();
     LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGVCnt));
-    if (TLSGVCnt == 1) {
+    if (TLSGVCnt == 1)
       FuncInfo->setAIXFuncUseTLSIE();
-    } else if (TLSGVCnt > 1) {
+    else if (TLSGVCnt > 1)
       FuncInfo->setAIXFuncUseTLSLD();
-    }
     FuncInfo->setAIXFuncUseInitDone();
   }
 

>From 8925ef8165c0d009993a085bb18e086086c7e6f7 Mon Sep 17 00:00:00 2001
From: Ting Wang <Ting.Wang.SH at ibm.com>
Date: Thu, 18 Apr 2024 20:59:00 -0400
Subject: [PATCH 9/9] Update according to comments: (1) Update Options.td to
 make it clear this is about the transform from LD to IE. (2) Limit transfrom
 from LD to IE only. (3) Add target hidden flag to control Limit count of the
 transformation. (4) Update test case.

---
 clang/include/clang/Driver/Options.td         |   3 +-
 llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp     |   3 +-
 llvm/lib/Target/PowerPC/PPCISelLowering.cpp   |  33 +-
 .../Target/PowerPC/PPCMachineFunctionInfo.h   |  21 +-
 .../PowerPC/aix-shared-lib-tls-model-opt.ll   | 664 ++++++++++--------
 5 files changed, 412 insertions(+), 312 deletions(-)

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 51b37a2ed4d1a3..33efe07d84216f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5032,7 +5032,8 @@ def maix_small_local_exec_tls : Flag<["-"], "maix-small-local-exec-tls">,
 def maix_shared_lib_tls_model_opt : Flag<["-"], "maix-shared-lib-tls-model-opt">,
   Group<m_ppc_Features_Group>,
   HelpText<"For shared library loaded with the main program, use heuristics to "
-           "tune the TLS model at the function level (AIX 64-bit only).">;
+           "change local-dynamic access(es) to initial-exec access(es) at the "
+           "function level (AIX 64-bit only).">;
 def maix_struct_return : Flag<["-"], "maix-struct-return">,
   Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
   HelpText<"Return all structs in memory (PPC32 only)">,
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 1267fe5b6ec0e1..1f9c580de5af6f 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -881,7 +881,8 @@ void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
       // On AIX, TLS model heuristics may have turned local-dynamic accesses
       // into initial-exec accesses.
       PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
-      if (Model == TLSModel::LocalDynamic && FuncInfo->isAIXFuncUseTLSIE()) {
+      if (Model == TLSModel::LocalDynamic &&
+          FuncInfo->isAIXFuncUseTLSIEForLD()) {
         LLVM_DEBUG(
             dbgs() << "Current function uses IE access for default LD vars.\n");
         return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 4460e3484df255..0a7483fc45b203 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -141,6 +141,11 @@ static cl::opt<unsigned> PPCGatherAllAliasesMaxDepth(
     "ppc-gather-alias-max-depth", cl::init(18), cl::Hidden,
     cl::desc("max depth when checking alias info in GatherAllAliases()"));
 
+static cl::opt<unsigned> PPCAIXTLSModelOptUseIEForLDLimit(
+    "ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden,
+    cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a "
+             "function to use initial-exec"));
+
 STATISTIC(NumTailCalls, "Number of tail calls");
 STATISTIC(NumSiblingCalls, "Number of sibling calls");
 STATISTIC(ShufflesHandledWithVPERM,
@@ -3373,7 +3378,7 @@ static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model,
   // function.
   PPCFunctionInfo *FuncInfo =
       DAG.getMachineFunction().getInfo<PPCFunctionInfo>();
-  if (!FuncInfo->isAIXFuncUseInitDone()) {
+  if (!FuncInfo->isAIXFuncTLSModelOptInitDone()) {
     SmallPtrSet<const GlobalValue *, 8> TLSGV;
     // Iterate over all instructions within current function, collect all TLS
     // global variables (global variables taken as the first parameter to
@@ -3391,31 +3396,21 @@ static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model,
                 if (const GlobalValue *GV =
                         dyn_cast<GlobalValue>(II->getOperand(0))) {
                   TLSModel::Model GVModel = TM.getTLSModel(GV);
-                  if (GVModel == TLSModel::InitialExec ||
-                      GVModel == TLSModel::LocalDynamic)
+                  if (GVModel == TLSModel::LocalDynamic)
                     TLSGV.insert(GV);
                 }
 
     unsigned TLSGVCnt = TLSGV.size();
-    LLVM_DEBUG(dbgs() << format("TLSGV count:%d\n", TLSGVCnt));
-    if (TLSGVCnt == 1)
-      FuncInfo->setAIXFuncUseTLSIE();
-    else if (TLSGVCnt > 1)
-      FuncInfo->setAIXFuncUseTLSLD();
-    FuncInfo->setAIXFuncUseInitDone();
+    LLVM_DEBUG(dbgs() << format("LocalDynamic TLSGV count:%d\n", TLSGVCnt));
+    if (TLSGVCnt <= PPCAIXTLSModelOptUseIEForLDLimit)
+      FuncInfo->setAIXFuncUseTLSIEForLD();
+    FuncInfo->setAIXFuncTLSModelOptInitDone();
   }
 
-  if (FuncInfo->isAIXFuncUseTLSLD()) {
-    LLVM_DEBUG(
-        dbgs()
-        << DAG.getMachineFunction().getName()
-        << " function is using the TLS-LD model for TLS IE/LD accesses.\n");
-    Model = TLSModel::LocalDynamic;
-  } else if (FuncInfo->isAIXFuncUseTLSIE()) {
+  if (FuncInfo->isAIXFuncUseTLSIEForLD()) {
     LLVM_DEBUG(
-        dbgs()
-        << DAG.getMachineFunction().getName()
-        << " function is using the TLS-IE model for TLS IE/LD accesses.\n");
+        dbgs() << DAG.getMachineFunction().getName()
+               << " function is using the TLS-IE model for TLS-LD access.\n");
     Model = TLSModel::InitialExec;
   }
 }
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index aa640e8ef65e0f..b7d14da05ee248 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -150,11 +150,10 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   /// to use SExt/ZExt flags in later optimization.
   std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
 
-  /// Flags for aix-shared-library-tls-model-heuristic, will be lazily
-  /// initialized for each function.
-  bool AIXFuncUseTLSLD = false;
-  bool AIXFuncUseTLSIE = false;
-  bool AIXFuncUseInitDone = false;
+  /// Flags for aix-shared-lib-tls-model-opt, will be lazily initialized for
+  /// each function.
+  bool AIXFuncUseTLSIEForLD = false;
+  bool AIXFuncTLSModelOptInitDone = false;
 
 public:
   explicit PPCFunctionInfo(const Function &F, const TargetSubtargetInfo *STI);
@@ -227,12 +226,12 @@ class PPCFunctionInfo : public MachineFunctionInfo {
   void setHasFastCall() { HasFastCall = true; }
   bool hasFastCall() const { return HasFastCall;}
 
-  void setAIXFuncUseInitDone() { AIXFuncUseInitDone = true; }
-  bool isAIXFuncUseInitDone() const { return AIXFuncUseInitDone; }
-  void setAIXFuncUseTLSLD() { AIXFuncUseTLSLD = true; }
-  bool isAIXFuncUseTLSLD() const { return AIXFuncUseTLSLD; }
-  void setAIXFuncUseTLSIE() { AIXFuncUseTLSIE = true; }
-  bool isAIXFuncUseTLSIE() const { return AIXFuncUseTLSIE; }
+  void setAIXFuncTLSModelOptInitDone() { AIXFuncTLSModelOptInitDone = true; }
+  bool isAIXFuncTLSModelOptInitDone() const {
+    return AIXFuncTLSModelOptInitDone;
+  }
+  void setAIXFuncUseTLSIEForLD() { AIXFuncUseTLSIEForLD = true; }
+  bool isAIXFuncUseTLSIEForLD() const { return AIXFuncUseTLSIEForLD; }
 
   int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
   void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
diff --git a/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll b/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll
index 9db3c2b8256847..140377270d6d9d 100644
--- a/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-shared-lib-tls-model-opt.ll
@@ -7,77 +7,37 @@
 ; RUN:      -mattr=+aix-shared-lib-tls-model-opt --code-model=small < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_SMALL64
 ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
 ; RUN:      -mattr=+aix-shared-lib-tls-model-opt --code-model=large < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_LARGE64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-lib-tls-model-opt -ppc-aix-shared-lib-tls-model-opt-limit=2 \
+; RUN:      --code-model=small < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_LIMIT2_SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-lib-tls-model-opt -ppc-aix-shared-lib-tls-model-opt-limit=2 \
+; RUN:      --code-model=large < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_LIMIT2_LARGE64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-lib-tls-model-opt -ppc-aix-shared-lib-tls-model-opt-limit=3 \
+; RUN:      --code-model=small < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_LIMIT3_SMALL64
+; RUN: llc -verify-machineinstrs -mcpu=pwr7 -mattr=-altivec -mtriple powerpc64-ibm-aix-xcoff \
+; RUN:      -mattr=+aix-shared-lib-tls-model-opt -ppc-aix-shared-lib-tls-model-opt-limit=3 \
+; RUN:      --code-model=large < %s | FileCheck %s --check-prefixes=TLS_MODEL_OPT_LIMIT3_LARGE64
 
- at VarTLSIE1 = internal thread_local(initialexec) global i32 42, align 4
- at VarTLSIE2 = internal thread_local(initialexec) global i32 0, align 4
 @VarTLSLD1 = internal thread_local(localdynamic) global i32 42, align 4
 @VarTLSLD2 = internal thread_local(localdynamic) global i32 0, align 4
+ at VarTLSLD3 = internal thread_local(localdynamic) global i32 0, align 4
 
 ; Tune function level TLS model settings:
 ; Use initial-exec when we have a function accessing only one TLS variable.
 ; Use local-dynamic when we have a function accessing a handful or more different TLS variables.
 
-define i32 @Single_IE_USE_IE(i32 %P, i32 %Q) {
-; DEFAULT_SMALL64-LABEL: Single_IE_USE_IE:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    and 4, 3, 4
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; DEFAULT_SMALL64-NEXT:    cmpwi 4, -1
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_SMALL64-NEXT:    blr
-;
-; DEFAULT_LARGE64-LABEL: Single_IE_USE_IE:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    and 4, 3, 4
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; DEFAULT_LARGE64-NEXT:    cmpwi 4, -1
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_LARGE64-NEXT:    blr
-;
-; TLS_MODEL_OPT_SMALL64-LABEL: Single_IE_USE_IE:
-; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
-; TLS_MODEL_OPT_SMALL64-NEXT:    and 4, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 4, -1
-; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 13, 3
-; TLS_MODEL_OPT_SMALL64-NEXT:    blr
-;
-; TLS_MODEL_OPT_LARGE64-LABEL: Single_IE_USE_IE:
-; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
-; TLS_MODEL_OPT_LARGE64-NEXT:    and 4, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 4, -1
-; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 13, 3
-; TLS_MODEL_OPT_LARGE64-NEXT:    blr
-entry:
-  %a = icmp slt i32 %P, 0
-  %b = icmp slt i32 %Q, 0
-  %c = and i1 %a, %b
-  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
-  %load1 = load i32, ptr %tls1, align 4
-  br i1 %c, label %bb1, label %return
-
-bb1:
-  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
-  %load2 = load i32, ptr %tls2, align 4
-  ret i32 %load2
-
-return:
-  ret i32 %load1
-}
-
-define i32 @Single_LD_USE_IE(i32 %P, i32 %Q) {
-; DEFAULT_SMALL64-LABEL: Single_LD_USE_IE:
+define i32 @Single_LD(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Single_LD:
 ; DEFAULT_SMALL64:       # %bb.0: # %entry
 ; DEFAULT_SMALL64-NEXT:    mflr 0
 ; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
 ; DEFAULT_SMALL64-NEXT:    and 6, 3, 4
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
 ; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
 ; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tlsld) @VarTLSLD1
 ; DEFAULT_SMALL64-NEXT:    cmpwi 6, -1
 ; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
 ; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
@@ -85,17 +45,17 @@ define i32 @Single_LD_USE_IE(i32 %P, i32 %Q) {
 ; DEFAULT_SMALL64-NEXT:    mtlr 0
 ; DEFAULT_SMALL64-NEXT:    blr
 ;
-; DEFAULT_LARGE64-LABEL: Single_LD_USE_IE:
+; DEFAULT_LARGE64-LABEL: Single_LD:
 ; DEFAULT_LARGE64:       # %bb.0: # %entry
 ; DEFAULT_LARGE64-NEXT:    mflr 0
 ; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
 ; DEFAULT_LARGE64-NEXT:    and 6, 3, 4
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; DEFAULT_LARGE64-NEXT:    addis 7, L..C2 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 7, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
 ; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
 ; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(7)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C1 at l(7)
 ; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
 ; DEFAULT_LARGE64-NEXT:    cmpwi 6, -1
 ; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
@@ -103,128 +63,66 @@ define i32 @Single_LD_USE_IE(i32 %P, i32 %Q) {
 ; DEFAULT_LARGE64-NEXT:    mtlr 0
 ; DEFAULT_LARGE64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_SMALL64-LABEL: Single_LD_USE_IE:
+; TLS_MODEL_OPT_SMALL64-LABEL: Single_LD:
 ; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
 ; TLS_MODEL_OPT_SMALL64-NEXT:    and 4, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSLD1
 ; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 4, -1
 ; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 13, 3
 ; TLS_MODEL_OPT_SMALL64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_LARGE64-LABEL: Single_LD_USE_IE:
+; TLS_MODEL_OPT_LARGE64-LABEL: Single_LD:
 ; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
 ; TLS_MODEL_OPT_LARGE64-NEXT:    and 4, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 4, -1
 ; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 13, 3
 ; TLS_MODEL_OPT_LARGE64-NEXT:    blr
-entry:
-  %a = icmp slt i32 %P, 0
-  %b = icmp slt i32 %Q, 0
-  %c = and i1 %a, %b
-  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
-  %load1 = load i32, ptr %tls1, align 4
-  br i1 %c, label %bb1, label %return
-
-bb1:
-  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
-  %load2 = load i32, ptr %tls2, align 4
-  ret i32 %load2
-
-return:
-  ret i32 %load1
-}
-
-define i32 @Multiple_IE_USE_LD(i32 %P, i32 %Q) {
-; DEFAULT_SMALL64-LABEL: Multiple_IE_USE_LD:
-; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    and 3, 3, 4
-; DEFAULT_SMALL64-NEXT:    cmpwi 3, -1
-; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB2_2
-; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C3(2) # target-flags(ppc-tprel) @VarTLSIE2
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_SMALL64-NEXT:    blr
-; DEFAULT_SMALL64-NEXT:  L..BB2_2: # %return
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_SMALL64-NEXT:    blr
 ;
-; DEFAULT_LARGE64-LABEL: Multiple_IE_USE_LD:
-; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    and 3, 3, 4
-; DEFAULT_LARGE64-NEXT:    cmpwi 3, -1
-; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB2_2
-; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C3 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C3 at l(3)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_LARGE64-NEXT:    blr
-; DEFAULT_LARGE64-NEXT:  L..BB2_2: # %return
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_LARGE64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: Single_LD:
+; TLS_MODEL_OPT_LIMIT2_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_SMALL64-LABEL: Multiple_IE_USE_LD:
-; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
-; TLS_MODEL_OPT_SMALL64-NEXT:    mflr 0
-; TLS_MODEL_OPT_SMALL64-NEXT:    stdu 1, -48(1)
-; TLS_MODEL_OPT_SMALL64-NEXT:    and 6, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
-; TLS_MODEL_OPT_SMALL64-NEXT:    std 0, 64(1)
-; TLS_MODEL_OPT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 6, -1
-; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB2_2
-; TLS_MODEL_OPT_SMALL64-NEXT:  # %bb.1: # %bb1
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSIE2
-; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB2_3
-; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB2_2: # %return
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @VarTLSIE1
-; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB2_3: # %bb1
-; TLS_MODEL_OPT_SMALL64-NEXT:    addi 1, 1, 48
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 0, 16(1)
-; TLS_MODEL_OPT_SMALL64-NEXT:    mtlr 0
-; TLS_MODEL_OPT_SMALL64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: Single_LD:
+; TLS_MODEL_OPT_LIMIT2_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_LARGE64-LABEL: Multiple_IE_USE_LD:
-; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
-; TLS_MODEL_OPT_LARGE64-NEXT:    mflr 0
-; TLS_MODEL_OPT_LARGE64-NEXT:    stdu 1, -48(1)
-; TLS_MODEL_OPT_LARGE64-NEXT:    and 6, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C2 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    std 0, 64(1)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C2 at l(3)
-; TLS_MODEL_OPT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 6, -1
-; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB2_2
-; TLS_MODEL_OPT_LARGE64-NEXT:  # %bb.1: # %bb1
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C3 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C3 at l(4)
-; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB2_3
-; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB2_2: # %return
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C4 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C4 at l(4)
-; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB2_3: # %bb1
-; TLS_MODEL_OPT_LARGE64-NEXT:    addi 1, 1, 48
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 0, 16(1)
-; TLS_MODEL_OPT_LARGE64-NEXT:    mtlr 0
-; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: Single_LD:
+; TLS_MODEL_OPT_LIMIT3_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: Single_LD:
+; TLS_MODEL_OPT_LIMIT3_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    and 4, 3, 4
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    cmpwi 4, -1
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    blr
 entry:
   %a = icmp slt i32 %P, 0
   %b = icmp slt i32 %Q, 0
   %c = and i1 %a, %b
-  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
   %load1 = load i32, ptr %tls1, align 4
   br i1 %c, label %bb1, label %return
 
 bb1:
-  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE2)
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
   %load2 = load i32, ptr %tls2, align 4
   ret i32 %load2
 
@@ -232,104 +130,164 @@ return:
   ret i32 %load1
 }
 
-define i32 @Multiple_LD_USE_LD(i32 %P, i32 %Q) {
-; DEFAULT_SMALL64-LABEL: Multiple_LD_USE_LD:
+define i32 @Two_LDs(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Two_LDs:
 ; DEFAULT_SMALL64:       # %bb.0: # %entry
 ; DEFAULT_SMALL64-NEXT:    mflr 0
 ; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
 ; DEFAULT_SMALL64-NEXT:    and 6, 3, 4
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
 ; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
 ; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
 ; DEFAULT_SMALL64-NEXT:    cmpwi 6, -1
-; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB3_2
+; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB1_2
 ; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD2
 ; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
-; DEFAULT_SMALL64-NEXT:    b L..BB3_3
-; DEFAULT_SMALL64-NEXT:  L..BB3_2: # %return
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    b L..BB1_3
+; DEFAULT_SMALL64-NEXT:  L..BB1_2: # %return
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tlsld) @VarTLSLD1
 ; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
-; DEFAULT_SMALL64-NEXT:  L..BB3_3: # %bb1
+; DEFAULT_SMALL64-NEXT:  L..BB1_3: # %bb1
 ; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
 ; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
 ; DEFAULT_SMALL64-NEXT:    mtlr 0
 ; DEFAULT_SMALL64-NEXT:    blr
 ;
-; DEFAULT_LARGE64-LABEL: Multiple_LD_USE_LD:
+; DEFAULT_LARGE64-LABEL: Two_LDs:
 ; DEFAULT_LARGE64:       # %bb.0: # %entry
 ; DEFAULT_LARGE64-NEXT:    mflr 0
 ; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
 ; DEFAULT_LARGE64-NEXT:    and 6, 3, 4
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
 ; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
 ; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
 ; DEFAULT_LARGE64-NEXT:    cmpwi 6, -1
-; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB3_2
+; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB1_2
 ; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
-; DEFAULT_LARGE64-NEXT:    addis 4, L..C4 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 4, L..C4 at l(4)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
-; DEFAULT_LARGE64-NEXT:    b L..BB3_3
-; DEFAULT_LARGE64-NEXT:  L..BB3_2: # %return
 ; DEFAULT_LARGE64-NEXT:    addis 4, L..C2 at u(2)
 ; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(4)
 ; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
-; DEFAULT_LARGE64-NEXT:  L..BB3_3: # %bb1
+; DEFAULT_LARGE64-NEXT:    b L..BB1_3
+; DEFAULT_LARGE64-NEXT:  L..BB1_2: # %return
+; DEFAULT_LARGE64-NEXT:    addis 4, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C1 at l(4)
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:  L..BB1_3: # %bb1
 ; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
 ; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
 ; DEFAULT_LARGE64-NEXT:    mtlr 0
 ; DEFAULT_LARGE64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_SMALL64-LABEL: Multiple_LD_USE_LD:
+; TLS_MODEL_OPT_SMALL64-LABEL: Two_LDs:
 ; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
 ; TLS_MODEL_OPT_SMALL64-NEXT:    mflr 0
 ; TLS_MODEL_OPT_SMALL64-NEXT:    stdu 1, -48(1)
 ; TLS_MODEL_OPT_SMALL64-NEXT:    and 6, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
 ; TLS_MODEL_OPT_SMALL64-NEXT:    std 0, 64(1)
 ; TLS_MODEL_OPT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
 ; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 6, -1
-; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB3_2
+; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB1_2
 ; TLS_MODEL_OPT_SMALL64-NEXT:  # %bb.1: # %bb1
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD2
 ; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB3_3
-; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB3_2: # %return
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C6(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB1_3
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB1_2: # %return
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSLD1
 ; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB3_3: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB1_3: # %bb1
 ; TLS_MODEL_OPT_SMALL64-NEXT:    addi 1, 1, 48
 ; TLS_MODEL_OPT_SMALL64-NEXT:    ld 0, 16(1)
 ; TLS_MODEL_OPT_SMALL64-NEXT:    mtlr 0
 ; TLS_MODEL_OPT_SMALL64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_LARGE64-LABEL: Multiple_LD_USE_LD:
+; TLS_MODEL_OPT_LARGE64-LABEL: Two_LDs:
 ; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
 ; TLS_MODEL_OPT_LARGE64-NEXT:    mflr 0
 ; TLS_MODEL_OPT_LARGE64-NEXT:    stdu 1, -48(1)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    and 6, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    std 0, 64(1)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
 ; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 6, -1
-; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB3_2
+; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB1_2
 ; TLS_MODEL_OPT_LARGE64-NEXT:  # %bb.1: # %bb1
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C5 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C5 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C2 at l(4)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB3_3
-; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB3_2: # %return
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C6 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C6 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB1_3
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB1_2: # %return
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C3 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C3 at l(4)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB3_3: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB1_3: # %bb1
 ; TLS_MODEL_OPT_LARGE64-NEXT:    addi 1, 1, 48
 ; TLS_MODEL_OPT_LARGE64-NEXT:    ld 0, 16(1)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    mtlr 0
 ; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: Two_LDs:
+; TLS_MODEL_OPT_LIMIT2_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    and 3, 3, 4
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    cmpwi 3, -1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    bgt 0, L..BB1_2
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD2
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:  L..BB1_2: # %return
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: Two_LDs:
+; TLS_MODEL_OPT_LIMIT2_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    and 3, 3, 4
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    cmpwi 3, -1
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    bgt 0, L..BB1_2
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:  L..BB1_2: # %return
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: Two_LDs:
+; TLS_MODEL_OPT_LIMIT3_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    and 3, 3, 4
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    cmpwi 3, -1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    bgt 0, L..BB1_2
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD2
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:  L..BB1_2: # %return
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: Two_LDs:
+; TLS_MODEL_OPT_LIMIT3_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    and 3, 3, 4
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    cmpwi 3, -1
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    bgt 0, L..BB1_2
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:  L..BB1_2: # %return
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    blr
 entry:
   %a = icmp slt i32 %P, 0
   %b = icmp slt i32 %Q, 0
@@ -347,114 +305,226 @@ return:
   ret i32 %load1
 }
 
-define i32 @Multiple_MIX_USE_LD(i32 %P, i32 %Q) {
-; DEFAULT_SMALL64-LABEL: Multiple_MIX_USE_LD:
+define i32 @Three_LDs(i32 %P, i32 %Q) {
+; DEFAULT_SMALL64-LABEL: Three_LDs:
 ; DEFAULT_SMALL64:       # %bb.0: # %entry
-; DEFAULT_SMALL64-NEXT:    and 3, 3, 4
-; DEFAULT_SMALL64-NEXT:    cmpwi 3, -1
-; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB4_2
-; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
 ; DEFAULT_SMALL64-NEXT:    mflr 0
 ; DEFAULT_SMALL64-NEXT:    stdu 1, -48(1)
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; DEFAULT_SMALL64-NEXT:    and 6, 3, 4
+; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tlsldm) @"_$TLSML"
 ; DEFAULT_SMALL64-NEXT:    std 0, 64(1)
 ; DEFAULT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; DEFAULT_SMALL64-NEXT:    cmpwi 6, -1
+; DEFAULT_SMALL64-NEXT:    bgt 0, L..BB2_2
+; DEFAULT_SMALL64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; DEFAULT_SMALL64-NEXT:    ld 5, L..C3(2) # target-flags(ppc-tlsld) @VarTLSLD3
+; DEFAULT_SMALL64-NEXT:    lwzx 4, 3, 4
+; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 5
+; DEFAULT_SMALL64-NEXT:    add 3, 4, 3
+; DEFAULT_SMALL64-NEXT:    b L..BB2_3
+; DEFAULT_SMALL64-NEXT:  L..BB2_2: # %return
+; DEFAULT_SMALL64-NEXT:    ld 4, L..C1(2) # target-flags(ppc-tlsld) @VarTLSLD1
 ; DEFAULT_SMALL64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_SMALL64-NEXT:  L..BB2_3: # %return
 ; DEFAULT_SMALL64-NEXT:    addi 1, 1, 48
 ; DEFAULT_SMALL64-NEXT:    ld 0, 16(1)
 ; DEFAULT_SMALL64-NEXT:    mtlr 0
 ; DEFAULT_SMALL64-NEXT:    blr
-; DEFAULT_SMALL64-NEXT:  L..BB4_2: # %return
-; DEFAULT_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSIE1
-; DEFAULT_SMALL64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_SMALL64-NEXT:    blr
 ;
-; DEFAULT_LARGE64-LABEL: Multiple_MIX_USE_LD:
+; DEFAULT_LARGE64-LABEL: Three_LDs:
 ; DEFAULT_LARGE64:       # %bb.0: # %entry
-; DEFAULT_LARGE64-NEXT:    and 3, 3, 4
-; DEFAULT_LARGE64-NEXT:    cmpwi 3, -1
-; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB4_2
-; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
 ; DEFAULT_LARGE64-NEXT:    mflr 0
 ; DEFAULT_LARGE64-NEXT:    stdu 1, -48(1)
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
-; DEFAULT_LARGE64-NEXT:    addis 6, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    and 6, 3, 4
+; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
 ; DEFAULT_LARGE64-NEXT:    std 0, 64(1)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
 ; DEFAULT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
-; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(6)
+; DEFAULT_LARGE64-NEXT:    cmpwi 6, -1
+; DEFAULT_LARGE64-NEXT:    bgt 0, L..BB2_2
+; DEFAULT_LARGE64-NEXT:  # %bb.1: # %bb1
+; DEFAULT_LARGE64-NEXT:    addis 4, L..C2 at u(2)
+; DEFAULT_LARGE64-NEXT:    addis 5, L..C3 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C2 at l(4)
+; DEFAULT_LARGE64-NEXT:    ld 5, L..C3 at l(5)
+; DEFAULT_LARGE64-NEXT:    lwzx 4, 3, 4
+; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 5
+; DEFAULT_LARGE64-NEXT:    add 3, 4, 3
+; DEFAULT_LARGE64-NEXT:    b L..BB2_3
+; DEFAULT_LARGE64-NEXT:  L..BB2_2: # %return
+; DEFAULT_LARGE64-NEXT:    addis 4, L..C1 at u(2)
+; DEFAULT_LARGE64-NEXT:    ld 4, L..C1 at l(4)
 ; DEFAULT_LARGE64-NEXT:    lwzx 3, 3, 4
+; DEFAULT_LARGE64-NEXT:  L..BB2_3: # %return
 ; DEFAULT_LARGE64-NEXT:    addi 1, 1, 48
 ; DEFAULT_LARGE64-NEXT:    ld 0, 16(1)
 ; DEFAULT_LARGE64-NEXT:    mtlr 0
 ; DEFAULT_LARGE64-NEXT:    blr
-; DEFAULT_LARGE64-NEXT:  L..BB4_2: # %return
-; DEFAULT_LARGE64-NEXT:    addis 3, L..C0 at u(2)
-; DEFAULT_LARGE64-NEXT:    ld 3, L..C0 at l(3)
-; DEFAULT_LARGE64-NEXT:    lwzx 3, 13, 3
-; DEFAULT_LARGE64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_SMALL64-LABEL: Multiple_MIX_USE_LD:
+; TLS_MODEL_OPT_SMALL64-LABEL: Three_LDs:
 ; TLS_MODEL_OPT_SMALL64:       # %bb.0: # %entry
 ; TLS_MODEL_OPT_SMALL64-NEXT:    mflr 0
 ; TLS_MODEL_OPT_SMALL64-NEXT:    stdu 1, -48(1)
 ; TLS_MODEL_OPT_SMALL64-NEXT:    and 6, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tlsldm) @"_$TLSML"
 ; TLS_MODEL_OPT_SMALL64-NEXT:    std 0, 64(1)
 ; TLS_MODEL_OPT_SMALL64-NEXT:    bla .__tls_get_mod[PR]
 ; TLS_MODEL_OPT_SMALL64-NEXT:    cmpwi 6, -1
-; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB4_2
+; TLS_MODEL_OPT_SMALL64-NEXT:    bgt 0, L..BB2_2
 ; TLS_MODEL_OPT_SMALL64-NEXT:  # %bb.1: # %bb1
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C6(2) # target-flags(ppc-tlsld) @VarTLSLD1
-; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB4_3
-; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB4_2: # %return
-; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C4(2) # target-flags(ppc-tlsld) @VarTLSIE1
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 5, L..C4(2) # target-flags(ppc-tlsld) @VarTLSLD3
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 4, 3, 4
+; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 5
+; TLS_MODEL_OPT_SMALL64-NEXT:    add 3, 4, 3
+; TLS_MODEL_OPT_SMALL64-NEXT:    b L..BB2_3
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSLD1
 ; TLS_MODEL_OPT_SMALL64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB4_3: # %bb1
+; TLS_MODEL_OPT_SMALL64-NEXT:  L..BB2_3: # %return
 ; TLS_MODEL_OPT_SMALL64-NEXT:    addi 1, 1, 48
 ; TLS_MODEL_OPT_SMALL64-NEXT:    ld 0, 16(1)
 ; TLS_MODEL_OPT_SMALL64-NEXT:    mtlr 0
 ; TLS_MODEL_OPT_SMALL64-NEXT:    blr
 ;
-; TLS_MODEL_OPT_LARGE64-LABEL: Multiple_MIX_USE_LD:
+; TLS_MODEL_OPT_LARGE64-LABEL: Three_LDs:
 ; TLS_MODEL_OPT_LARGE64:       # %bb.0: # %entry
 ; TLS_MODEL_OPT_LARGE64-NEXT:    mflr 0
 ; TLS_MODEL_OPT_LARGE64-NEXT:    stdu 1, -48(1)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    and 6, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 3, L..C1 at u(2)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    std 0, 64(1)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 3, L..C1 at l(3)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    bla .__tls_get_mod[PR]
 ; TLS_MODEL_OPT_LARGE64-NEXT:    cmpwi 6, -1
-; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB4_2
+; TLS_MODEL_OPT_LARGE64-NEXT:    bgt 0, L..BB2_2
 ; TLS_MODEL_OPT_LARGE64-NEXT:  # %bb.1: # %bb1
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C6 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C6 at l(4)
-; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB4_3
-; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB4_2: # %return
-; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C4 at u(2)
-; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C4 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C2 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 5, L..C4 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C2 at l(4)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 5, L..C4 at l(5)
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 4, 3, 4
+; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 5
+; TLS_MODEL_OPT_LARGE64-NEXT:    add 3, 4, 3
+; TLS_MODEL_OPT_LARGE64-NEXT:    b L..BB2_3
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_LARGE64-NEXT:    addis 4, L..C3 at u(2)
+; TLS_MODEL_OPT_LARGE64-NEXT:    ld 4, L..C3 at l(4)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    lwzx 3, 3, 4
-; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB4_3: # %bb1
+; TLS_MODEL_OPT_LARGE64-NEXT:  L..BB2_3: # %return
 ; TLS_MODEL_OPT_LARGE64-NEXT:    addi 1, 1, 48
 ; TLS_MODEL_OPT_LARGE64-NEXT:    ld 0, 16(1)
 ; TLS_MODEL_OPT_LARGE64-NEXT:    mtlr 0
 ; TLS_MODEL_OPT_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: Three_LDs:
+; TLS_MODEL_OPT_LIMIT2_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    mflr 0
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 3, L..C2(2) # target-flags(ppc-tlsldm) @"_$TLSML"
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    bgt 0, L..BB2_2
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 4, L..C3(2) # target-flags(ppc-tlsld) @VarTLSLD2
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 5, L..C4(2) # target-flags(ppc-tlsld) @VarTLSLD3
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    lwzx 4, 3, 4
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    lwzx 3, 3, 5
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    add 3, 4, 3
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    b L..BB2_3
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 4, L..C5(2) # target-flags(ppc-tlsld) @VarTLSLD1
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:  L..BB2_3: # %return
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: Three_LDs:
+; TLS_MODEL_OPT_LIMIT2_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    mflr 0
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    stdu 1, -48(1)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    and 6, 3, 4
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 3, L..C2 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    std 0, 64(1)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 3, L..C2 at l(3)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    bla .__tls_get_mod[PR]
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    cmpwi 6, -1
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    bgt 0, L..BB2_2
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 4, L..C3 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 5, L..C4 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 4, L..C3 at l(4)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 5, L..C4 at l(5)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    lwzx 4, 3, 4
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    lwzx 3, 3, 5
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    add 3, 4, 3
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    b L..BB2_3
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addis 4, L..C5 at u(2)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 4, L..C5 at l(4)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    lwzx 3, 3, 4
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:  L..BB2_3: # %return
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    addi 1, 1, 48
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    ld 0, 16(1)
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    mtlr 0
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: Three_LDs:
+; TLS_MODEL_OPT_LIMIT3_SMALL64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    and 3, 3, 4
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    cmpwi 3, -1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    bgt 0, L..BB2_2
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    ld 3, L..C1(2) # target-flags(ppc-tprel) @VarTLSLD2
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    ld 4, L..C2(2) # target-flags(ppc-tprel) @VarTLSLD3
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    lwzx 4, 13, 4
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    add 3, 3, 4
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    ld 3, L..C0(2) # target-flags(ppc-tprel) @VarTLSLD1
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT:    blr
+;
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: Three_LDs:
+; TLS_MODEL_OPT_LIMIT3_LARGE64:       # %bb.0: # %entry
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    and 3, 3, 4
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    cmpwi 3, -1
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    bgt 0, L..BB2_2
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:  # %bb.1: # %bb1
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    addis 3, L..C1 at u(2)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    addis 4, L..C2 at u(2)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    ld 3, L..C1 at l(3)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    ld 4, L..C2 at l(4)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    lwzx 4, 13, 4
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    add 3, 3, 4
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    blr
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:  L..BB2_2: # %return
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    addis 3, L..C0 at u(2)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    ld 3, L..C0 at l(3)
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    lwzx 3, 13, 3
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT:    blr
 entry:
   %a = icmp slt i32 %P, 0
   %b = icmp slt i32 %Q, 0
   %c = and i1 %a, %b
-  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSIE1)
+  %tls1 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
   %load1 = load i32, ptr %tls1, align 4
   br i1 %c, label %bb1, label %return
 
 bb1:
-  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD1)
+  %tls2 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD2)
   %load2 = load i32, ptr %tls2, align 4
-  ret i32 %load2
+  %tls3 = tail call align 4 ptr @llvm.threadlocal.address.p0(ptr align 4 @VarTLSLD3)
+  %load3 = load i32, ptr %tls3, align 4
+  %sum = add i32 %load2, %load3
+  ret i32 %sum
 
 return:
   ret i32 %load1
@@ -464,60 +534,94 @@ declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull)
 
 ; DEFAULT_SMALL64-LABEL: .toc
 ; DEFAULT_SMALL64-LABEL: L..C0:
-; DEFAULT_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
-; DEFAULT_SMALL64-LABEL: L..C1:
 ; DEFAULT_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; DEFAULT_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; DEFAULT_SMALL64-LABEL: L..C2:
+; DEFAULT_SMALL64-LABEL: L..C1:
 ; DEFAULT_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ld
-; DEFAULT_SMALL64-LABEL: L..C3:
-; DEFAULT_SMALL64-NEXT: .tc VarTLSIE2[TC],VarTLSIE2[UL]@ie
-; DEFAULT_SMALL64-LABEL: L..C4:
+; DEFAULT_SMALL64-LABEL: L..C2:
 ; DEFAULT_SMALL64-NEXT: .tc VarTLSLD2[TC],VarTLSLD2[UL]@ld
+; DEFAULT_SMALL64-LABEL: L..C3:
+; DEFAULT_SMALL64-NEXT: .tc VarTLSLD3[TC],VarTLSLD3[UL]@ld
 
 ; DEFAULT_LARGE64-LABEL: .toc
 ; DEFAULT_LARGE64-LABEL: L..C0:
-; DEFAULT_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
-; DEFAULT_LARGE64-LABEL: L..C1:
 ; DEFAULT_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; DEFAULT_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; DEFAULT_LARGE64-LABEL: L..C2:
+; DEFAULT_LARGE64-LABEL: L..C1:
 ; DEFAULT_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ld
-; DEFAULT_LARGE64-LABEL: L..C3:
-; DEFAULT_LARGE64-NEXT: .tc VarTLSIE2[TE],VarTLSIE2[UL]@ie
-; DEFAULT_LARGE64-LABEL: L..C4:
+; DEFAULT_LARGE64-LABEL: L..C2:
 ; DEFAULT_LARGE64-NEXT: .tc VarTLSLD2[TE],VarTLSLD2[UL]@ld
+; DEFAULT_LARGE64-LABEL: L..C3:
+; DEFAULT_LARGE64-NEXT: .tc VarTLSLD3[TE],VarTLSLD3[UL]@ld
 
 ; TLS_MODEL_OPT_SMALL64-LABEL: .toc
 ; TLS_MODEL_OPT_SMALL64-LABEL: L..C0:
-; TLS_MODEL_OPT_SMALL64-NEXT: .tc VarTLSIE1[TC],VarTLSIE1[TL]@ie
-; TLS_MODEL_OPT_SMALL64-LABEL: L..C1:
 ; TLS_MODEL_OPT_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ie
-; TLS_MODEL_OPT_SMALL64-LABEL: L..C2:
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C1:
 ; TLS_MODEL_OPT_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; TLS_MODEL_OPT_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; TLS_MODEL_OPT_SMALL64-LABEL: L..C3:
-; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSIE2[TC],VarTLSIE2[UL]@ld
-; TLS_MODEL_OPT_SMALL64-LABEL: L..C4:
-; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSIE1[TC],VarTLSIE1[TL]@ld
-; TLS_MODEL_OPT_SMALL64-LABEL: L..C5:
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C2:
 ; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSLD2[TC],VarTLSLD2[UL]@ld
-; TLS_MODEL_OPT_SMALL64-LABEL: L..C6:
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C3:
 ; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSLD1[TC],VarTLSLD1[TL]@ld
+; TLS_MODEL_OPT_SMALL64-LABEL: L..C4:
+; TLS_MODEL_OPT_SMALL64-NEXT: .tc .VarTLSLD3[TC],VarTLSLD3[UL]@ld
 
 ; TLS_MODEL_OPT_LARGE64-LABEL: .toc
 ; TLS_MODEL_OPT_LARGE64-LABEL: L..C0:
-; TLS_MODEL_OPT_LARGE64-NEXT: .tc VarTLSIE1[TE],VarTLSIE1[TL]@ie
-; TLS_MODEL_OPT_LARGE64-LABEL: L..C1:
 ; TLS_MODEL_OPT_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ie
-; TLS_MODEL_OPT_LARGE64-LABEL: L..C2:
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C1:
 ; TLS_MODEL_OPT_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
 ; TLS_MODEL_OPT_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
-; TLS_MODEL_OPT_LARGE64-LABEL: L..C3:
-; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSIE2[TE],VarTLSIE2[UL]@ld
-; TLS_MODEL_OPT_LARGE64-LABEL: L..C4:
-; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSIE1[TE],VarTLSIE1[TL]@ld
-; TLS_MODEL_OPT_LARGE64-LABEL: L..C5:
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C2:
 ; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSLD2[TE],VarTLSLD2[UL]@ld
-; TLS_MODEL_OPT_LARGE64-LABEL: L..C6:
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C3:
 ; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSLD1[TE],VarTLSLD1[TL]@ld
+; TLS_MODEL_OPT_LARGE64-LABEL: L..C4:
+; TLS_MODEL_OPT_LARGE64-NEXT: .tc .VarTLSLD3[TE],VarTLSLD3[UL]@ld
+
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: .toc
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: L..C0:
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ie
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: L..C1:
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .tc VarTLSLD2[TC],VarTLSLD2[UL]@ie
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: L..C2:
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: L..C3:
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .tc .VarTLSLD2[TC],VarTLSLD2[UL]@ld
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: L..C4:
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .tc .VarTLSLD3[TC],VarTLSLD3[UL]@ld
+; TLS_MODEL_OPT_LIMIT2_SMALL64-LABEL: L..C5:
+; TLS_MODEL_OPT_LIMIT2_SMALL64-NEXT: .tc .VarTLSLD1[TC],VarTLSLD1[TL]@ld
+
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: .toc
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: L..C0:
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ie
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: L..C1:
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .tc VarTLSLD2[TE],VarTLSLD2[UL]@ie
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: L..C2:
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .tc _Renamed..5f24__TLSML[TC],_Renamed..5f24__TLSML[TC]@ml
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .rename _Renamed..5f24__TLSML[TC],"_$TLSML"
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: L..C3:
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .tc .VarTLSLD2[TE],VarTLSLD2[UL]@ld
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: L..C4:
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .tc .VarTLSLD3[TE],VarTLSLD3[UL]@ld
+; TLS_MODEL_OPT_LIMIT2_LARGE64-LABEL: L..C5:
+; TLS_MODEL_OPT_LIMIT2_LARGE64-NEXT: .tc .VarTLSLD1[TE],VarTLSLD1[TL]@ld
+
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: .toc
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: L..C0:
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT: .tc VarTLSLD1[TC],VarTLSLD1[TL]@ie
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: L..C1:
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT: .tc VarTLSLD2[TC],VarTLSLD2[UL]@ie
+; TLS_MODEL_OPT_LIMIT3_SMALL64-LABEL: L..C2:
+; TLS_MODEL_OPT_LIMIT3_SMALL64-NEXT: .tc VarTLSLD3[TC],VarTLSLD3[UL]@ie
+
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: .toc
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: L..C0:
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT: .tc VarTLSLD1[TE],VarTLSLD1[TL]@ie
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: L..C1:
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT: .tc VarTLSLD2[TE],VarTLSLD2[UL]@ie
+; TLS_MODEL_OPT_LIMIT3_LARGE64-LABEL: L..C2:
+; TLS_MODEL_OPT_LIMIT3_LARGE64-NEXT: .tc VarTLSLD3[TE],VarTLSLD3[UL]@ie



More information about the cfe-commits mailing list