[lld] [lldb] [llvm] [AArch64] Support TLS variables in debug info (PR #146572)

Shivam Gupta via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 10 08:00:42 PDT 2026


https://github.com/xgupta updated https://github.com/llvm/llvm-project/pull/146572

>From 31de6db3f0d2b28b5c7307aeb4d6b9acb68c252a Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Tue, 1 Jul 2025 19:42:48 +0530
Subject: [PATCH 01/12] [AArch64] Support TLS variables in debug info

This adds an implementation of getDebugThreadLocalSymbol for
AArch64 by using AArch::S_DTPREL.

Fixes #83466
---
 lld/ELF/Arch/AArch64.cpp                      |  8 ++++
 .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp  |  1 +
 .../AArch64/AArch64TargetObjectFile.cpp       |  7 +++-
 .../Target/AArch64/AArch64TargetObjectFile.h  |  3 ++
 .../AArch64/AsmParser/AArch64AsmParser.cpp    |  1 +
 .../MCTargetDesc/AArch64ELFObjectWriter.cpp   |  5 +++
 .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp |  4 ++
 llvm/test/CodeGen/AArch64/tls-dtprel64.ll     | 37 ++++++++++++++++++
 .../test/DebugInfo/AArch64/tls-at-location.ll | 12 ++++--
 llvm/test/MC/AArch64/tls-dtprel64.s           | 38 +++++++++++++++++++
 10 files changed, 112 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/CodeGen/AArch64/tls-dtprel64.ll
 create mode 100644 llvm/test/MC/AArch64/tls-dtprel64.s

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index f85a3f48f21838..26d98aa8312a94 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -236,6 +236,10 @@ void AArch64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
       expr = RE_AARCH64_AUTH;
       break;
 
+    case R_AARCH64_TLS_DTPREL64:
+      expr = R_DTPREL;
+      break;
+
     case R_AARCH64_PATCHINST:
       if (!isAbsolute(sym))
         Err(ctx) << getErrorLoc(ctx, sec.content().data() + offset)
@@ -649,6 +653,10 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     checkInt(ctx, loc, val, 32, rel);
     write32(ctx, loc, val);
     break;
+  case R_AARCH64_TLS_DTPREL64:
+    checkInt(ctx, loc, val, 64, rel);
+    write64(ctx, loc, val);
+    break;
   case R_AARCH64_ADD_ABS_LO12_NC:
   case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
     write32Imm12(loc, val);
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index d5d0dcf1e0d843..de60c0bd413402 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -3118,6 +3118,7 @@ unsigned ObjectFileELF::ApplyRelocations(
       case llvm::ELF::EM_AARCH64:
         switch (reloc_type(rel)) {
         case R_AARCH64_ABS64:
+        case R_AARCH64_TLS_DTPREL64:
           ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
           break;
         case R_AARCH64_ABS32:
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 886f41975e1996..0d2c3e15004eb4 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -30,7 +30,7 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
 
   // AARCH64 ELF ABI does not define static relocation type for TLS offset
   // within a module.  Do not generate AT_location for TLS variables.
-  SupportDebugThreadLocalLocation = false;
+  SupportDebugThreadLocalLocation = true;
 
   // Make sure the implicitly created empty .text section has the
   // SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is
@@ -187,3 +187,8 @@ MCSection *AArch64_ELFTargetObjectFile::SelectSectionForGlobal(
 
   return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
 }
+
+const MCExpr *AArch64_ELFTargetObjectFile::getDebugThreadLocalSymbol(
+    const MCSymbol *Sym) const {
+  return MCSymbolRefExpr::create(Sym, AArch64::S_DTPREL, getContext());
+}
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
index 6b3381452c70bf..78c0c22da8d1b7 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.h
@@ -40,6 +40,9 @@ class AArch64_ELFTargetObjectFile : public TargetLoweringObjectFileELF {
 
   MCSection *SelectSectionForGlobal(const GlobalObject *GO, SectionKind Kind,
                                     const TargetMachine &TM) const override;
+
+  /// Describe a TLS variable address within debug info.
+  const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override;
 };
 
 /// AArch64_MachoTargetObjectFile - This TLOF implementation is used for Darwin.
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 590da8f93873dd..cdfb9ee46634a2 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -4659,6 +4659,7 @@ bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
                   .Case("prel_g1_nc", AArch64::S_PREL_G1_NC)
                   .Case("prel_g0", AArch64::S_PREL_G0)
                   .Case("prel_g0_nc", AArch64::S_PREL_G0_NC)
+                  .Case("dtprel", AArch64::S_DTPREL)
                   .Case("dtprel_g2", AArch64::S_DTPREL_G2)
                   .Case("dtprel_g1", AArch64::S_DTPREL_G1)
                   .Case("dtprel_g1_nc", AArch64::S_DTPREL_G1_NC)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index e33196d4c01448..003c666814cc82 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -249,8 +249,11 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
       }
       if (RefKind == AArch64::S_AUTH || RefKind == AArch64::S_AUTHADDR)
         return ELF::R_AARCH64_AUTH_ABS64;
+      if (RefKind == AArch64::S_DTPREL) {
+        return ELF::R_AARCH64_TLS_DTPREL64;
       if (RefKind == AArch64::S_FUNCINIT)
         return ELF::R_AARCH64_FUNCINIT64;
+      }
       return ELF::R_AARCH64_ABS64;
     }
     case AArch64::fixup_aarch64_add_imm12:
@@ -465,6 +468,8 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
         return R_CLS(MOVW_PREL_G0);
       if (RefKind == AArch64::S_PREL_G0_NC)
         return R_CLS(MOVW_PREL_G0_NC);
+      if (RefKind == AArch64::S_DTPREL)
+        return ELF::R_AARCH64_TLS_DTPREL64;
       if (RefKind == AArch64::S_DTPREL_G2)
         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
       if (RefKind == AArch64::S_DTPREL_G1)
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index ff7831e752b8aa..66c8d52736f5e0 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -38,6 +38,9 @@ const MCAsmInfo::AtSpecifier COFFAtSpecifiers[] = {
 
 const MCAsmInfo::AtSpecifier ELFAtSpecifiers[] = {
     {AArch64::S_GOT, "GOT"},
+    {AArch64::S_GOTPCREL, "GOTPCREL"},
+    {AArch64::S_PLT, "PLT"},
+    {AArch64::S_FUNCINIT, "FUNCINIT"},
 };
 
 const MCAsmInfo::AtSpecifier MachOAtSpecifiers[] = {
@@ -73,6 +76,7 @@ StringRef AArch64::getSpecifierName(AArch64::Specifier S) {
   case AArch64::S_PREL_G1_NC:          return ":prel_g1_nc:";
   case AArch64::S_PREL_G0:             return ":prel_g0:";
   case AArch64::S_PREL_G0_NC:          return ":prel_g0_nc:";
+  case AArch64::S_DTPREL:              return ":dtprel:";
   case AArch64::S_DTPREL_G2:           return ":dtprel_g2:";
   case AArch64::S_DTPREL_G1:           return ":dtprel_g1:";
   case AArch64::S_DTPREL_G1_NC:        return ":dtprel_g1_nc:";
diff --git a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
new file mode 100644
index 00000000000000..c4819803549052
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
@@ -0,0 +1,37 @@
+; RUN: llc -O0 -mtriple=aarch64-linux-gnu -filetype=obj < %s \
+; RUN: | llvm-objdump -r - | FileCheck %s
+
+; CHECK: R_AARCH64_TLS_DTPREL64
+
+ at var = thread_local global i32 0, align 4, !dbg !0
+
+; Function Attrs: noinline nounwind optnone
+define i32 @foo() #0 !dbg !11 {
+entry:
+  %0 = load i32, ptr @var, align 4, !dbg !14
+  ret i32 %0, !dbg !15
+}
+
+attributes #0 = { noinline nounwind optnone }
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!7, !8, !9}
+!llvm.ident = !{!10}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "var", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 7.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
+!3 = !DIFile(filename: "tls-at-location.c", directory: "/home/lliu0/llvm/tls-at-location/DebugInfo/AArch64")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = !{i32 2, !"Dwarf Version", i32 4}
+!8 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = !{i32 1, !"wchar_size", i32 4}
+!10 = !{!"clang version 7.0.0"}
+!11 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, isOptimized: false, unit: !2)
+!12 = !DISubroutineType(types: !13)
+!13 = !{!6}
+!14 = !DILocation(line: 4, column: 10, scope: !11)
+!15 = !DILocation(line: 4, column: 3, scope: !11)
+
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location.ll b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
index 20a0afb7897716..d619962ccbf69a 100644
--- a/llvm/test/DebugInfo/AArch64/tls-at-location.ll
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
@@ -1,8 +1,14 @@
-; RUN: llc -filetype=obj -mtriple=aarch64--linux-gnu -o - %s | llvm-dwarfdump -v - | FileCheck %s
-;
+; RUN: llc -O0 -mtriple=aarch64-non-linux-gnu -filetype=obj < %s \
+; RUN:  | llvm-dwarfdump - | FileCheck %s
+
 ; CHECK: .debug_info contents:
 ; CHECK: DW_TAG_variable
-; CHECK-NOT: DW_AT_location
+; CHECK:   DW_AT_name      ("var")
+; CHECK-NEXT:   DW_AT_type      (0x00000040 "int")
+; CHECK-NEXT:   DW_AT_external  (true)
+; CHECK-NEXT:   DW_AT_decl_file ("{{.*}}tls-at-location.c")
+; CHECK-NEXT:   DW_AT_decl_line (1)
+; CHECK-NEXT:   DW_AT_location  (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
 
 @var = thread_local global i32 0, align 4, !dbg !0
 
diff --git a/llvm/test/MC/AArch64/tls-dtprel64.s b/llvm/test/MC/AArch64/tls-dtprel64.s
new file mode 100644
index 00000000000000..7cb47f9543f685
--- /dev/null
+++ b/llvm/test/MC/AArch64/tls-dtprel64.s
@@ -0,0 +1,38 @@
+# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s | llvm-readobj -r - | FileCheck %s
+  
+# CHECK: Relocations [
+# CHECK:   Section {{.*}} .rela.debug_info {
+# CHECK:     0x{{[0-9A-F]+}} R_AARCH64_TLS_DTPREL64 var {{.*}}
+# CHECK:   }
+
+.section .tdata,"awT", at progbits
+.globl var
+var:
+  .word 0
+
+.section .debug_abbrev,"", at progbits
+.byte 1                  // Abbreviation Code
+.byte 17                 // DW_TAG_compile_unit
+.byte 1                  // DW_CHILDREN_yes
+.byte 0                  // EOM(1)
+.byte 0                  // EOM(2)
+
+.byte 2                  // Abbreviation Code
+.byte 52                 // DW_TAG_variable
+.byte 0                  // DW_CHILDREN_no
+.byte 2;                 // DW_AT_location
+.byte 24                 // DW_FORM_exprloc
+.byte 0                  // EOM(1)
+.byte 0                  // EOM(2)
+
+.section        .debug_info,"", at progbits
+.Lcu_begin0:
+  .word .Lcu_end - .Lcu_body // Length of Unit
+.Lcu_body:
+  .hword 4               // DWARF version number
+  .word   .debug_abbrev  // Offset Into Abbrev. Section
+  .byte   8              // Address Size (in bytes)
+  .byte   1              // Abbrev [1] DW_TAG_compile_unit
+  .byte   2              // Abbrev [2] DW_TAG_variable
+  .xword  var at DTPREL
+.Lcu_end:

>From 4950d703933fbc46a84ca85b9a6313ca69d0430a Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sun, 18 Jan 2026 21:14:48 +0530
Subject: [PATCH 02/12] Address reviewer's comments

---
 llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp           | 2 --
 .../Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp    | 3 +--
 llvm/test/CodeGen/AArch64/tls-dtprel64.ll                     | 4 ++--
 llvm/test/DebugInfo/AArch64/tls-at-location.ll                | 2 +-
 4 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 0d2c3e15004eb4..573498e6152b6a 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -28,8 +28,6 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
   PLTPCRelativeSpecifier = AArch64::S_PLT;
   SupportIndirectSymViaGOTPCRel = true;
 
-  // AARCH64 ELF ABI does not define static relocation type for TLS offset
-  // within a module.  Do not generate AT_location for TLS variables.
   SupportDebugThreadLocalLocation = true;
 
   // Make sure the implicitly created empty .text section has the
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
index 003c666814cc82..4ecf2ef268f919 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -249,11 +249,10 @@ unsigned AArch64ELFObjectWriter::getRelocType(const MCFixup &Fixup,
       }
       if (RefKind == AArch64::S_AUTH || RefKind == AArch64::S_AUTHADDR)
         return ELF::R_AARCH64_AUTH_ABS64;
-      if (RefKind == AArch64::S_DTPREL) {
+      if (RefKind == AArch64::S_DTPREL)
         return ELF::R_AARCH64_TLS_DTPREL64;
       if (RefKind == AArch64::S_FUNCINIT)
         return ELF::R_AARCH64_FUNCINIT64;
-      }
       return ELF::R_AARCH64_ABS64;
     }
     case AArch64::fixup_aarch64_add_imm12:
diff --git a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
index c4819803549052..b025c8c9331fd8 100644
--- a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
+++ b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
@@ -1,7 +1,7 @@
 ; RUN: llc -O0 -mtriple=aarch64-linux-gnu -filetype=obj < %s \
-; RUN: | llvm-objdump -r - | FileCheck %s
+; RUN:     | llvm-objdump -r - | FileCheck %s
 
-; CHECK: R_AARCH64_TLS_DTPREL64
+; CHECK: R_AARCH64_TLS_DTPREL64   var
 
 @var = thread_local global i32 0, align 4, !dbg !0
 
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location.ll b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
index d619962ccbf69a..13bdad20032bea 100644
--- a/llvm/test/DebugInfo/AArch64/tls-at-location.ll
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
@@ -1,5 +1,5 @@
 ; RUN: llc -O0 -mtriple=aarch64-non-linux-gnu -filetype=obj < %s \
-; RUN:  | llvm-dwarfdump - | FileCheck %s
+; RUN:     | llvm-dwarfdump - | FileCheck %s
 
 ; CHECK: .debug_info contents:
 ; CHECK: DW_TAG_variable

>From 38354f86f304fa29c87c13f00db3a90caf1a1268 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Wed, 25 Feb 2026 12:20:02 +0000
Subject: [PATCH 03/12] Update new ABI syntax for dtprel

---
 .../AArch64/AsmParser/AArch64AsmParser.cpp    | 41 ++++++++++++++++++-
 llvm/test/MC/AArch64/tls-dtprel64.s           | 17 ++++----
 2 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index cdfb9ee46634a2..fe34ca17b80ee0 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -185,6 +185,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E);
   bool parseDataExpr(const MCExpr *&Res) override;
   bool parseAuthExpr(const MCExpr *&Res, SMLoc &EndLoc);
+  bool parsePercentRelocExpr(const MCExpr *&Res, SMLoc &EndLoc);
 
   bool parseDirectiveArch(SMLoc L);
   bool parseDirectiveArchExtension(SMLoc L);
@@ -8476,13 +8477,28 @@ bool AArch64AsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
 }
 
 bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
+  MCAsmParser &Parser = getParser();
+  SMLoc StartLoc = getLoc();
   SMLoc EndLoc;
   if (parseOptionalToken(AsmToken::Percent))
     return parseExprWithSpecifier(Res, EndLoc);
 
+  if (getLexer().is(AsmToken::Percent)) {
+    Lex(); // eat %
+
+    if (getLexer().getKind() != AsmToken::Identifier)
+      return Error(StartLoc, "expected identifier after '%'");
+
+    StringRef Identifier = getLexer().getTok().getIdentifier();
+    Lex(); // eat identifier
+
+    if (Identifier == "dtprel")
+      return parsePercentRelocExpr(Res, EndLoc);
+    return false;
+  }
+
   if (getParser().parseExpression(Res))
     return true;
-  MCAsmParser &Parser = getParser();
   if (!parseOptionalToken(AsmToken::At))
     return false;
   if (getLexer().getKind() != AsmToken::Identifier)
@@ -8523,6 +8539,29 @@ bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
   return false;
 }
 
+bool AArch64AsmParser::parsePercentRelocExpr(const MCExpr *&Res,
+                                             SMLoc &EndLoc) {
+  SMLoc StartLoc = getLoc();
+  if (parseToken(AsmToken::LParen, "expected '('"))
+    return true;
+
+  const MCExpr *Inner;
+  if (getParser().parseExpression(Inner))
+    return true;
+
+  EndLoc = getParser().getTok().getEndLoc();
+
+  if (parseToken(AsmToken::RParen, "expected ')'"))
+    return true;
+
+  auto *SymRef = dyn_cast<MCSymbolRefExpr>(Inner);
+  if (!SymRef)
+    return Error(StartLoc, "expected symbol inside %operator()");
+
+  Res = MCSpecifierExpr::create(Inner, AArch64::S_DTPREL, getContext());
+  return false;
+}
+
 ///  parseAuthExpr
 ///  ::= _sym at AUTH(ib,123[,addr])
 ///  ::= (_sym + 5)@AUTH(ib,123[,addr])
diff --git a/llvm/test/MC/AArch64/tls-dtprel64.s b/llvm/test/MC/AArch64/tls-dtprel64.s
index 7cb47f9543f685..34e9588c48f2de 100644
--- a/llvm/test/MC/AArch64/tls-dtprel64.s
+++ b/llvm/test/MC/AArch64/tls-dtprel64.s
@@ -1,9 +1,12 @@
-# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s | llvm-readobj -r - | FileCheck %s
-  
-# CHECK: Relocations [
-# CHECK:   Section {{.*}} .rela.debug_info {
-# CHECK:     0x{{[0-9A-F]+}} R_AARCH64_TLS_DTPREL64 var {{.*}}
-# CHECK:   }
+// RUN: llvm-mc -triple=aarch64-none-linux-gnu -show-encoding < %s | FileCheck %s
+// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s | llvm-readobj -r - | FileCheck --check-prefix=CHECK-ELF %s
+
+# CHECK: .xword %dtprel(var)
+
+# CHECK-ELF: Relocations [
+# CHECK-ELF:   Section {{.*}} .rela.debug_info {
+# CHECK-ELF:     0x{{[0-9A-F]+}} R_AARCH64_TLS_DTPREL64 var {{.*}}
+# CHECK-ELF:   }
 
 .section .tdata,"awT", at progbits
 .globl var
@@ -34,5 +37,5 @@ var:
   .byte   8              // Address Size (in bytes)
   .byte   1              // Abbrev [1] DW_TAG_compile_unit
   .byte   2              // Abbrev [2] DW_TAG_variable
-  .xword  var at DTPREL
+  .xword  %dtprel(var)
 .Lcu_end:

>From d9b011124409012a3f784bd5658b31804cceedcc Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 28 Feb 2026 21:07:12 +0000
Subject: [PATCH 04/12] Address review comment

---
 lld/ELF/Arch/AArch64.cpp                      |  8 ----
 .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp  |  1 -
 .../AArch64/AArch64TargetObjectFile.cpp       |  2 +-
 .../AArch64/AsmParser/AArch64AsmParser.cpp    | 42 +------------------
 .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp |  3 +-
 5 files changed, 4 insertions(+), 52 deletions(-)

diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 26d98aa8312a94..f85a3f48f21838 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -236,10 +236,6 @@ void AArch64::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
       expr = RE_AARCH64_AUTH;
       break;
 
-    case R_AARCH64_TLS_DTPREL64:
-      expr = R_DTPREL;
-      break;
-
     case R_AARCH64_PATCHINST:
       if (!isAbsolute(sym))
         Err(ctx) << getErrorLoc(ctx, sec.content().data() + offset)
@@ -653,10 +649,6 @@ void AArch64::relocate(uint8_t *loc, const Relocation &rel,
     checkInt(ctx, loc, val, 32, rel);
     write32(ctx, loc, val);
     break;
-  case R_AARCH64_TLS_DTPREL64:
-    checkInt(ctx, loc, val, 64, rel);
-    write64(ctx, loc, val);
-    break;
   case R_AARCH64_ADD_ABS_LO12_NC:
   case R_AARCH64_AUTH_GOT_ADD_LO12_NC:
     write32Imm12(loc, val);
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index de60c0bd413402..d5d0dcf1e0d843 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -3118,7 +3118,6 @@ unsigned ObjectFileELF::ApplyRelocations(
       case llvm::ELF::EM_AARCH64:
         switch (reloc_type(rel)) {
         case R_AARCH64_ABS64:
-        case R_AARCH64_TLS_DTPREL64:
           ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
           break;
         case R_AARCH64_ABS32:
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 573498e6152b6a..b855cd9b992d01 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -188,5 +188,5 @@ MCSection *AArch64_ELFTargetObjectFile::SelectSectionForGlobal(
 
 const MCExpr *AArch64_ELFTargetObjectFile::getDebugThreadLocalSymbol(
     const MCSymbol *Sym) const {
-  return MCSymbolRefExpr::create(Sym, AArch64::S_DTPREL, getContext());
+  return MCSpecifierExpr::create(Sym, AArch64::S_DTPREL, getContext());
 }
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index fe34ca17b80ee0..017ed2a5d0868b 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -185,7 +185,6 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E);
   bool parseDataExpr(const MCExpr *&Res) override;
   bool parseAuthExpr(const MCExpr *&Res, SMLoc &EndLoc);
-  bool parsePercentRelocExpr(const MCExpr *&Res, SMLoc &EndLoc);
 
   bool parseDirectiveArch(SMLoc L);
   bool parseDirectiveArchExtension(SMLoc L);
@@ -8463,7 +8462,6 @@ bool AArch64AsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
   auto Spec = AArch64::parsePercentSpecifierName(Identifier);
   if (!Spec)
     return TokError("invalid relocation specifier");
-
   getParser().Lex(); // Eat the identifier
   if (parseToken(AsmToken::LParen, "expected '('"))
     return true;
@@ -8477,28 +8475,13 @@ bool AArch64AsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
 }
 
 bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
-  MCAsmParser &Parser = getParser();
-  SMLoc StartLoc = getLoc();
   SMLoc EndLoc;
   if (parseOptionalToken(AsmToken::Percent))
     return parseExprWithSpecifier(Res, EndLoc);
 
-  if (getLexer().is(AsmToken::Percent)) {
-    Lex(); // eat %
-
-    if (getLexer().getKind() != AsmToken::Identifier)
-      return Error(StartLoc, "expected identifier after '%'");
-
-    StringRef Identifier = getLexer().getTok().getIdentifier();
-    Lex(); // eat identifier
-
-    if (Identifier == "dtprel")
-      return parsePercentRelocExpr(Res, EndLoc);
-    return false;
-  }
-
   if (getParser().parseExpression(Res))
     return true;
+  MCAsmParser &Parser = getParser();
   if (!parseOptionalToken(AsmToken::At))
     return false;
   if (getLexer().getKind() != AsmToken::Identifier)
@@ -8539,29 +8522,6 @@ bool AArch64AsmParser::parseDataExpr(const MCExpr *&Res) {
   return false;
 }
 
-bool AArch64AsmParser::parsePercentRelocExpr(const MCExpr *&Res,
-                                             SMLoc &EndLoc) {
-  SMLoc StartLoc = getLoc();
-  if (parseToken(AsmToken::LParen, "expected '('"))
-    return true;
-
-  const MCExpr *Inner;
-  if (getParser().parseExpression(Inner))
-    return true;
-
-  EndLoc = getParser().getTok().getEndLoc();
-
-  if (parseToken(AsmToken::RParen, "expected ')'"))
-    return true;
-
-  auto *SymRef = dyn_cast<MCSymbolRefExpr>(Inner);
-  if (!SymRef)
-    return Error(StartLoc, "expected symbol inside %operator()");
-
-  Res = MCSpecifierExpr::create(Inner, AArch64::S_DTPREL, getContext());
-  return false;
-}
-
 ///  parseAuthExpr
 ///  ::= _sym at AUTH(ib,123[,addr])
 ///  ::= (_sym + 5)@AUTH(ib,123[,addr])
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index 66c8d52736f5e0..fdbfe6218264d3 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -76,7 +76,6 @@ StringRef AArch64::getSpecifierName(AArch64::Specifier S) {
   case AArch64::S_PREL_G1_NC:          return ":prel_g1_nc:";
   case AArch64::S_PREL_G0:             return ":prel_g0:";
   case AArch64::S_PREL_G0_NC:          return ":prel_g0_nc:";
-  case AArch64::S_DTPREL:              return ":dtprel:";
   case AArch64::S_DTPREL_G2:           return ":dtprel_g2:";
   case AArch64::S_DTPREL_G1:           return ":dtprel_g1:";
   case AArch64::S_DTPREL_G1_NC:        return ":dtprel_g1_nc:";
@@ -118,6 +117,7 @@ StringRef AArch64::getSpecifierName(AArch64::Specifier S) {
 
   case AArch64::S_GOTPCREL:            return "%gotpcrel";
   case AArch64::S_PLT:                 return "%pltpcrel";
+  case AArch64::S_DTPREL:              return "%dtprel";
   case AArch64::S_FUNCINIT:            return "%funcinit";
   default:
     llvm_unreachable("Invalid relocation specifier");
@@ -129,6 +129,7 @@ AArch64::Specifier AArch64::parsePercentSpecifierName(StringRef name) {
   return StringSwitch<AArch64::Specifier>(name)
       .Case("pltpcrel", AArch64::S_PLT)
       .Case("gotpcrel", AArch64::S_GOTPCREL)
+      .Case("dtprel", AArch64::S_DTPREL)
       .Case("funcinit", AArch64::S_FUNCINIT)
       .Default(0);
 }

>From 560348964b084cb49bad6b029b245f2a56ea7edf Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 28 Feb 2026 22:37:59 +0000
Subject: [PATCH 05/12] added back a removed blank line

---
 llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 017ed2a5d0868b..cdfb9ee46634a2 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -8462,6 +8462,7 @@ bool AArch64AsmParser::parseExprWithSpecifier(const MCExpr *&Res, SMLoc &E) {
   auto Spec = AArch64::parsePercentSpecifierName(Identifier);
   if (!Spec)
     return TokError("invalid relocation specifier");
+
   getParser().Lex(); // Eat the identifier
   if (parseToken(AsmToken::LParen, "expected '('"))
     return true;

>From 84ed476938ae1a7053b193723c023237c92292b2 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 7 Mar 2026 12:12:38 +0000
Subject: [PATCH 06/12] Do not emit DW_AT_location for preemptible global TLS
 variables

---
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   | 15 ++++++--
 llvm/test/CodeGen/AArch64/tls-dtprel64.ll     |  2 +-
 .../test/DebugInfo/AArch64/tls-at-location.ll |  4 +-
 .../DebugInfo/AArch64/tls-at-location1.ll     | 38 +++++++++++++++++++
 4 files changed, 53 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/DebugInfo/AArch64/tls-at-location1.ll

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index eb55b47dfde2bb..c9a5e1b4a2e6b8 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -274,9 +274,18 @@ void DwarfCompileUnit::addLocationAttribute(
     if (!Global && (!Expr || !Expr->isConstant()))
       continue;
 
-    if (Global && Global->isThreadLocal() &&
-        !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
-      continue;
+    if (Global && Global->isThreadLocal()) {
+      // Do not emit TLS location for interposable TLS variables
+      // (e.g. TLS in shared libraries). The TLS offset cannot be
+      // represented safely in DWARF. In that case let Debugger use
+      // Runtime TLS lookup via DTV (Dynmic thread vector).
+      if (Asm->TM.getTargetTriple().isAArch64() &&
+          Asm->TM.getTargetTriple().isOSBinFormatELF() && !Global->isDSOLocal())
+        continue;
+
+      if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())
+        continue;
+    }
 
     if (!Loc) {
       addToAccelTable = true;
diff --git a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
index b025c8c9331fd8..a3898e88be6ffb 100644
--- a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
+++ b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
@@ -3,7 +3,7 @@
 
 ; CHECK: R_AARCH64_TLS_DTPREL64   var
 
- at var = thread_local global i32 0, align 4, !dbg !0
+ at var = internal thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: noinline nounwind optnone
 define i32 @foo() #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location.ll b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
index 13bdad20032bea..69911eaa3a17b3 100644
--- a/llvm/test/DebugInfo/AArch64/tls-at-location.ll
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
@@ -4,13 +4,13 @@
 ; CHECK: .debug_info contents:
 ; CHECK: DW_TAG_variable
 ; CHECK:   DW_AT_name      ("var")
-; CHECK-NEXT:   DW_AT_type      (0x00000040 "int")
+; CHECK-NEXT:   DW_AT_type      (0x{{.*}} "int")
 ; CHECK-NEXT:   DW_AT_external  (true)
 ; CHECK-NEXT:   DW_AT_decl_file ("{{.*}}tls-at-location.c")
 ; CHECK-NEXT:   DW_AT_decl_line (1)
 ; CHECK-NEXT:   DW_AT_location  (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
 
- at var = thread_local global i32 0, align 4, !dbg !0
+ at var = internal thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: noinline nounwind optnone
 define i32 @foo() #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location1.ll b/llvm/test/DebugInfo/AArch64/tls-at-location1.ll
new file mode 100644
index 00000000000000..6e70c36e6e9bf8
--- /dev/null
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location1.ll
@@ -0,0 +1,38 @@
+; RUN: llc -O0 -mtriple=aarch64-linux-gnu -filetype=obj < %s \
+; RUN:     | llvm-dwarfdump - | FileCheck %s
+
+; CHECK: .debug_info contents:
+; CHECK: DW_TAG_variable
+; CHECK:   DW_AT_name      ("tls_var")
+; CHECK-NEXT:   DW_AT_type      (0x{{.*}} "int")
+; CHECK-NEXT:   DW_AT_external  (true)
+; CHECK-NEXT:   DW_AT_decl_file ("{{.*}}tls-location.c")
+; CHECK-NEXT:   DW_AT_decl_line (1)
+; CHECK-NEXT:   DW_AT_location  (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
+
+ at tls_var = hidden thread_local global i32 0, align 4, !dbg !0
+
+define i32 @foo() !dbg !10 {
+entry:
+  %0 = load i32, ptr @tls_var, align 4, !dbg !13
+  ret i32 %0, !dbg !14
+}
+
+!llvm.dbg.cu = !{!1}
+!llvm.module.flags = !{!6, !7}
+!llvm.ident = !{!8}
+
+!0 = !DIGlobalVariableExpression(var: !2, expr: !DIExpression())
+!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4)
+!2 = distinct !DIGlobalVariable(name: "tls_var", scope: !1, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true)
+!3 = !DIFile(filename: "tls-location.c", directory: "/tmp")
+!4 = !{!0}
+!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!6 = !{i32 2, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+!8 = !{!"clang"}
+!10 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 3, type: !11, unit: !1)
+!11 = !DISubroutineType(types: !12)
+!12 = !{!5}
+!13 = !DILocation(line: 4, column: 10, scope: !10)
+!14 = !DILocation(line: 4, column: 3, scope: !10)

>From 9ffcfa643112411b5cac4ae2aeadc3d5ba83c642 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 7 Mar 2026 12:16:25 +0000
Subject: [PATCH 07/12] Minor wording change

---
 llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index c9a5e1b4a2e6b8..57013431a23259 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -275,7 +275,7 @@ void DwarfCompileUnit::addLocationAttribute(
       continue;
 
     if (Global && Global->isThreadLocal()) {
-      // Do not emit TLS location for interposable TLS variables
+      // Do not emit TLS location for preemptible TLS variables
       // (e.g. TLS in shared libraries). The TLS offset cannot be
       // represented safely in DWARF. In that case let Debugger use
       // Runtime TLS lookup via DTV (Dynmic thread vector).

>From 78d51360b8c2e645ca2cd33ddc8afd7e5660fcfb Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 7 Mar 2026 12:44:48 +0000
Subject: [PATCH 08/12] Remove elf check

---
 llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 57013431a23259..53bf83f4734cca 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -279,8 +279,7 @@ void DwarfCompileUnit::addLocationAttribute(
       // (e.g. TLS in shared libraries). The TLS offset cannot be
       // represented safely in DWARF. In that case let Debugger use
       // Runtime TLS lookup via DTV (Dynmic thread vector).
-      if (Asm->TM.getTargetTriple().isAArch64() &&
-          Asm->TM.getTargetTriple().isOSBinFormatELF() && !Global->isDSOLocal())
+      if (Asm->TM.getTargetTriple().isAArch64() && !Global->isDSOLocal())
         continue;
 
       if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())

>From 9c438fa995e43a6a0356c447944f1d4c0ab3af23 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Mon, 9 Mar 2026 18:38:30 +0000
Subject: [PATCH 09/12] Address review comments

---
 llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp          | 2 +-
 llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp       | 2 --
 llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp | 3 ---
 llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll     | 2 +-
 llvm/test/DebugInfo/X86/debugger-tune.ll                  | 2 +-
 llvm/test/DebugInfo/X86/gnu-names.ll                      | 2 +-
 llvm/test/DebugInfo/X86/tls.ll                            | 2 +-
 7 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 53bf83f4734cca..ffe6f2e6973292 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -279,7 +279,7 @@ void DwarfCompileUnit::addLocationAttribute(
       // (e.g. TLS in shared libraries). The TLS offset cannot be
       // represented safely in DWARF. In that case let Debugger use
       // Runtime TLS lookup via DTV (Dynmic thread vector).
-      if (Asm->TM.getTargetTriple().isAArch64() && !Global->isDSOLocal())
+      if (!Global->isDSOLocal())
         continue;
 
       if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index b855cd9b992d01..d70f8a46f897d7 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -28,8 +28,6 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
   PLTPCRelativeSpecifier = AArch64::S_PLT;
   SupportIndirectSymViaGOTPCRel = true;
 
-  SupportDebugThreadLocalLocation = true;
-
   // Make sure the implicitly created empty .text section has the
   // SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is
   // present.
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
index fdbfe6218264d3..1a5a7da95347e9 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -38,9 +38,6 @@ const MCAsmInfo::AtSpecifier COFFAtSpecifiers[] = {
 
 const MCAsmInfo::AtSpecifier ELFAtSpecifiers[] = {
     {AArch64::S_GOT, "GOT"},
-    {AArch64::S_GOTPCREL, "GOTPCREL"},
-    {AArch64::S_PLT, "PLT"},
-    {AArch64::S_FUNCINIT, "FUNCINIT"},
 };
 
 const MCAsmInfo::AtSpecifier MachOAtSpecifiers[] = {
diff --git a/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll b/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
index 35752a934d0e67..59ed8772118220 100644
--- a/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
+++ b/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
@@ -1,4 +1,4 @@
- at var = thread_local global i32 0, align 4, !dbg !0
+ at var = internal thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/debugger-tune.ll b/llvm/test/DebugInfo/X86/debugger-tune.ll
index 39359359d64dca..41429b2f650ddb 100644
--- a/llvm/test/DebugInfo/X86/debugger-tune.ll
+++ b/llvm/test/DebugInfo/X86/debugger-tune.ll
@@ -24,7 +24,7 @@
 ; SCE-NOT: DW_AT_APPLE_optimized
 ; SCE-NOT: DW_OP_GNU_push_tls_address
 
- at var = thread_local global i32 0, align 4, !dbg !0
+ at var = internal thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/gnu-names.ll b/llvm/test/DebugInfo/X86/gnu-names.ll
index fe535e662dc048..de8b147a1087c6 100644
--- a/llvm/test/DebugInfo/X86/gnu-names.ll
+++ b/llvm/test/DebugInfo/X86/gnu-names.ll
@@ -41,7 +41,7 @@
 ; NONE-NOT: debug_names
 ; NONE: debug_gnu_pub
 
- at var = thread_local global i32 0, align 4, !dbg !0
+ at var = internal thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/tls.ll b/llvm/test/DebugInfo/X86/tls.ll
index da569fdc5e5a4b..d8ef5e80dc15e8 100644
--- a/llvm/test/DebugInfo/X86/tls.ll
+++ b/llvm/test/DebugInfo/X86/tls.ll
@@ -102,7 +102,7 @@
 
 source_filename = "test/DebugInfo/X86/tls.ll"
 
- at tls = thread_local global i32 0, align 4, !dbg !0
+ at tls = internal thread_local global i32 0, align 4, !dbg !0
 @glbl = global i32 0, align 4, !dbg !4
 
 ; Function Attrs: nounwind uwtable

>From fa5cdf16aaee10c0eed5bfe529044d7c593e4d54 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Mon, 9 Mar 2026 21:40:20 +0000
Subject: [PATCH 10/12] Updated test cases and add opt in option

---
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   |  8 ++++
 llvm/test/CodeGen/AArch64/tls-dtprel64.ll     |  4 +-
 .../test/DebugInfo/AArch64/tls-at-location.ll |  4 +-
 .../DebugInfo/AArch64/tls-at-location1.ll     | 38 -------------------
 llvm/test/DebugInfo/ARM/tls.ll                |  4 +-
 .../Inputs/name-table-kind-apple-5.ll         |  2 +-
 llvm/test/DebugInfo/Mips/dwarfdump-tls.ll     | 10 ++---
 llvm/test/DebugInfo/Mips/tls.ll               |  6 +--
 llvm/test/DebugInfo/PowerPC/tls-fission.ll    |  4 +-
 llvm/test/DebugInfo/PowerPC/tls.ll            |  4 +-
 .../DebugInfo/WebAssembly/tls_pic_globals.ll  | 20 +++++-----
 llvm/test/DebugInfo/X86/debugger-tune.ll      | 18 ++++-----
 llvm/test/DebugInfo/X86/gnu-names.ll          |  6 +--
 llvm/test/DebugInfo/X86/tls.ll                | 14 +++----
 llvm/test/DebugInfo/accel-tables-apple.ll     |  4 +-
 .../DWARF/crash-thread-local-storage.test     |  2 +-
 16 files changed, 59 insertions(+), 89 deletions(-)
 delete mode 100644 llvm/test/DebugInfo/AArch64/tls-at-location1.ll

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index ffe6f2e6973292..41f7e942a67398 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -56,6 +56,11 @@ static cl::opt<bool> EmitFuncLineTableOffsetsOption(
              "sequence after each function's line data."),
     cl::init(false));
 
+static cl::opt<bool> EnableDebugTLSLocation(
+    "enable-debug-tls-location", cl::Hidden,
+    cl::desc("Enable emitting TLS DWARF location with DTPREL relocation"),
+    cl::init(false));
+
 static bool AddLinkageNamesToDeclCallOriginsForTuning(const DwarfDebug *DD) {
   bool EnabledByDefault = DD->tuneForSCE();
   if (EnabledByDefault)
@@ -282,6 +287,9 @@ void DwarfCompileUnit::addLocationAttribute(
       if (!Global->isDSOLocal())
         continue;
 
+      if (!EnableDebugTLSLocation)
+        continue;
+
       if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())
         continue;
     }
diff --git a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
index a3898e88be6ffb..46c8a86a53f4bd 100644
--- a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
+++ b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
@@ -1,9 +1,9 @@
-; RUN: llc -O0 -mtriple=aarch64-linux-gnu -filetype=obj < %s \
+; RUN: llc -O0 -mtriple=aarch64-linux-gnu -enable-debug-tls-location -filetype=obj < %s \
 ; RUN:     | llvm-objdump -r - | FileCheck %s
 
 ; CHECK: R_AARCH64_TLS_DTPREL64   var
 
- at var = internal thread_local global i32 0, align 4, !dbg !0
+ at var = dso_local thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: noinline nounwind optnone
 define i32 @foo() #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location.ll b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
index 69911eaa3a17b3..335ee5dc603796 100644
--- a/llvm/test/DebugInfo/AArch64/tls-at-location.ll
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -mtriple=aarch64-non-linux-gnu -filetype=obj < %s \
+; RUN: llc -O0 -mtriple=aarch64-non-linux-gnu -enable-debug-tls-location -filetype=obj < %s \
 ; RUN:     | llvm-dwarfdump - | FileCheck %s
 
 ; CHECK: .debug_info contents:
@@ -10,7 +10,7 @@
 ; CHECK-NEXT:   DW_AT_decl_line (1)
 ; CHECK-NEXT:   DW_AT_location  (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
 
- at var = internal thread_local global i32 0, align 4, !dbg !0
+ at var = dso_local thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: noinline nounwind optnone
 define i32 @foo() #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/AArch64/tls-at-location1.ll b/llvm/test/DebugInfo/AArch64/tls-at-location1.ll
deleted file mode 100644
index 6e70c36e6e9bf8..00000000000000
--- a/llvm/test/DebugInfo/AArch64/tls-at-location1.ll
+++ /dev/null
@@ -1,38 +0,0 @@
-; RUN: llc -O0 -mtriple=aarch64-linux-gnu -filetype=obj < %s \
-; RUN:     | llvm-dwarfdump - | FileCheck %s
-
-; CHECK: .debug_info contents:
-; CHECK: DW_TAG_variable
-; CHECK:   DW_AT_name      ("tls_var")
-; CHECK-NEXT:   DW_AT_type      (0x{{.*}} "int")
-; CHECK-NEXT:   DW_AT_external  (true)
-; CHECK-NEXT:   DW_AT_decl_file ("{{.*}}tls-location.c")
-; CHECK-NEXT:   DW_AT_decl_line (1)
-; CHECK-NEXT:   DW_AT_location  (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address)
-
- at tls_var = hidden thread_local global i32 0, align 4, !dbg !0
-
-define i32 @foo() !dbg !10 {
-entry:
-  %0 = load i32, ptr @tls_var, align 4, !dbg !13
-  ret i32 %0, !dbg !14
-}
-
-!llvm.dbg.cu = !{!1}
-!llvm.module.flags = !{!6, !7}
-!llvm.ident = !{!8}
-
-!0 = !DIGlobalVariableExpression(var: !2, expr: !DIExpression())
-!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4)
-!2 = distinct !DIGlobalVariable(name: "tls_var", scope: !1, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true)
-!3 = !DIFile(filename: "tls-location.c", directory: "/tmp")
-!4 = !{!0}
-!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!6 = !{i32 2, !"Dwarf Version", i32 4}
-!7 = !{i32 2, !"Debug Info Version", i32 3}
-!8 = !{!"clang"}
-!10 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 3, type: !11, unit: !1)
-!11 = !DISubroutineType(types: !12)
-!12 = !{!5}
-!13 = !DILocation(line: 4, column: 10, scope: !10)
-!14 = !DILocation(line: 4, column: 3, scope: !10)
diff --git a/llvm/test/DebugInfo/ARM/tls.ll b/llvm/test/DebugInfo/ARM/tls.ll
index 53cb08d0f299cf..936ed9bc6b1ccf 100644
--- a/llvm/test/DebugInfo/ARM/tls.ll
+++ b/llvm/test/DebugInfo/ARM/tls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi < %s \
+; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi -enable-debug-tls-location < %s \
 ; RUN:     | FileCheck %s
 ; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi -emulated-tls < %s \
 ; RUN:     | FileCheck %s --check-prefix=EMU
@@ -8,7 +8,7 @@
 
 source_filename = "test/DebugInfo/ARM/tls.ll"
 
- at x = thread_local global i32 0, align 4, !dbg !0
+ at x = dso_local thread_local global i32 0, align 4, !dbg !0
 
 !llvm.dbg.cu = !{!4}
 !llvm.module.flags = !{!7, !8}
diff --git a/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll b/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
index 59ed8772118220..1a8c30f459ff6f 100644
--- a/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
+++ b/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
@@ -1,4 +1,4 @@
- at var = internal thread_local global i32 0, align 4, !dbg !0
+ at var = dso_local thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll b/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll
index acf7067e8c52b1..ebd839e5f4c4cb 100644
--- a/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll
+++ b/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll
@@ -1,16 +1,16 @@
-; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -filetype=obj \
+; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -enable-debug-tls-location -filetype=obj \
 ; RUN:     -split-dwarf-file=foo.dwo -o=%t-32.o < %s
 ; RUN: llvm-dwarfdump %t-32.o 2>&1 | FileCheck %s
-; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -filetype=obj \
+; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -enable-debug-tls-location -filetype=obj \
 ; RUN:     -split-dwarf-file=foo.dwo -o=%t-64.o < %s
 ; RUN: llvm-dwarfdump %t-64.o 2>&1 | FileCheck %s
 
-; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -filetype=asm \
+; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -enable-debug-tls-location -filetype=asm \
 ; RUN:     -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM32 %s
-; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -filetype=asm \
+; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -enable-debug-tls-location -filetype=asm \
 ; RUN:     -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM64 %s
 
- at x = thread_local global i32 5, align 4, !dbg !0
+ at x = dso_local thread_local global i32 5, align 4, !dbg !0
 
 ; CHECK-NOT: error: failed to compute relocation: R_MIPS_TLS_DTPREL
 
diff --git a/llvm/test/DebugInfo/Mips/tls.ll b/llvm/test/DebugInfo/Mips/tls.ll
index 5a00d6b757c36e..f1ca265b74a546 100644
--- a/llvm/test/DebugInfo/Mips/tls.ll
+++ b/llvm/test/DebugInfo/Mips/tls.ll
@@ -1,7 +1,7 @@
-; RUN: llc -O0 -mtriple=mips-elf -mcpu=mips32r2 -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-WORD
-; RUN: llc -O0 -mtriple=mips64-elf -mcpu=mips64r2 -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-DWORD
+; RUN: llc -O0 -mtriple=mips-elf -mcpu=mips32r2 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-WORD
+; RUN: llc -O0 -mtriple=mips64-elf -mcpu=mips64r2 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-DWORD
 
- at x = thread_local global i32 5, align 4, !dbg !0
+ at x = dso_local thread_local global i32 5, align 4, !dbg !0
 
 ; CHECK-WORD: .dtprelword x+32768
 ; CHECK-DWORD: .dtpreldword x+32768
diff --git a/llvm/test/DebugInfo/PowerPC/tls-fission.ll b/llvm/test/DebugInfo/PowerPC/tls-fission.ll
index fdc53de8317485..31918364f12656 100644
--- a/llvm/test/DebugInfo/PowerPC/tls-fission.ll
+++ b/llvm/test/DebugInfo/PowerPC/tls-fission.ll
@@ -1,4 +1,4 @@
-; RUN: llc -split-dwarf-file=foo.dwo -mtriple=powerpc64-unknown-linux-gnu -O0 -filetype=asm < %s | FileCheck %s
+; RUN: llc -split-dwarf-file=foo.dwo -mtriple=powerpc64-unknown-linux-gnu -O0 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s
 
 ; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use
 ; that here instead of raw assembly printing
@@ -19,7 +19,7 @@
 
 source_filename = "test/DebugInfo/PowerPC/tls-fission.ll"
 
- at tls = thread_local global i32 0, align 4, !dbg !0
+ at tls = dso_local thread_local global i32 0, align 4, !dbg !0
 
 !llvm.dbg.cu = !{!4}
 !llvm.module.flags = !{!7, !8}
diff --git a/llvm/test/DebugInfo/PowerPC/tls.ll b/llvm/test/DebugInfo/PowerPC/tls.ll
index 1483381d99605a..a07f23f7d6aeef 100644
--- a/llvm/test/DebugInfo/PowerPC/tls.ll
+++ b/llvm/test/DebugInfo/PowerPC/tls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -O0 -filetype=asm < %s | FileCheck %s
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -O0 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s
 
 ; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use
 ; that here instead of raw assembly printing
@@ -14,7 +14,7 @@
 
 source_filename = "test/DebugInfo/PowerPC/tls.ll"
 
- at tls = thread_local global i32 7, align 4, !dbg !0
+ at tls = dso_local thread_local global i32 7, align 4, !dbg !0
 
 !llvm.dbg.cu = !{!4}
 !llvm.module.flags = !{!7, !8}
diff --git a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
index 70a68f9489764a..80f7da4764022b 100644
--- a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
+++ b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
@@ -1,30 +1,30 @@
 ; Non-PIC tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics - -o %t.localexec.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics - -o %t.generaldynamic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics - -o %t.localexec.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics - -o %t.generaldynamic.o
 ; RUN: llvm-dwarfdump %t.localexec.o | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.o | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-readobj -r %t.localexec.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT
 ; RUN: llvm-readobj -r %t.generaldynamic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT
 
 ; PIC tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.localexec.pic.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.generaldynamic.pic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.localexec.pic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.generaldynamic.pic.o
 ; RUN: llvm-dwarfdump %t.localexec.pic.o | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.pic.o | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-readobj -r %t.localexec.pic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT,RELOCS-PIC-NOSPLIT
 ; RUN: llvm-readobj -r %t.generaldynamic.pic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT,RELOCS-PIC-NOSPLIT
 
 ; Non-PIC + split DWARF tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.localexec.split.dwo -split-dwarf-output=%t.localexec.split.dwo - -o %t.localexec.split.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.generaldynamic.split.dwo -split-dwarf-output=%t.generaldynamic.split.dwo - -o %t.generaldynamic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.localexec.split.dwo -split-dwarf-output=%t.localexec.split.dwo - -o %t.localexec.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.generaldynamic.split.dwo -split-dwarf-output=%t.generaldynamic.split.dwo - -o %t.generaldynamic.split.o
 ; RUN: llvm-dwarfdump %t.localexec.split.dwo | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.split.dwo | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-readobj -r %t.localexec.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
 ; RUN: llvm-readobj -r %t.generaldynamic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
 
 ; PIC + split DWARF tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.localexec.pic.split.dwo -split-dwarf-output=%t.localexec.pic.split.dwo - -o %t.localexec.pic.split.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.generaldynamic.pic.split.dwo -split-dwarf-output=%t.generaldynamic.pic.split.dwo - -o %t.generaldynamic.pic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.localexec.pic.split.dwo -split-dwarf-output=%t.localexec.pic.split.dwo - -o %t.localexec.pic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.generaldynamic.pic.split.dwo -split-dwarf-output=%t.generaldynamic.pic.split.dwo - -o %t.generaldynamic.pic.split.o
 ; RUN: llvm-dwarfdump %t.localexec.pic.split.dwo | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.pic.split.dwo | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-readobj -r %t.localexec.pic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
@@ -57,8 +57,8 @@ target triple = "wasm32-unknown-emscripten"
 @external_var1 = global i32 222, align 4, !dbg !5
 @internal_var0 = internal global i32 333, align 4, !dbg !8
 @internal_var1 = internal global i32 444, align 4, !dbg !10
- at external_tls_var0 = thread_local[[TLS_MODE]] global i32 555, align 4, !dbg !12
- at external_tls_var1 = thread_local[[TLS_MODE]] global i32 666, align 4, !dbg !14
+ at external_tls_var0 = dso_local thread_local[[TLS_MODE]] global i32 555, align 4, !dbg !12
+ at external_tls_var1 = dso_local thread_local[[TLS_MODE]] global i32 666, align 4, !dbg !14
 @internal_tls_var0 = internal thread_local[[TLS_MODE]] global i32 777, align 4, !dbg !16
 @internal_tls_var1 = internal thread_local[[TLS_MODE]] global i32 888, align 4, !dbg !18
 
diff --git a/llvm/test/DebugInfo/X86/debugger-tune.ll b/llvm/test/DebugInfo/X86/debugger-tune.ll
index 41429b2f650ddb..aae56ff2149f71 100644
--- a/llvm/test/DebugInfo/X86/debugger-tune.ll
+++ b/llvm/test/DebugInfo/X86/debugger-tune.ll
@@ -4,16 +4,16 @@
 ; vs. DW_OP_GNU_push_tls_address opcodes to distinguish the debuggers.
 
 ; Verify defaults for various targets.
-; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
-; RUN: llc -mtriple=x86_64-sie-ps5 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
-; RUN: llc -mtriple=x86_64-pc-freebsd -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
-; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
+; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
+; RUN: llc -mtriple=x86_64-sie-ps5 -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
+; RUN: llc -mtriple=x86_64-pc-freebsd -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
+; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
 
 ; We can override defaults.
-; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -debugger-tune=gdb < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
-; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -debugger-tune=lldb < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=sce < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
+; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -debugger-tune=gdb -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
+; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -debugger-tune=lldb -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=sce -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
 
 ; GDB-NOT: DW_AT_APPLE_optimized
 ; GDB-NOT: DW_OP_form_tls_address
@@ -24,7 +24,7 @@
 ; SCE-NOT: DW_AT_APPLE_optimized
 ; SCE-NOT: DW_OP_GNU_push_tls_address
 
- at var = internal thread_local global i32 0, align 4, !dbg !0
+ at var = dso_local thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/gnu-names.ll b/llvm/test/DebugInfo/X86/gnu-names.ll
index de8b147a1087c6..37b6612a7c82c2 100644
--- a/llvm/test/DebugInfo/X86/gnu-names.ll
+++ b/llvm/test/DebugInfo/X86/gnu-names.ll
@@ -1,10 +1,10 @@
 ; Verify the emission of accelerator tables for various targets for the DWARF<=4 case
 
 ; Darwin has the apple tables unless we specifically tune for gdb
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %s > %t
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -enable-debug-tls-location < %s > %t
 ; RUN: llvm-readobj --sections %t | FileCheck --check-prefix=APPLE %s
 ; RUN: llvm-dwarfdump -apple-names %t | FileCheck --check-prefix=APPLE-NAMES %s
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=gdb < %s \
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=gdb -enable-debug-tls-location < %s \
 ; RUN:   | llvm-readobj --sections - | FileCheck --check-prefix=GNU %s
 
 ; Linux does has debug_names tables only if we explicitly tune for lldb
@@ -41,7 +41,7 @@
 ; NONE-NOT: debug_names
 ; NONE: debug_gnu_pub
 
- at var = internal thread_local global i32 0, align 4, !dbg !0
+ at var = dso_local thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/tls.ll b/llvm/test/DebugInfo/X86/tls.ll
index d8ef5e80dc15e8..78517671adef0a 100644
--- a/llvm/test/DebugInfo/X86/tls.ll
+++ b/llvm/test/DebugInfo/X86/tls.ll
@@ -1,19 +1,19 @@
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -enable-debug-tls-location \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-64,GNUOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu -enable-debug-tls-location -enable-debug-tls-location \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-32,GNUOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -split-dwarf-file=foo.dwo \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -split-dwarf-file=foo.dwo -enable-debug-tls-location \
 ; RUN:   | FileCheck --check-prefixes=FISSION,GNUOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-scei-ps4 \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-scei-ps4 -enable-debug-tls-location \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-64,STDOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-apple-darwin \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-apple-darwin -enable-debug-tls-location \
 ; RUN:   | FileCheck --check-prefixes=DARWIN,STDOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd -enable-debug-tls-location \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-64,GNUOP %s
 
 ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -emulated-tls \
@@ -102,7 +102,7 @@
 
 source_filename = "test/DebugInfo/X86/tls.ll"
 
- at tls = internal thread_local global i32 0, align 4, !dbg !0
+ at tls = dso_local thread_local global i32 0, align 4, !dbg !0
 @glbl = global i32 0, align 4, !dbg !4
 
 ; Function Attrs: nounwind uwtable
diff --git a/llvm/test/DebugInfo/accel-tables-apple.ll b/llvm/test/DebugInfo/accel-tables-apple.ll
index 727e7aecc130e4..c72d460e8bfa8e 100644
--- a/llvm/test/DebugInfo/accel-tables-apple.ll
+++ b/llvm/test/DebugInfo/accel-tables-apple.ll
@@ -1,11 +1,11 @@
 ; Verify the emission of accelerator tables for nameTableKind: Apple
 ; REQUIRES: x86-registered-target
 
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -o %t.d5.o < %S/Inputs/name-table-kind-apple-5.ll
+; RUN: llc -mtriple=x86_64-apple-darwin12 -enable-debug-tls-location -filetype=obj -o %t.d5.o < %S/Inputs/name-table-kind-apple-5.ll
 ; RUN:   llvm-readobj --sections %t.d5.o | FileCheck --check-prefix=DEBUG_NAMES %s
 ; RUN:   llvm-dwarfdump --debug-names %t.d5.o | FileCheck --check-prefix=COUNT_DEBUG_NAMES %s
 
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %S/Inputs/name-table-kind-apple-4.ll \
+; RUN: llc -mtriple=x86_64-apple-darwin12 -enable-debug-tls-location -filetype=obj < %S/Inputs/name-table-kind-apple-4.ll \
 ; RUN:   | llvm-readobj --sections - | FileCheck --check-prefix=APPLE %s
 
 ; APPLE-NOT: debug_names
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test
index d5349f9f403c39..7f3dd6f6ec5892 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test
@@ -24,7 +24,7 @@
 ; llvm-debuginfo-analyzer --attribute=location --print=symbols
 ;                         ThreadLocalStorage.o
 
-; RUN: llc --filetype=obj \
+; RUN: llc --filetype=obj -enable-debug-tls-location \
 ; RUN:     %p/Inputs/ThreadLocalStorage.ll -o %t.ThreadLocalStorage.o
 
 ; RUN: llvm-debuginfo-analyzer --attribute=location \

>From beedfda6e705c6daeb3711a92ea864ceb2c43146 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Tue, 10 Mar 2026 14:54:34 +0000
Subject: [PATCH 11/12] Added aarch64 check

---
 .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp   |  6 ++---
 llvm/test/DebugInfo/ARM/tls.ll                |  4 ++--
 .../Inputs/name-table-kind-apple-5.ll         |  2 +-
 llvm/test/DebugInfo/Mips/dwarfdump-tls.ll     | 10 ++++----
 llvm/test/DebugInfo/Mips/tls.ll               |  6 ++---
 llvm/test/DebugInfo/PowerPC/tls-fission.ll    |  4 ++--
 llvm/test/DebugInfo/PowerPC/tls.ll            |  4 ++--
 .../DebugInfo/WebAssembly/tls_pic_globals.ll  | 24 +++++++++----------
 llvm/test/DebugInfo/X86/debugger-tune.ll      | 18 +++++++-------
 llvm/test/DebugInfo/X86/gnu-names.ll          |  6 ++---
 llvm/test/DebugInfo/X86/tls.ll                | 14 +++++------
 llvm/test/DebugInfo/accel-tables-apple.ll     |  4 ++--
 .../DWARF/crash-thread-local-storage.test     |  2 +-
 13 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 41f7e942a67398..89f1a490608995 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -284,10 +284,8 @@ void DwarfCompileUnit::addLocationAttribute(
       // (e.g. TLS in shared libraries). The TLS offset cannot be
       // represented safely in DWARF. In that case let Debugger use
       // Runtime TLS lookup via DTV (Dynmic thread vector).
-      if (!Global->isDSOLocal())
-        continue;
-
-      if (!EnableDebugTLSLocation)
+      if (!EnableDebugTLSLocation && !Global->isDSOLocal() &&
+          !Asm->TM.getTargetTriple().isAArch64())
         continue;
 
       if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())
diff --git a/llvm/test/DebugInfo/ARM/tls.ll b/llvm/test/DebugInfo/ARM/tls.ll
index 936ed9bc6b1ccf..53cb08d0f299cf 100644
--- a/llvm/test/DebugInfo/ARM/tls.ll
+++ b/llvm/test/DebugInfo/ARM/tls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi -enable-debug-tls-location < %s \
+; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi < %s \
 ; RUN:     | FileCheck %s
 ; RUN: llc -O0 -filetype=asm -mtriple=armv7-linux-gnuehabi -emulated-tls < %s \
 ; RUN:     | FileCheck %s --check-prefix=EMU
@@ -8,7 +8,7 @@
 
 source_filename = "test/DebugInfo/ARM/tls.ll"
 
- at x = dso_local thread_local global i32 0, align 4, !dbg !0
+ at x = thread_local global i32 0, align 4, !dbg !0
 
 !llvm.dbg.cu = !{!4}
 !llvm.module.flags = !{!7, !8}
diff --git a/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll b/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
index 1a8c30f459ff6f..35752a934d0e67 100644
--- a/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
+++ b/llvm/test/DebugInfo/Inputs/name-table-kind-apple-5.ll
@@ -1,4 +1,4 @@
- at var = dso_local thread_local global i32 0, align 4, !dbg !0
+ at var = thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll b/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll
index ebd839e5f4c4cb..acf7067e8c52b1 100644
--- a/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll
+++ b/llvm/test/DebugInfo/Mips/dwarfdump-tls.ll
@@ -1,16 +1,16 @@
-; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -enable-debug-tls-location -filetype=obj \
+; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -filetype=obj \
 ; RUN:     -split-dwarf-file=foo.dwo -o=%t-32.o < %s
 ; RUN: llvm-dwarfdump %t-32.o 2>&1 | FileCheck %s
-; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -enable-debug-tls-location -filetype=obj \
+; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -filetype=obj \
 ; RUN:     -split-dwarf-file=foo.dwo -o=%t-64.o < %s
 ; RUN: llvm-dwarfdump %t-64.o 2>&1 | FileCheck %s
 
-; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -enable-debug-tls-location -filetype=asm \
+; RUN: llc -O0 -mtriple=mips -mcpu=mips32r2 -filetype=asm \
 ; RUN:     -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM32 %s
-; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -enable-debug-tls-location -filetype=asm \
+; RUN: llc -O0 -mtriple=mips64 -mcpu=mips64r2 -filetype=asm \
 ; RUN:     -split-dwarf-file=foo.dwo < %s | FileCheck -check-prefix=ASM64 %s
 
- at x = dso_local thread_local global i32 5, align 4, !dbg !0
+ at x = thread_local global i32 5, align 4, !dbg !0
 
 ; CHECK-NOT: error: failed to compute relocation: R_MIPS_TLS_DTPREL
 
diff --git a/llvm/test/DebugInfo/Mips/tls.ll b/llvm/test/DebugInfo/Mips/tls.ll
index f1ca265b74a546..5a00d6b757c36e 100644
--- a/llvm/test/DebugInfo/Mips/tls.ll
+++ b/llvm/test/DebugInfo/Mips/tls.ll
@@ -1,7 +1,7 @@
-; RUN: llc -O0 -mtriple=mips-elf -mcpu=mips32r2 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-WORD
-; RUN: llc -O0 -mtriple=mips64-elf -mcpu=mips64r2 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-DWORD
+; RUN: llc -O0 -mtriple=mips-elf -mcpu=mips32r2 -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-WORD
+; RUN: llc -O0 -mtriple=mips64-elf -mcpu=mips64r2 -filetype=asm < %s | FileCheck %s -check-prefix=CHECK-DWORD
 
- at x = dso_local thread_local global i32 5, align 4, !dbg !0
+ at x = thread_local global i32 5, align 4, !dbg !0
 
 ; CHECK-WORD: .dtprelword x+32768
 ; CHECK-DWORD: .dtpreldword x+32768
diff --git a/llvm/test/DebugInfo/PowerPC/tls-fission.ll b/llvm/test/DebugInfo/PowerPC/tls-fission.ll
index 31918364f12656..fdc53de8317485 100644
--- a/llvm/test/DebugInfo/PowerPC/tls-fission.ll
+++ b/llvm/test/DebugInfo/PowerPC/tls-fission.ll
@@ -1,4 +1,4 @@
-; RUN: llc -split-dwarf-file=foo.dwo -mtriple=powerpc64-unknown-linux-gnu -O0 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s
+; RUN: llc -split-dwarf-file=foo.dwo -mtriple=powerpc64-unknown-linux-gnu -O0 -filetype=asm < %s | FileCheck %s
 
 ; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use
 ; that here instead of raw assembly printing
@@ -19,7 +19,7 @@
 
 source_filename = "test/DebugInfo/PowerPC/tls-fission.ll"
 
- at tls = dso_local thread_local global i32 0, align 4, !dbg !0
+ at tls = thread_local global i32 0, align 4, !dbg !0
 
 !llvm.dbg.cu = !{!4}
 !llvm.module.flags = !{!7, !8}
diff --git a/llvm/test/DebugInfo/PowerPC/tls.ll b/llvm/test/DebugInfo/PowerPC/tls.ll
index a07f23f7d6aeef..1483381d99605a 100644
--- a/llvm/test/DebugInfo/PowerPC/tls.ll
+++ b/llvm/test/DebugInfo/PowerPC/tls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -O0 -enable-debug-tls-location -filetype=asm < %s | FileCheck %s
+; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -O0 -filetype=asm < %s | FileCheck %s
 
 ; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use
 ; that here instead of raw assembly printing
@@ -14,7 +14,7 @@
 
 source_filename = "test/DebugInfo/PowerPC/tls.ll"
 
- at tls = dso_local thread_local global i32 7, align 4, !dbg !0
+ at tls = thread_local global i32 7, align 4, !dbg !0
 
 !llvm.dbg.cu = !{!4}
 !llvm.module.flags = !{!7, !8}
diff --git a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
index 80f7da4764022b..e4a2858b69788e 100644
--- a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
+++ b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
@@ -1,30 +1,30 @@
 ; Non-PIC tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics - -o %t.localexec.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics - -o %t.generaldynamic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics - -o %t.localexec.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics - -o %t.generaldynamic.o
 ; RUN: llvm-dwarfdump %t.localexec.o | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.o | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-readobj -r %t.localexec.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT
 ; RUN: llvm-readobj -r %t.generaldynamic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT
 
 ; PIC tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.localexec.pic.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.generaldynamic.pic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.localexec.pic.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic - -o %t.generaldynamic.pic.o
 ; RUN: llvm-dwarfdump %t.localexec.pic.o | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.pic.o | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-readobj -r %t.localexec.pic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT,RELOCS-PIC-NOSPLIT
 ; RUN: llvm-readobj -r %t.generaldynamic.pic.o | FileCheck %s --check-prefixes=RELOCS-NOSPLIT,RELOCS-PIC-NOSPLIT
 
 ; Non-PIC + split DWARF tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.localexec.split.dwo -split-dwarf-output=%t.localexec.split.dwo - -o %t.localexec.split.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.generaldynamic.split.dwo -split-dwarf-output=%t.generaldynamic.split.dwo - -o %t.generaldynamic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.localexec.split.dwo -split-dwarf-output=%t.localexec.split.dwo - -o %t.localexec.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -split-dwarf-file=%t.generaldynamic.split.dwo -split-dwarf-output=%t.generaldynamic.split.dwo - -o %t.generaldynamic.split.o
 ; RUN: llvm-dwarfdump %t.localexec.split.dwo | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.split.dwo | FileCheck %s --check-prefixes=CHECK,NOPIC
 ; RUN: llvm-readobj -r %t.localexec.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
 ; RUN: llvm-readobj -r %t.generaldynamic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
 
 ; PIC + split DWARF tests
-; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.localexec.pic.split.dwo -split-dwarf-output=%t.localexec.pic.split.dwo - -o %t.localexec.pic.split.o
-; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -enable-debug-tls-location -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.generaldynamic.pic.split.dwo -split-dwarf-output=%t.generaldynamic.pic.split.dwo - -o %t.generaldynamic.pic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]/(localexec)/' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.localexec.pic.split.dwo -split-dwarf-output=%t.localexec.pic.split.dwo - -o %t.localexec.pic.split.o
+; RUN: sed -e 's/\[\[TLS_MODE\]\]//' %s | llc -filetype=obj -mattr=+bulk-memory,atomics -relocation-model=pic -split-dwarf-file=%t.generaldynamic.pic.split.dwo -split-dwarf-output=%t.generaldynamic.pic.split.dwo - -o %t.generaldynamic.pic.split.o
 ; RUN: llvm-dwarfdump %t.localexec.pic.split.dwo | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-dwarfdump %t.generaldynamic.pic.split.dwo | FileCheck %s --check-prefixes=CHECK,PIC
 ; RUN: llvm-readobj -r %t.localexec.pic.split.dwo | FileCheck %s --check-prefixes=RELOCS-SPLIT
@@ -57,10 +57,10 @@ target triple = "wasm32-unknown-emscripten"
 @external_var1 = global i32 222, align 4, !dbg !5
 @internal_var0 = internal global i32 333, align 4, !dbg !8
 @internal_var1 = internal global i32 444, align 4, !dbg !10
- at external_tls_var0 = dso_local thread_local[[TLS_MODE]] global i32 555, align 4, !dbg !12
- at external_tls_var1 = dso_local thread_local[[TLS_MODE]] global i32 666, align 4, !dbg !14
- at internal_tls_var0 = internal thread_local[[TLS_MODE]] global i32 777, align 4, !dbg !16
- at internal_tls_var1 = internal thread_local[[TLS_MODE]] global i32 888, align 4, !dbg !18
+ at external_tls_var0 = thread_local[[TLS_MODE]] global i32 555, align 4, !dbg !12
+ at external_tls_var1 = thread_local[[TLS_MODE]] global i32 666, align 4, !dbg !14
+ at internal_tls_var0 = thread_local[[TLS_MODE]] global i32 777, align 4, !dbg !16
+ at internal_tls_var1 = thread_local[[TLS_MODE]] global i32 888, align 4, !dbg !18
 
 define void @foo(i32, i32, i32, i32, i32, i32, i32, i32) {
   ret void
diff --git a/llvm/test/DebugInfo/X86/debugger-tune.ll b/llvm/test/DebugInfo/X86/debugger-tune.ll
index aae56ff2149f71..39359359d64dca 100644
--- a/llvm/test/DebugInfo/X86/debugger-tune.ll
+++ b/llvm/test/DebugInfo/X86/debugger-tune.ll
@@ -4,16 +4,16 @@
 ; vs. DW_OP_GNU_push_tls_address opcodes to distinguish the debuggers.
 
 ; Verify defaults for various targets.
-; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
-; RUN: llc -mtriple=x86_64-sie-ps5 -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
-; RUN: llc -mtriple=x86_64-pc-freebsd -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
-; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
+; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
+; RUN: llc -mtriple=x86_64-sie-ps5 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
+; RUN: llc -mtriple=x86_64-pc-freebsd -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
+; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
 
 ; We can override defaults.
-; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -debugger-tune=gdb -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
-; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -debugger-tune=lldb -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=sce -enable-debug-tls-location < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
+; RUN: llc -mtriple=x86_64-scei-ps4 -filetype=obj -debugger-tune=gdb < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=GDB %s
+; RUN: llc -mtriple=x86_64-pc-linux -filetype=obj -debugger-tune=lldb < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=LLDB %s
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=sce < %s | llvm-dwarfdump -debug-info - | FileCheck --check-prefix=SCE %s
 
 ; GDB-NOT: DW_AT_APPLE_optimized
 ; GDB-NOT: DW_OP_form_tls_address
@@ -24,7 +24,7 @@
 ; SCE-NOT: DW_AT_APPLE_optimized
 ; SCE-NOT: DW_OP_GNU_push_tls_address
 
- at var = dso_local thread_local global i32 0, align 4, !dbg !0
+ at var = thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/gnu-names.ll b/llvm/test/DebugInfo/X86/gnu-names.ll
index 37b6612a7c82c2..fe535e662dc048 100644
--- a/llvm/test/DebugInfo/X86/gnu-names.ll
+++ b/llvm/test/DebugInfo/X86/gnu-names.ll
@@ -1,10 +1,10 @@
 ; Verify the emission of accelerator tables for various targets for the DWARF<=4 case
 
 ; Darwin has the apple tables unless we specifically tune for gdb
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -enable-debug-tls-location < %s > %t
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %s > %t
 ; RUN: llvm-readobj --sections %t | FileCheck --check-prefix=APPLE %s
 ; RUN: llvm-dwarfdump -apple-names %t | FileCheck --check-prefix=APPLE-NAMES %s
-; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=gdb -enable-debug-tls-location < %s \
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -debugger-tune=gdb < %s \
 ; RUN:   | llvm-readobj --sections - | FileCheck --check-prefix=GNU %s
 
 ; Linux does has debug_names tables only if we explicitly tune for lldb
@@ -41,7 +41,7 @@
 ; NONE-NOT: debug_names
 ; NONE: debug_gnu_pub
 
- at var = dso_local thread_local global i32 0, align 4, !dbg !0
+ at var = thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: norecurse nounwind readnone uwtable
 define void @_Z3funv() local_unnamed_addr #0 !dbg !11 {
diff --git a/llvm/test/DebugInfo/X86/tls.ll b/llvm/test/DebugInfo/X86/tls.ll
index 78517671adef0a..da569fdc5e5a4b 100644
--- a/llvm/test/DebugInfo/X86/tls.ll
+++ b/llvm/test/DebugInfo/X86/tls.ll
@@ -1,19 +1,19 @@
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -enable-debug-tls-location \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-64,GNUOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu -enable-debug-tls-location -enable-debug-tls-location \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-32,GNUOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -split-dwarf-file=foo.dwo -enable-debug-tls-location \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -split-dwarf-file=foo.dwo \
 ; RUN:   | FileCheck --check-prefixes=FISSION,GNUOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-scei-ps4 -enable-debug-tls-location \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-scei-ps4 \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-64,STDOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-apple-darwin -enable-debug-tls-location \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-apple-darwin \
 ; RUN:   | FileCheck --check-prefixes=DARWIN,STDOP %s
 
-; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd -enable-debug-tls-location \
+; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd \
 ; RUN:   | FileCheck --check-prefixes=SINGLE,SINGLE-64,GNUOP %s
 
 ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -emulated-tls \
@@ -102,7 +102,7 @@
 
 source_filename = "test/DebugInfo/X86/tls.ll"
 
- at tls = dso_local thread_local global i32 0, align 4, !dbg !0
+ at tls = thread_local global i32 0, align 4, !dbg !0
 @glbl = global i32 0, align 4, !dbg !4
 
 ; Function Attrs: nounwind uwtable
diff --git a/llvm/test/DebugInfo/accel-tables-apple.ll b/llvm/test/DebugInfo/accel-tables-apple.ll
index c72d460e8bfa8e..727e7aecc130e4 100644
--- a/llvm/test/DebugInfo/accel-tables-apple.ll
+++ b/llvm/test/DebugInfo/accel-tables-apple.ll
@@ -1,11 +1,11 @@
 ; Verify the emission of accelerator tables for nameTableKind: Apple
 ; REQUIRES: x86-registered-target
 
-; RUN: llc -mtriple=x86_64-apple-darwin12 -enable-debug-tls-location -filetype=obj -o %t.d5.o < %S/Inputs/name-table-kind-apple-5.ll
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj -o %t.d5.o < %S/Inputs/name-table-kind-apple-5.ll
 ; RUN:   llvm-readobj --sections %t.d5.o | FileCheck --check-prefix=DEBUG_NAMES %s
 ; RUN:   llvm-dwarfdump --debug-names %t.d5.o | FileCheck --check-prefix=COUNT_DEBUG_NAMES %s
 
-; RUN: llc -mtriple=x86_64-apple-darwin12 -enable-debug-tls-location -filetype=obj < %S/Inputs/name-table-kind-apple-4.ll \
+; RUN: llc -mtriple=x86_64-apple-darwin12 -filetype=obj < %S/Inputs/name-table-kind-apple-4.ll \
 ; RUN:   | llvm-readobj --sections - | FileCheck --check-prefix=APPLE %s
 
 ; APPLE-NOT: debug_names
diff --git a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test
index 7f3dd6f6ec5892..d5349f9f403c39 100644
--- a/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test
+++ b/llvm/test/tools/llvm-debuginfo-analyzer/DWARF/crash-thread-local-storage.test
@@ -24,7 +24,7 @@
 ; llvm-debuginfo-analyzer --attribute=location --print=symbols
 ;                         ThreadLocalStorage.o
 
-; RUN: llc --filetype=obj -enable-debug-tls-location \
+; RUN: llc --filetype=obj \
 ; RUN:     %p/Inputs/ThreadLocalStorage.ll -o %t.ThreadLocalStorage.o
 
 ; RUN: llvm-debuginfo-analyzer --attribute=location \

>From 726643fd5543508214eb81b272854ea07b9c5470 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Tue, 10 Mar 2026 15:00:19 +0000
Subject: [PATCH 12/12] Rollback WebAssembly/tls_pic_globals.ll change

---
 llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
index e4a2858b69788e..70a68f9489764a 100644
--- a/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
+++ b/llvm/test/DebugInfo/WebAssembly/tls_pic_globals.ll
@@ -59,8 +59,8 @@ target triple = "wasm32-unknown-emscripten"
 @internal_var1 = internal global i32 444, align 4, !dbg !10
 @external_tls_var0 = thread_local[[TLS_MODE]] global i32 555, align 4, !dbg !12
 @external_tls_var1 = thread_local[[TLS_MODE]] global i32 666, align 4, !dbg !14
- at internal_tls_var0 = thread_local[[TLS_MODE]] global i32 777, align 4, !dbg !16
- at internal_tls_var1 = thread_local[[TLS_MODE]] global i32 888, align 4, !dbg !18
+ at internal_tls_var0 = internal thread_local[[TLS_MODE]] global i32 777, align 4, !dbg !16
+ at internal_tls_var1 = internal thread_local[[TLS_MODE]] global i32 888, align 4, !dbg !18
 
 define void @foo(i32, i32, i32, i32, i32, i32, i32, i32) {
   ret void



More information about the llvm-commits mailing list