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

Felix via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 8 22:25:29 PDT 2024


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

>From b98cb6aa10d146bf2c969ff861b44f730c640130 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/7] [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 16942c6893a16d..631a5465ed119f 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -2931,10 +2931,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 53da3d430f69edb9051d6a9747a0c667daf60441 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/7] [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 0e106e1c03eaac053825e2895c30ef48afa2d234 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/7] 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 535616d33a8032..00df231ed1885c 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -329,6 +329,10 @@ def FeatureAIXLocalExecTLS :
                    "Produce a TOC-free local-exec 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 631a5465ed119f..c2162ba7c30313 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -877,6 +877,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 43e4a34a9b3483..58633608065da4 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 54dfd43b0f532cbbb1b91218e83343481280f486 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/7] 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 00df231ed1885c..535616d33a8032 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -329,10 +329,6 @@ def FeatureAIXLocalExecTLS :
                    "Produce a TOC-free local-exec 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 c2162ba7c30313..16942c6893a16d 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -877,13 +877,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
@@ -2938,10 +2931,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 58633608065da4..43e4a34a9b3483 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 547d6c7eb7d9a3ccc82eeb7254fdeac0f21e5226 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/7] 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 f745e573eb2686..0a257081e7375b 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5019,6 +5019,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 535616d33a8032..788f04472582bb 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -329,6 +329,12 @@ def FeatureAIXLocalExecTLS :
                    "Produce a TOC-free local-exec 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 16942c6893a16d..508c96c4e0b66e 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -877,6 +877,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
@@ -2924,7 +2932,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 43e4a34a9b3483..89ee47b6fc2eca 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 653d9bda99192a..1bb744d016fedc 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 8cd54b7a043cea1859aab6248e97264e933677bb 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/7] 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 0a257081e7375b..119c72721e5860 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5019,10 +5019,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 788f04472582bb..b3fe3633ea64a7 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -329,9 +329,9 @@ def FeatureAIXLocalExecTLS :
                    "Produce a TOC-free local-exec 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 508c96c4e0b66e..8571d528fb0eeb 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -877,12 +877,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!");
@@ -2935,7 +2935,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 89ee47b6fc2eca..d62bb802d6c504 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 1bb744d016fedc..916301eca4f5c8 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 c52530e69945aadd1d0fcb8619201332c5b73138 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/7] 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 d62bb802d6c504..745381c63fc1fe 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;
 



More information about the llvm-commits mailing list