[llvm-branch-commits] [llvm] 2cdedc6 - Revert "[AArch64][BOLT] Fold local-exec TLS relocations into loads and stores…"

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 18 11:06:03 PDT 2026


Author: Eugene Epshteyn
Date: 2026-08-18T14:05:56-04:00
New Revision: 2cdedc647d906f37743732be0c0b941cda6008d9

URL: https://github.com/llvm/llvm-project/commit/2cdedc647d906f37743732be0c0b941cda6008d9
DIFF: https://github.com/llvm/llvm-project/commit/2cdedc647d906f37743732be0c0b941cda6008d9.diff

LOG: Revert "[AArch64][BOLT] Fold local-exec TLS relocations into loads and stores…"

This reverts commit 378f2d88e32147459b24d63b971711136f83c0b0.

Added: 
    

Modified: 
    bolt/lib/Core/Relocation.cpp
    bolt/test/AArch64/tls.c
    llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
    llvm/test/CodeGen/AArch64/arm64-tls-local-exec.ll
    llvm/test/CodeGen/AArch64/win-tls.ll

Removed: 
    


################################################################################
diff  --git a/bolt/lib/Core/Relocation.cpp b/bolt/lib/Core/Relocation.cpp
index 55d5e07042897..b0f6b6ce0eddc 100644
--- a/bolt/lib/Core/Relocation.cpp
+++ b/bolt/lib/Core/Relocation.cpp
@@ -606,14 +606,6 @@ static bool isTLSAArch64(uint32_t Type) {
   case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
   case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
   case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
-  case ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12:
-  case ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
-  case ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12:
-  case ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
-  case ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12:
-  case ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
-  case ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12:
-  case ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
   case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:
   case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
   case ELF::R_AARCH64_TLSDESC_LD64_LO12:

diff  --git a/bolt/test/AArch64/tls.c b/bolt/test/AArch64/tls.c
index ebef59e3c1d32..947a5f587f293 100644
--- a/bolt/test/AArch64/tls.c
+++ b/bolt/test/AArch64/tls.c
@@ -5,8 +5,6 @@ __thread struct str {
   int b;
 } tbssstruct = {}, tdatastruct = {4, 2};
 
-__thread int directaccess;
-
 extern __thread struct str extstruct;
 
 extern void processAddr(volatile void *);
@@ -20,9 +18,6 @@ int main() {
   processAddr(&tbssstruct.b);
   processAddr(&tdatastruct.b);
 
-  // R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC for a direct access
-  directaccess++;
-
   // The R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 and
   // R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC relocations
   processAddr(&extstruct.b);
@@ -33,8 +28,6 @@ int main() {
 // RUN:   -Wl,--unresolved-symbols=ignore-all \
 // RUN:   -fuse-ld=lld \
 // RUN:   -nostdlib
-// RUN: llvm-objdump -d -r --disassemble-symbols=main %t.exe \
-// RUN:   | FileCheck %s --check-prefix=CHECK-DIRECT-ACCESS
 // RUN: llvm-bolt %t.exe -o %t.bolt
 // RUN: %clang %cflags -fPIC -pie %s -o %t_pie.exe -Wl,-q \
 // RUN:   -Wl,--unresolved-symbols=ignore-all \
@@ -47,11 +40,6 @@ int main() {
 // RUN: llvm-objdump -d -r --disassemble-symbols=main %t.so | FileCheck %s
 // RUN: llvm-bolt %t.so -o %t.bolt.so
 
-// CHECK-DIRECT-ACCESS: R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC directaccess
-// CHECK-DIRECT-ACCESS-NEXT: add {{.*}} #0x1
-// CHECK-DIRECT-ACCESS-NEXT: str {{.*}}
-// CHECK-DIRECT-ACCESS-NEXT: R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC directaccess
-
 // Verify that unoptimized TLS access was generated for shared object.
 // CHECK:      adrp    x0
 // CHECK-NEXT: R_AARCH64_TLSDESC_ADR_PAGE21     tbssstruct

diff  --git a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
index ddbe7f24dc39a..f22806678211f 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp
@@ -1254,18 +1254,6 @@ static bool isWorthFoldingADDlow(SDValue N) {
   return true;
 }
 
-/// Check whether \p GAN is the low part of a TLS address computation, i.e. the
-/// second operand of an ADDlow. The target flags on their own do not tell the
-/// ELF local-exec (:tprel_lo12: and :tprel_lo12_nc:) cases apart from other
-/// uses, so callers that depend on local-exec semantics have to check the
-/// object format as well. Local dynamic never gets here because it does not
-/// build an ADDlow.
-static bool isTLSLo12(const GlobalAddressSDNode *GAN) {
-  unsigned Flags = GAN->getTargetFlags();
-  return (Flags & (AArch64II::MO_TLS | AArch64II::MO_FRAGMENT)) ==
-         (AArch64II::MO_TLS | AArch64II::MO_PAGEOFF);
-}
-
 /// Check if the immediate offset is valid as a scaled immediate.
 static bool isValidAsScaledImmediate(int64_t Offset, unsigned Range,
                                      unsigned Size) {
@@ -1361,13 +1349,8 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue N, unsigned Size,
     if (!GAN)
       return true;
 
-    // Folding the low part of an ELF local-exec TLS address into a 128-bit
-    // access needs R_AARCH64_TLSLE_LDST128_TPREL_LO12 or its NC variant, which
-    // the GNU bfd linker does not support, so keep materialising the address
-    // with an add.
     if (GAN->getOffset() % Size == 0 &&
-        GAN->getGlobal()->getPointerAlignment(DL) >= Size &&
-        !(Size > 8 && Subtarget->isTargetELF() && isTLSLo12(GAN)))
+        GAN->getGlobal()->getPointerAlignment(DL) >= Size)
       return true;
   }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 45e1788a85b62..c60d02be4c39b 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -11542,7 +11542,10 @@ SDValue AArch64TargetLowering::LowerELFTLSLocalExec(const GlobalValue *GV,
     // add   x0, x0, :tprel_lo12:a
     SDValue Var = DAG.getTargetGlobalAddress(
         GV, DL, PtrVT, 0, AArch64II::MO_TLS | AArch64II::MO_PAGEOFF);
-    return DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, ThreadBase, Var);
+    return SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, ThreadBase,
+                                      Var,
+                                      DAG.getTargetConstant(0, DL, MVT::i32)),
+                   0);
   }
 
   case 24: {
@@ -11558,10 +11561,10 @@ SDValue AArch64TargetLowering::LowerELFTLSLocalExec(const GlobalValue *GV,
                                       HiVar,
                                       DAG.getTargetConstant(0, DL, MVT::i32)),
                    0);
-    // Emit the low part as an ADDlow so that it can be folded into the
-    // addressing mode of a following load or store, turning the add into a
-    // :tprel_lo12_nc: relocation on the memory access itself.
-    return DAG.getNode(AArch64ISD::ADDlow, DL, PtrVT, Addr, LoVar);
+    return SDValue(DAG.getMachineNode(AArch64::ADDXri, DL, PtrVT, Addr,
+                                      LoVar,
+                                      DAG.getTargetConstant(0, DL, MVT::i32)),
+                   0);
   }
 
   case 32: {

diff  --git a/llvm/test/CodeGen/AArch64/arm64-tls-local-exec.ll b/llvm/test/CodeGen/AArch64/arm64-tls-local-exec.ll
index a30a441abfe1f..59d5500ce534e 100644
--- a/llvm/test/CodeGen/AArch64/arm64-tls-local-exec.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-tls-local-exec.ll
@@ -27,24 +27,24 @@
 ; RUN: llc -mtriple=arm64-none-linux-gnu -filetype=obj < %s -code-model=large | llvm-objdump -r - | FileCheck --check-prefix=CHECK-24-RELOC %s
 
 @local_exec_var = thread_local(localexec) global i32 0
- at local_exec_var64 = thread_local(localexec) global i64 0
- at vec_local_exec_var = thread_local(localexec) global <2 x i64> zeroinitializer, align 16
 
 define i32 @test_local_exec() {
 ; CHECK-LABEL: test_local_exec:
   %val = load i32, ptr @local_exec_var
 
 ; CHECK-12: mrs x[[R1:[0-9]+]], TPIDR_EL0
-; CHECK-12: ldr w0, [x[[R1]], :tprel_lo12:local_exec_var]
+; CHECK-12: add x[[R2:[0-9]+]], x[[R1]], :tprel_lo12:local_exec_var
+; CHECK-12: ldr w0, [x[[R2]]]
 
-; CHECK-12-RELOC: R_AARCH64_TLSLE_LDST32_TPREL_LO12
+; CHECK-12-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12
 
 ; CHECK-24: mrs x[[R1:[0-9]+]], TPIDR_EL0
 ; CHECK-24: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var
-; CHECK-24: ldr w0, [x[[R2]], :tprel_lo12_nc:local_exec_var]
+; CHECK-24: add x[[R3:[0-9]+]], x[[R2]], :tprel_lo12_nc:local_exec_var
+; CHECK-24: ldr w0, [x[[R3]]]
 
 ; CHECK-24-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12
-; CHECK-24-RELOC: R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
+; CHECK-24-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC
 
 ; CHECK-32: movz x[[R2:[0-9]+]], #:tprel_g1:local_exec_var
 ; CHECK-32: mrs x[[R1:[0-9]+]], TPIDR_EL0
@@ -66,24 +66,6 @@ define i32 @test_local_exec() {
   ret i32 %val
 }
 
-define void @test_local_exec_store64(i64 %val) {
-; CHECK-LABEL: test_local_exec_store64:
-  store i64 %val, ptr @local_exec_var64
-
-; CHECK-12: mrs x[[R1:[0-9]+]], TPIDR_EL0
-; CHECK-12: str x0, [x[[R1]], :tprel_lo12:local_exec_var64]
-
-; CHECK-12-RELOC: R_AARCH64_TLSLE_LDST64_TPREL_LO12
-
-; CHECK-24: mrs x[[R1:[0-9]+]], TPIDR_EL0
-; CHECK-24: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:local_exec_var64
-; CHECK-24: str x0, [x[[R2]], :tprel_lo12_nc:local_exec_var64]
-
-; CHECK-24-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12 local_exec_var64
-; CHECK-24-RELOC-NEXT: R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC local_exec_var64
-  ret void
-}
-
 define ptr @test_local_exec_addr() {
 ; CHECK-LABEL: test_local_exec_addr:
   ret ptr @local_exec_var
@@ -122,26 +104,3 @@ define ptr @test_local_exec_addr() {
 ; CHECK-48-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G1_NC
 ; CHECK-48-RELOC: R_AARCH64_TLSLE_MOVW_TPREL_G0_NC
 }
-
-; A 128-bit access would need R_AARCH64_TLSLE_LDST128_TPREL_LO12 or its NC
-; variant, which not every linker implements, so the low part stays in a
-; separate add.
-define <2 x i64> @test_local_exec_128bit() {
-; CHECK-LABEL: test_local_exec_128bit:
-  %val = load <2 x i64>, ptr @vec_local_exec_var
-
-; CHECK-12: mrs x[[R1:[0-9]+]], TPIDR_EL0
-; CHECK-12: add x[[R2:[0-9]+]], x[[R1]], :tprel_lo12:vec_local_exec_var
-; CHECK-12: ldr q0, [x[[R2]]]
-
-; CHECK-12-RELOC: R_AARCH64_TLSLE_ADD_TPREL_LO12 vec_local_exec_var
-
-; CHECK-24: mrs x[[R1:[0-9]+]], TPIDR_EL0
-; CHECK-24: add x[[R2:[0-9]+]], x[[R1]], :tprel_hi12:vec_local_exec_var
-; CHECK-24: add x[[R3:[0-9]+]], x[[R2]], :tprel_lo12_nc:vec_local_exec_var
-; CHECK-24: ldr q0, [x[[R3]]]
-
-; CHECK-24-RELOC: R_AARCH64_TLSLE_ADD_TPREL_HI12 vec_local_exec_var
-; CHECK-24-RELOC-NEXT: R_AARCH64_TLSLE_ADD_TPREL_LO12_NC vec_local_exec_var
-  ret <2 x i64> %val
-}

diff  --git a/llvm/test/CodeGen/AArch64/win-tls.ll b/llvm/test/CodeGen/AArch64/win-tls.ll
index f184ad74a9e25..e448282b7c4cf 100644
--- a/llvm/test/CodeGen/AArch64/win-tls.ll
+++ b/llvm/test/CodeGen/AArch64/win-tls.ll
@@ -3,7 +3,6 @@
 @tlsVar = thread_local global i32 0
 @tlsVar8 = thread_local global i8 0
 @tlsVar64 = thread_local global i64 0
- at tlsVar128 = thread_local global <2 x i64> zeroinitializer
 
 define i32 @getVar() {
   %1 = load i32, ptr @tlsVar
@@ -29,11 +28,6 @@ define i64 @getVar64() {
   ret i64 %1
 }
 
-define <2 x i64> @getVar128() {
-  %1 = load <2 x i64>, ptr @tlsVar128
-  ret <2 x i64> %1
-}
-
 ; CHECK-LABEL: getVar
 ; CHECK: adrp [[TLS_INDEX_ADDR:x[0-9]+]], _tls_index
 ; CHECK: ldr [[TLS_POINTER:x[0-9]+]], [x18, #88]
@@ -68,7 +62,3 @@ define <2 x i64> @getVar128() {
 ; CHECK-LABEL: getVar64
 ; CHECK: add [[TLS:x[0-9]+]], [[TLS]], :secrel_hi12:tlsVar64
 ; CHECK: ldr x0, [[[TLS]], :secrel_lo12:tlsVar64]
-
-; CHECK-LABEL: getVar128
-; CHECK: add [[TLS:x[0-9]+]], [[TLS]], :secrel_hi12:tlsVar128
-; CHECK: ldr q0, [[[TLS]], :secrel_lo12:tlsVar128]


        


More information about the llvm-branch-commits mailing list