[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