[lld] 35e0470 - [ELF,PPC64] Scope checkPPC64TLSRelax to section and simplify TLS markers

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 14 18:02:58 PST 2026


Author: Fangrui Song
Date: 2026-02-14T18:02:53-08:00
New Revision: 35e04701dd3a0352176de6cafc6ac4e0f18b9089

URL: https://github.com/llvm/llvm-project/commit/35e04701dd3a0352176de6cafc6ac4e0f18b9089
DIFF: https://github.com/llvm/llvm-project/commit/35e04701dd3a0352176de6cafc6ac4e0f18b9089.diff

LOG: [ELF,PPC64] Scope checkPPC64TLSRelax to section and simplify TLS markers

checkPPC64TLSRelax detects TLS GD/LD without TLSGD/TLSLD markers
(generated from old IBM XL) and disables TLS optimization. Previously it
set a per-file flag (ppc64DisableTLSRelax). Now scope it in the section
being scanned.

In addition, simplify the R_PPC64_TLSGD/R_PPC64_TLSLD marker handling:
the redundant `sym.setFlags(NEEDS_TLSIE)` is unnecessary as the
preceding GOT_TLSGD relocation already sets it.

Added: 
    

Modified: 
    lld/ELF/Arch/PPC64.cpp
    lld/ELF/InputFiles.h
    lld/test/ELF/ppc64-tls-missing-gdld.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp
index bf1df37231a90..cb237fb1385eb 100644
--- a/lld/ELF/Arch/PPC64.cpp
+++ b/lld/ELF/Arch/PPC64.cpp
@@ -1144,23 +1144,18 @@ static bool isTocOptType(RelType type) {
   }
 }
 
-// R_PPC64_TLSGD/R_PPC64_TLSLD is required to mark `bl __tls_get_addr` for
-// General Dynamic/Local Dynamic code sequences. If a GD/LD GOT relocation is
-// found but no R_PPC64_TLSGD/R_PPC64_TLSLD is seen, we assume that the
-// instructions are generated by very old IBM XL compilers. Work around the
-// issue by disabling GD/LD to IE/LE relaxation.
+// Return true if the section has GD/LD GOT relocations without
+// R_PPC64_TLSGD/R_PPC64_TLSLD markers. Old IBM XL compilers generate GD/LD code
+// sequences without markers; disable GD/LD to IE/LE relaxation for the section.
 template <class RelTy>
-static void checkPPC64TLSRelax(InputSectionBase &sec, Relocs<RelTy> rels) {
-  // Skip if sec is synthetic (sec.file is null) or if sec has been marked.
-  if (!sec.file || sec.file->ppc64DisableTLSRelax)
-    return;
-  bool hasGDLD = false;
+static bool missingTlsGdLdMarker(InputSectionBase &sec, Relocs<RelTy> rels) {
+  bool hasGotGdLd = false;
   for (const RelTy &rel : rels) {
     RelType type = rel.getType(false);
     switch (type) {
     case R_PPC64_TLSGD:
     case R_PPC64_TLSLD:
-      return; // Found a marker
+      return false; // Found a marker
     case R_PPC64_GOT_TLSGD16:
     case R_PPC64_GOT_TLSGD16_HA:
     case R_PPC64_GOT_TLSGD16_HI:
@@ -1169,26 +1164,26 @@ static void checkPPC64TLSRelax(InputSectionBase &sec, Relocs<RelTy> rels) {
     case R_PPC64_GOT_TLSLD16_HA:
     case R_PPC64_GOT_TLSLD16_HI:
     case R_PPC64_GOT_TLSLD16_LO:
-      hasGDLD = true;
+      hasGotGdLd = true;
       break;
     }
   }
-  if (hasGDLD) {
-    sec.file->ppc64DisableTLSRelax = true;
+  if (hasGotGdLd) {
     Warn(sec.file->ctx)
         << sec.file
         << ": disable TLS relaxation due to R_PPC64_GOT_TLS* relocations "
            "without "
            "R_PPC64_TLSGD/R_PPC64_TLSLD relocations";
   }
+  return hasGotGdLd;
 }
 
 template <class ELFT, class RelTy>
 void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
   RelocScan rs(ctx, &sec);
   sec.relocations.reserve(rels.size());
-  checkPPC64TLSRelax<RelTy>(sec, rels);
-  bool execOptimize = !ctx.arg.shared && !sec.file->ppc64DisableTLSRelax;
+  bool optimizeTlsGdLd =
+      !missingTlsGdLdMarker<RelTy>(sec, rels) && !ctx.arg.shared;
   for (auto it = rels.begin(); it != rels.end(); ++it) {
     RelType type = it->getType(false);
     uint32_t symIdx = it->getSymbol(false);
@@ -1328,7 +1323,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
     case R_PPC64_GOT_TLSGD16_LO:
     case R_PPC64_GOT_TLSGD_PCREL34: {
       bool isPCRel = type == R_PPC64_GOT_TLSGD_PCREL34;
-      if (execOptimize) {
+      if (optimizeTlsGdLd) {
         if (sym.isPreemptible) {
           ctx.hasTlsIe.store(true, std::memory_order_relaxed);
           sym.setFlags(NEEDS_TLSIE);
@@ -1363,13 +1358,9 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
       // and relaxTlsGdToLe can distinguish it from the TOC case.
       if (it1->getType(false) == R_PPC64_REL24_NOTOC)
         ++offset;
-      if (execOptimize) {
-        if (type == R_PPC64_TLSGD && sym.isPreemptible) {
-          sym.setFlags(NEEDS_TLSIE);
-          sec.addReloc({R_GOT_OFF, type, offset, addend, &sym});
-        } else {
-          sec.addReloc({R_TPREL, type, offset, addend, &sym});
-        }
+      if (optimizeTlsGdLd) {
+        sec.addReloc({sym.isPreemptible ? R_GOT_OFF : R_TPREL, type, offset,
+                      addend, &sym});
         ++it; // skip REL24
       }
       continue;
@@ -1381,7 +1372,7 @@ void PPC64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
     case R_PPC64_GOT_TLSLD16_HI:
     case R_PPC64_GOT_TLSLD16_LO:
     case R_PPC64_GOT_TLSLD_PCREL34:
-      if (execOptimize) {
+      if (optimizeTlsGdLd) {
         sec.addReloc({R_TPREL, type, offset, addend, &sym});
       } else {
         ctx.needsTlsLd.store(true, std::memory_order_relaxed);

diff  --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h
index 4672657cad71a..1823e037ca73a 100644
--- a/lld/ELF/InputFiles.h
+++ b/lld/ELF/InputFiles.h
@@ -158,10 +158,6 @@ class InputFile {
   // [.got, .got + 0xFFFC].
   bool ppc64SmallCodeModelTocRelocs = false;
 
-  // True if the file has TLSGD/TLSLD GOT relocations without R_PPC64_TLSGD or
-  // R_PPC64_TLSLD. Disable TLS relaxation to avoid bad code generation.
-  bool ppc64DisableTLSRelax = false;
-
 public:
   // If not empty, this stores the name of the archive containing this file.
   // We use this string for creating error messages.

diff  --git a/lld/test/ELF/ppc64-tls-missing-gdld.s b/lld/test/ELF/ppc64-tls-missing-gdld.s
index 236f0661ae87b..a7f8d20e08d70 100644
--- a/lld/test/ELF/ppc64-tls-missing-gdld.s
+++ b/lld/test/ELF/ppc64-tls-missing-gdld.s
@@ -73,7 +73,7 @@
 # DIS2-NEXT:    addi 3, 3, -32760
 # DIS2-NEXT:    bl [[#TGA]]
 
-## IE to LE is relaxed even when ppc64DisableTLSRelax is set,
+## IE to LE is relaxed even when GD/LD relaxation is disabled,
 ## since IE does not involve __tls_get_addr.
 # DIS2-LABEL: <InitialExec>:
 # DIS2-NEXT:    nop


        


More information about the llvm-commits mailing list