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

Shivam Gupta via lldb-commits lldb-commits at lists.llvm.org
Sat Mar 14 08:21:36 PDT 2026


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

>From 46f04ef96c7644557202c4ed1421e2422eb787ca 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/15] [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 f85a3f48f2183..26d98aa8312a9 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 d5d0dcf1e0d84..de60c0bd41340 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 886f41975e199..0d2c3e15004eb 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 6b3381452c70b..78c0c22da8d1b 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 590da8f93873d..cdfb9ee46634a 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 e33196d4c0144..003c666814cc8 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 8c7336084c232..010afd50c4eae 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 0000000000000..c481980354905
--- /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 20a0afb789771..d619962ccbf69 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 0000000000000..7cb47f9543f68
--- /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 8f59715a14af9797356bd440dcfb279ebefa195b 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/15] 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 0d2c3e15004eb..573498e6152b6 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 003c666814cc8..4ecf2ef268f91 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 c481980354905..b025c8c9331fd 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 d619962ccbf69..13bdad20032be 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 1a0514b8936fab18701a4d3cc1f39c9c5e207b00 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/15] 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 cdfb9ee46634a..fe34ca17b80ee 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 7cb47f9543f68..34e9588c48f2d 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 9276b7189f83e30663971ea49a82caed077b8498 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/15] 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 26d98aa8312a9..f85a3f48f2183 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 de60c0bd41340..d5d0dcf1e0d84 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 573498e6152b6..b855cd9b992d0 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 fe34ca17b80ee..017ed2a5d0868 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 010afd50c4eae..df4732d2fbba4 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 2e7ea4b818f1c5ef32f7a7a3cc7e87bbca85050a 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/15] 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 017ed2a5d0868..cdfb9ee46634a 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 7807c0095168058da2cd29038ad56707be6238c2 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/15] 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 840f2637d9564..2c1b1dfc4d8dd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -254,9 +254,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 b025c8c9331fd..a3898e88be6ff 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 13bdad20032be..69911eaa3a17b 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 0000000000000..6e70c36e6e9bf
--- /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 c40a73fecd6255d3f23078421285673d041bce8a 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/15] 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 2c1b1dfc4d8dd..1678570f05daa 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -255,7 +255,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 a253cc9fa8c269b03d52606b58d37b7d861e903d 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/15] 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 1678570f05daa..7e4c4f2a3dcba 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -259,8 +259,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 225e0d4d8f0746aa98328052ee49528109f98687 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/15] 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 7e4c4f2a3dcba..313e4e69a9e99 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -259,7 +259,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 b855cd9b992d0..d70f8a46f897d 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 df4732d2fbba4..fb99523e81cd9 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 35752a934d0e6..59ed877211822 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 39359359d64dc..41429b2f650dd 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 fe535e662dc04..de8b147a1087c 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 da569fdc5e5a4..d8ef5e80dc15e 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 f4272d72d3131bb67f616fda394af199d52a9fa9 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/15] 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 313e4e69a9e99..00a58e99b14c5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -55,6 +55,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)
@@ -262,6 +267,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 a3898e88be6ff..46c8a86a53f4b 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 69911eaa3a17b..335ee5dc60379 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 6e70c36e6e9bf..0000000000000
--- 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 53cb08d0f299c..936ed9bc6b1cc 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 59ed877211822..1a8c30f459ff6 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 acf7067e8c52b..ebd839e5f4c4c 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 5a00d6b757c36..f1ca265b74a54 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 fdc53de831748..31918364f1265 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 1483381d99605..a07f23f7d6aee 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 70a68f9489764..80f7da4764022 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 41429b2f650dd..aae56ff2149f7 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 de8b147a1087c..37b6612a7c82c 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 d8ef5e80dc15e..78517671adef0 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 727e7aecc130e..c72d460e8bfa8 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 d5349f9f403c3..7f3dd6f6ec589 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 b342065c411a3dee366aa2401226faa010a52565 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/15] 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 00a58e99b14c5..8d7f99e1b5f8b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -264,10 +264,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 936ed9bc6b1cc..53cb08d0f299c 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 1a8c30f459ff6..35752a934d0e6 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 ebd839e5f4c4c..acf7067e8c52b 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 f1ca265b74a54..5a00d6b757c36 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 31918364f1265..fdc53de831748 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 a07f23f7d6aee..1483381d99605 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 80f7da4764022..e4a2858b69788 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 aae56ff2149f7..39359359d64dc 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 37b6612a7c82c..fe535e662dc04 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 78517671adef0..da569fdc5e5a4 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 c72d460e8bfa8..727e7aecc130e 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 7f3dd6f6ec589..d5349f9f403c3 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 de72597b7302a3f1e1e3ec662728e9ad68276939 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/15] 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 e4a2858b69788..70a68f9489764 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

>From 6cd9b9608ddadf6be542f31ca233bf0ca3289672 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Wed, 11 Mar 2026 16:49:36 +0000
Subject: [PATCH 13/15] Removed dsolocal check

Signed-off-by: Shivam Gupta <shivam98.tkg at gmail.com>
---
 llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 9 +++------
 llvm/test/CodeGen/AArch64/tls-dtprel64.ll        | 2 +-
 llvm/test/DebugInfo/AArch64/tls-at-location.ll   | 2 +-
 3 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 8d7f99e1b5f8b..4501728c7857c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -260,12 +260,9 @@ void DwarfCompileUnit::addLocationAttribute(
       continue;
 
     if (Global && Global->isThreadLocal()) {
-      // 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).
-      if (!EnableDebugTLSLocation && !Global->isDSOLocal() &&
-          !Asm->TM.getTargetTriple().isAArch64())
+      // Temporary guard with option 'enable-debug-tls-location' until lld and
+      // ld support R_AARCH64_TLS_DTPREL64 relocation.
+      if (Asm->TM.getTargetTriple().isAArch64() && !EnableDebugTLSLocation)
         continue;
 
       if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())
diff --git a/llvm/test/CodeGen/AArch64/tls-dtprel64.ll b/llvm/test/CodeGen/AArch64/tls-dtprel64.ll
index 46c8a86a53f4b..108b9b7b3121f 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 = dso_local thread_local global i32 0, align 4, !dbg !0
+ at var = 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 335ee5dc60379..8c487b76da449 100644
--- a/llvm/test/DebugInfo/AArch64/tls-at-location.ll
+++ b/llvm/test/DebugInfo/AArch64/tls-at-location.ll
@@ -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 = dso_local thread_local global i32 0, align 4, !dbg !0
+ at var = thread_local global i32 0, align 4, !dbg !0
 
 ; Function Attrs: noinline nounwind optnone
 define i32 @foo() #0 !dbg !11 {

>From 85a8921e4982aec60a6a497cee35b986bacb651c Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 14 Mar 2026 20:23:45 +0530
Subject: [PATCH 14/15] Took out MC part

---
 .../AArch64/AsmParser/AArch64AsmParser.cpp    |  1 -
 .../MCTargetDesc/AArch64ELFObjectWriter.cpp   |  4 --
 .../AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp |  2 -
 llvm/test/MC/AArch64/tls-dtprel64.s           | 41 -------------------
 4 files changed, 48 deletions(-)
 delete mode 100644 llvm/test/MC/AArch64/tls-dtprel64.s

diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index cdfb9ee46634a..590da8f93873d 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -4659,7 +4659,6 @@ 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 4ecf2ef268f91..e33196d4c0144 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp
@@ -249,8 +249,6 @@ 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;
@@ -467,8 +465,6 @@ 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 fb99523e81cd9..8c7336084c232 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCAsmInfo.cpp
@@ -114,7 +114,6 @@ 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");
@@ -126,7 +125,6 @@ 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);
 }
diff --git a/llvm/test/MC/AArch64/tls-dtprel64.s b/llvm/test/MC/AArch64/tls-dtprel64.s
deleted file mode 100644
index 34e9588c48f2d..0000000000000
--- a/llvm/test/MC/AArch64/tls-dtprel64.s
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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
-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  %dtprel(var)
-.Lcu_end:

>From af32ee9b84743593845bd39bfaff849792650bc5 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <shivam98.tkg at gmail.com>
Date: Sat, 14 Mar 2026 20:50:58 +0530
Subject: [PATCH 15/15] Address review comments

---
 .../lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 17 +++--------------
 .../Target/AArch64/AArch64TargetObjectFile.cpp  |  7 +++++++
 2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 4501728c7857c..840f2637d9564 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -55,11 +55,6 @@ 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)
@@ -259,15 +254,9 @@ void DwarfCompileUnit::addLocationAttribute(
     if (!Global && (!Expr || !Expr->isConstant()))
       continue;
 
-    if (Global && Global->isThreadLocal()) {
-      // Temporary guard with option 'enable-debug-tls-location' until lld and
-      // ld support R_AARCH64_TLS_DTPREL64 relocation.
-      if (Asm->TM.getTargetTriple().isAArch64() && !EnableDebugTLSLocation)
-        continue;
-
-      if (!Asm->getObjFileLowering().supportDebugThreadLocalLocation())
-        continue;
-    }
+    if (Global && Global->isThreadLocal() &&
+        !Asm->getObjFileLowering().supportDebugThreadLocalLocation())
+      continue;
 
     if (!Loc) {
       addToAccelTable = true;
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index d70f8a46f897d..814a0443a93b7 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -22,6 +22,11 @@
 using namespace llvm;
 using namespace dwarf;
 
+static cl::opt<bool> EnableAArch64DebugTLSLocation(
+    "enable-debug-tls-location", cl::Hidden,
+    cl::desc("Enable emitting TLS DWARF location with DTPREL relocation"),
+    cl::init(false));
+
 void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
                                              const TargetMachine &TM) {
   TargetLoweringObjectFileELF::Initialize(Ctx, TM);
@@ -186,5 +191,7 @@ MCSection *AArch64_ELFTargetObjectFile::SelectSectionForGlobal(
 
 const MCExpr *AArch64_ELFTargetObjectFile::getDebugThreadLocalSymbol(
     const MCSymbol *Sym) const {
+  if (!EnableAArch64DebugTLSLocation)
+    return nullptr;
   return MCSpecifierExpr::create(Sym, AArch64::S_DTPREL, getContext());
 }



More information about the lldb-commits mailing list