[llvm-branch-commits] [llvm] release/23.x: [ARM] Exclude TLS symbols from the .reloc/R_ARM_REL32 path (#212549) (PR #212735)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jul 29 03:54:05 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: llvmbot

<details>
<summary>Changes</summary>

Backport f4382be

Requested by: @<!-- -->dongjianqiang2

---
Full diff: https://github.com/llvm/llvm-project/pull/212735.diff


2 Files Affected:

- (modified) llvm/lib/Target/ARM/ARMAsmPrinter.cpp (+5-4) 
- (modified) llvm/test/CodeGen/ARM/elf-preemption.ll (+35) 


``````````diff
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 49c5c983e2934..b067c1e60c4b2 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -1023,10 +1023,11 @@ void ARMAsmPrinter::emitMachineConstantPoolValue(
     // a weak definition with a non-weak definition from another section. Use a
     // .reloc directive rather than a fixup to force the generation of a
     // relocation (R_ARM_REL32) so the linker can perform the override. This is
-    // restricted to dso_local symbols: a preemptible/external weak symbol
-    // (e.g. an extern_weak reference) must use the GOT, as R_ARM_REL32 against
-    // an external symbol cannot be used when making a shared object.
-    if (GV->isWeakForLinker() && GV->isDSOLocal() &&
+    // restricted to dso_local, non-TLS symbols: a preemptible/external weak
+    // symbol (e.g. an extern_weak reference) must use the GOT, as R_ARM_REL32
+    // against an external symbol cannot be used when making a shared object;
+    // and TLS symbols require TLS-specific relocations, not R_ARM_REL32.
+    if (GV->isWeakForLinker() && GV->isDSOLocal() && !GV->isThreadLocal() &&
         TM.getTargetTriple().isOSBinFormatELF() && TM.isPositionIndependent() &&
         ACPV->getPCAdjustment() != 0) {
       MCSymbol *CPILabel = OutContext.createTempSymbol();
diff --git a/llvm/test/CodeGen/ARM/elf-preemption.ll b/llvm/test/CodeGen/ARM/elf-preemption.ll
index 599a59520e5e3..aa8296b0c4902 100644
--- a/llvm/test/CodeGen/ARM/elf-preemption.ll
+++ b/llvm/test/CodeGen/ARM/elf-preemption.ll
@@ -291,3 +291,38 @@ define ptr @get_extern_weak_hidden_func() nounwind {
 ; PIC-NEXT:    .long extern_weak_hidden_func(GOT_PREL)-(.LPC12_0+8-.Ltmp7)
   ret ptr @extern_weak_hidden_func
 }
+
+;; TLS weak symbols must not use the .reloc/R_ARM_REL32 path; they require
+;; TLS-specific relocations (R_ARM_TLS_GD32 etc.), not R_ARM_REL32. Using
+;; R_ARM_REL32 for a TLS symbol produces a wrong address and crashes at runtime.
+ at tls_weak_var = weak dso_local thread_local global i32 42
+define ptr @get_tls_weak_var() nounwind {
+; STATIC-LABEL: get_tls_weak_var:
+; STATIC:       @ %bb.0:
+; STATIC-NEXT:    .save {r11, lr}
+; STATIC-NEXT:    push {r11, lr}
+; STATIC-NEXT:    ldr r1, .LCPI13_0
+; STATIC-NEXT:    bl __aeabi_read_tp
+; STATIC-NEXT:    add r0, r0, r1
+; STATIC-NEXT:    pop {r11, pc}
+; STATIC-NEXT:    .p2align 2
+; STATIC-NEXT:  @ %bb.1:
+; STATIC-NEXT:  .LCPI13_0:
+; STATIC-NEXT:    .long tls_weak_var(TPOFF)
+;
+; PIC-LABEL: get_tls_weak_var:
+; PIC:       @ %bb.0:
+; PIC-NEXT:    .save {r11, lr}
+; PIC-NEXT:    push {r11, lr}
+; PIC-NEXT:    ldr r0, .LCPI13_0
+; PIC-NEXT:  .LPC13_0:
+; PIC-NEXT:    add r0, pc, r0
+; PIC-NEXT:    bl __tls_get_addr
+; PIC-NEXT:    pop {r11, pc}
+; PIC-NEXT:    .p2align 2
+; PIC-NEXT:  @ %bb.1:
+; PIC-NEXT:  .LCPI13_0:
+; PIC-NEXT:  .Ltmp8:
+; PIC-NEXT:    .long tls_weak_var(TLSGD)-(.LPC13_0+8-.Ltmp8)
+  ret ptr @tls_weak_var
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/212735


More information about the llvm-branch-commits mailing list