[llvm-branch-commits] [lld] [lld][LoongArch] Relax TLSDESC code sequence. (PR #123677)

Zhaoxin Yang via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Jan 20 16:39:36 PST 2025


https://github.com/ylzsx created https://github.com/llvm/llvm-project/pull/123677

Relax TLSDESC code sequence.

Original code sequence:
  * pcalau12i  $a0, %desc_pc_hi20(sym_desc)
  * addi.d     $a0, $a0, %desc_pc_lo12(sym_desc)
  * ld.d       $ra, $a0, %desc_ld(sym_desc)
  * jirl       $ra, $ra, %desc_call(sym_desc)

Cannot convert to LE/IE, but relax:
  * pcaddi     $a0, %desc_pcrel_20(sym_desc)
  * ld.d       $ra, $a0, %desc_ld(sym_desc)
  * jirl       $ra, $ra, %desc_call(sym_desc)

FIXME: The conversion of TLSDESC GD/LD to LE/IE will implement in a future patch.

>From 56c24f9746ef42c449a4d1d5caf10f7cd1dd7d81 Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Tue, 31 Dec 2024 15:51:43 +0800
Subject: [PATCH 1/6] Relax TLSDESC code sequence.

Original code sequence:
 * pcalau12i  $a0, %desc_pc_hi20(sym_desc)
 * addi.d     $a0, $a0, %desc_pc_lo12(sym_desc)
 * ld.d       $ra, $a0, %desc_ld(sym_desc)
 * jirl       $ra, $ra, %desc_call(sym_desc)

Cannot convert to LE/IE, but relax:
 * pcaddi     $a0, %desc_pcrel_20(sym_desc)
 * ld.d       $ra, $a0, %desc_ld(sym_desc)
 * jirl       $ra, $ra, %desc_call(sym_desc)

FIXME: The conversion of TLSDESC GD/LD to LE/IE will implement in a
future patch.
---
 lld/ELF/Arch/LoongArch.cpp | 44 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 2d6d86d2ca63b2..a6db15bbf1efd4 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -782,7 +782,9 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
         (rHi20.type == R_LARCH_TLS_GD_PC_HI20 &&
          rLo12.type == R_LARCH_GOT_PC_LO12) ||
         (rHi20.type == R_LARCH_TLS_LD_PC_HI20 &&
-         rLo12.type == R_LARCH_GOT_PC_LO12)))
+         rLo12.type == R_LARCH_GOT_PC_LO12) ||
+        (rHi20.type == R_LARCH_TLS_DESC_PC_HI20 &&
+         rLo12.type == R_LARCH_TLS_DESC_PC_LO12)))
     return;
 
   // GOT references to absolute symbols can't be relaxed to use pcaddi in
@@ -804,6 +806,8 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
     symBase = rHi20.sym->getVA(ctx);
   else if (rHi20.expr == RE_LOONGARCH_TLSGD_PAGE_PC)
     symBase = ctx.in.got->getGlobalDynAddr(*rHi20.sym);
+  else if (rHi20.expr == RE_LOONGARCH_TLSDESC_PAGE_PC)
+    symBase = ctx.in.got->getTlsDescAddr(*rHi20.sym);
   else {
     Err(ctx) << getErrorLoc(ctx, (const uint8_t *)loc) << "unknown expr ("
              << rHi20.expr << ") against symbol " << rHi20.sym
@@ -837,6 +841,8 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
     sec.relaxAux->relocTypes[i + 2] = R_LARCH_TLS_GD_PCREL20_S2;
   else if (rHi20.type == R_LARCH_TLS_LD_PC_HI20)
     sec.relaxAux->relocTypes[i + 2] = R_LARCH_TLS_LD_PCREL20_S2;
+  else if (rHi20.type == R_LARCH_TLS_DESC_PC_HI20)
+    sec.relaxAux->relocTypes[i + 2] = R_LARCH_TLS_DESC_PCREL20_S2;
   else
     sec.relaxAux->relocTypes[i + 2] = R_LARCH_PCREL20_S2;
   sec.relaxAux->writes.push_back(insn(PCADDI, getD5(nextInsn), 0, 0));
@@ -903,6 +909,33 @@ static void relaxTlsLe(Ctx &ctx, const InputSection &sec, size_t i,
   }
 }
 
+// Relax TLSDESC code sequence. In LoongArch, the conversion of TLSDESC GD/LD to
+// LE/IE is closely tied to relaxation, similar to how GCC handles it. (Due to
+// the lack of an efficient way for handling conversions in the extreme code
+// model and the difficulty in determining whether the extreme code model is
+// being used in handleTlsRelocation, this approach may seem like a workaround).
+// Consequently, the resulting code sequence depends on whether the conversion
+// to LE/IE is performed.
+//
+// Original code sequence:
+//  * pcalau12i  $a0, %desc_pc_hi20(sym_desc)
+//  * addi.d     $a0, $a0, %desc_pc_lo12(sym_desc)
+//  * ld.d       $ra, $a0, %desc_ld(sym_desc)
+//  * jirl       $ra, $ra, %desc_call(sym_desc)
+//
+// Cannot convert to LE/IE, but relax:
+//  * pcaddi     $a0, %desc_pcrel_20(sym_desc)
+//  * ld.d       $ra, $a0, %desc_ld(sym_desc)
+//  * jirl       $ra, $ra, %desc_call(sym_desc)
+//
+// FIXME: Implement TLSDESC GD/LD to LE/IE.
+static void relaxTlsdesc(Ctx &ctx, const InputSection &sec, size_t i,
+                         uint64_t loc, Relocation &rHi20, Relocation &rLo12,
+                         uint32_t &remove) {
+  if (ctx.arg.shared && rHi20.type == R_LARCH_TLS_DESC_PC_HI20)
+    return relaxPCHi20Lo12(ctx, sec, i, loc, rHi20, rLo12, remove);
+}
+
 static bool relax(Ctx &ctx, InputSection &sec) {
   const uint64_t secAddr = sec.getVA();
   const MutableArrayRef<Relocation> relocs = sec.relocs();
@@ -959,6 +992,10 @@ static bool relax(Ctx &ctx, InputSection &sec) {
       if (relaxable(relocs, i))
         relaxTlsLe(ctx, sec, i, loc, r, remove);
       break;
+    case R_LARCH_TLS_DESC_PC_HI20:
+      if (isPairRelaxable(relocs, i))
+        relaxTlsdesc(ctx, sec, i, loc, r, relocs[i + 2], remove);
+      break;
     }
 
     // For all anchors whose offsets are <= r.offset, they are preceded by
@@ -1078,6 +1115,11 @@ void LoongArch::finalizeRelax(int passes) const {
             write32le(p, aux.writes[writesIdx++]);
             r.expr = R_TLSGD_PC;
             break;
+          case R_LARCH_TLS_DESC_PCREL20_S2:
+            skip = 4;
+            write32le(p, aux.writes[writesIdx++]);
+            r.expr = R_TLSDESC_PC;
+            break;
           default:
             llvm_unreachable("unsupported type");
           }

>From 880523cdb13c1a1216cbdd08faf3180e79587110 Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Tue, 31 Dec 2024 22:30:40 +0800
Subject: [PATCH 2/6] Add test loongarch-relax-tlsdesc.s

---
 lld/test/ELF/loongarch-relax-tlsdesc.s | 189 +++++++++++++++++++++++++
 1 file changed, 189 insertions(+)
 create mode 100644 lld/test/ELF/loongarch-relax-tlsdesc.s

diff --git a/lld/test/ELF/loongarch-relax-tlsdesc.s b/lld/test/ELF/loongarch-relax-tlsdesc.s
new file mode 100644
index 00000000000000..6470bdf35cb223
--- /dev/null
+++ b/lld/test/ELF/loongarch-relax-tlsdesc.s
@@ -0,0 +1,189 @@
+# REQUIRES: loongarch
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.64.o
+# RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax c.s -o c.64.o
+# RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so
+# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax --defsym ELF32=1 a.s -o a.32.o
+# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax --defsym ELF32=1 c.s -o c.32.o
+# RUN: ld.lld -shared -soname=c.32.so c.32.o -o c.32.so
+
+## Test the TLSDESC relaxation. Also check --emit-relocs.
+# RUN: ld.lld -shared --emit-relocs -z now a.64.o c.64.o -o a.64.so
+# RUN: llvm-readobj -r -x .got a.64.so | FileCheck --check-prefix=GD64-RELA %s
+# RUN: llvm-objdump --no-show-raw-insn -dr a.64.so | FileCheck %s --check-prefix=GD64
+
+## FIXME: The transition frome TLSDESC to IE/LE has not yet been implemented.
+## Keep the dynamic relocations and hand them over to dynamic linker.
+
+# RUN: ld.lld -e 0 -z now --emit-relocs a.64.o c.64.o -o a.64.le
+# RUN: llvm-readobj -r -x .got a.64.le | FileCheck --check-prefix=LE64-RELA %s
+# RUN: llvm-objdump --no-show-raw-insn -d a.64.le | FileCheck %s --check-prefix=LE64
+
+# RUN: ld.lld -e 0 -z now --emit-relocs a.64.o c.64.so -o a.64.ie
+# RUN: llvm-readobj -r -x .got a.64.ie | FileCheck --check-prefix=IE64-RELA %s
+# RUN: llvm-objdump --no-show-raw-insn -d a.64.ie | FileCheck %s --check-prefix=IE64
+
+## 32-bit code is mostly the same. We only test a few variants.
+
+# RUN: ld.lld -shared -z now a.32.o c.32.o -o rel.32.so -z rel
+# RUN: llvm-readobj -r -x .got rel.32.so | FileCheck --check-prefix=GD32-REL %s
+
+# GD64-RELA:      .rela.dyn {
+# GD64-RELA-NEXT:   0x20448 R_LARCH_TLS_DESC64 - 0x7FF
+# GD64-RELA-NEXT:   0x20418 R_LARCH_TLS_DESC64 a 0x0
+# GD64-RELA-NEXT:   0x20428 R_LARCH_TLS_DESC64 c 0x0
+# GD64-RELA-NEXT:   0x20438 R_LARCH_TLS_DESC64 d 0x0
+# GD64-RELA-NEXT: }
+# GD64-RELA:      Hex dump of section '.got':
+# GD64-RELA-NEXT: 0x00020418 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020428 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020438 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020448 00000000 00000000 00000000 00000000 .
+
+## &.got[a]-. = 0x20418 - 0x10318 = 16448<<2
+# GD64:        10318: pcaddi  $a0, 16448
+# GD64-NEXT:          ld.d    $ra, $a0, 0
+# GD64-NEXT:          jirl    $ra, $ra, 0
+# GD64-NEXT:          add.d   $a1, $a0, $tp
+
+## &.got[b]-. = 0x20418+48 - 0x10328 = 16456<<2
+# GD64:        10328: pcaddi  $a0, 16456
+# GD64-NEXT:          ld.d    $ra, $a0, 0
+# GD64-NEXT:          jirl    $ra, $ra, 0
+# GD64-NEXT:          add.d   $a2, $a0, $tp
+
+## &.got[c]-. = 0x20418+16 - 0x10338 = 16444<<2
+# GD64:        10338: pcaddi  $a0, 16
+# GD64-NEXT:          ld.d    $ra, $a0, 0
+# GD64-NEXT:          jirl    $ra, $ra, 0
+# GD64-NEXT:          add.d   $a3, $a0, $tp
+
+## &.got[d]-. = 0x20418+32 - 0x10348 = 16444<<2
+# GD64:        10348: pcaddi  $a0, 16444
+# GD64-NEXT:          ld.d    $ra, $a0, 0
+# GD64-NEXT:          jirl    $ra, $ra, 0
+# GD64-NEXT:          add.d   $a4, $a0, $tp
+
+# LE64-RELA:      .rela.dyn {
+# LE64-RELA-NEXT:   0x30278 R_LARCH_TLS_DESC64 - 0x8
+# LE64-RELA-NEXT:   0x30288 R_LARCH_TLS_DESC64 - 0x800
+# LE64-RELA-NEXT:   0x30298 R_LARCH_TLS_DESC64 - 0x1000
+# LE64-RELA-NEXT:   0x302A8 R_LARCH_TLS_DESC64 - 0x7FF
+# LE64-RELA-NEXT: }
+# LE64-RELA:      Hex dump of section '.got':
+# LE64-RELA-NEXT: 0x00030278 00000000 00000000 00000000 00000000 .
+# LE64-RELA-NEXT: 0x00030288 00000000 00000000 00000000 00000000 .
+# LE64-RELA-NEXT: 0x00030298 00000000 00000000 00000000 00000000 .
+# LE64-RELA-NEXT: 0x000302a8 00000000 00000000 00000000 00000000 .
+
+# LE64-LABEL: <.text>:
+## &.got[a]-. = 0x30278 - 0x20228: 0x10 pages, page offset 0x278
+# LE64-NEXT:   20228: pcalau12i $a0, 16
+# LE64-NEXT:          addi.d    $a0, $a0, 632
+# LE64-NEXT:          ld.d      $ra, $a0, 0
+# LE64-NEXT:          jirl      $ra, $ra, 0
+# LE64-NEXT:          add.d     $a1, $a0, $tp
+## &.got[b]-. = 0x302a8 - 0x2023c: 0x10 pages, page offset 0x2a8
+# LE64-NEXT:   2023c: pcalau12i $a0, 16
+# LE64-NEXT:          addi.d    $a0, $a0, 680
+# LE64-NEXT:          ld.d      $ra, $a0, 0
+# LE64-NEXT:          jirl      $ra, $ra, 0
+# LE64-NEXT:          add.d     $a2, $a0, $tp
+## &.got[c]-. = 0x30288 - 0x20250: 0x10 pages, page offset 0x288
+# LE64-NEXT:   20250: pcalau12i $a0, 16
+# LE64-NEXT:          addi.d    $a0, $a0, 648
+# LE64-NEXT:          ld.d      $ra, $a0, 0
+# LE64-NEXT:          jirl      $ra, $ra, 0
+# LE64-NEXT:          add.d     $a3, $a0, $tp
+## &.got[d]-. = 0x30298 - 0x20264: 0x10 pages, page offset 0x298
+# LE64-NEXT:   20264: pcalau12i $a0, 16
+# LE64-NEXT:          addi.d    $a0, $a0, 664
+# LE64-NEXT:          ld.d      $ra, $a0, 0
+# LE64-NEXT:          jirl      $ra, $ra, 0
+# LE64-NEXT:          add.d     $a4, $a0, $tp
+
+# IE64-RELA:      .rela.dyn {
+# IE64-RELA-NEXT:   0x30428 R_LARCH_TLS_DESC64 - 0x8
+# IE64-RELA-NEXT:   0x30458 R_LARCH_TLS_DESC64 - 0x7FF
+# IE64-RELA-NEXT:   0x30438 R_LARCH_TLS_DESC64 c 0x0
+# IE64-RELA-NEXT:   0x30448 R_LARCH_TLS_DESC64 d 0x0
+# IE64-RELA-NEXT: }
+# IE64-RELA:      Hex dump of section '.got':
+# IE64-RELA-NEXT: 0x00030428 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030438 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030448 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030458 00000000 00000000 00000000 00000000 .
+
+## a and b are optimized to use LE. c and d are optimized to IE.
+# IE64-LABEL: <.text>:
+## &.got[a]-. = 0x30428 - 0x202f8: 0x10 pages, page offset 0x428
+# IE64-NEXT:   202f8: pcalau12i $a0, 16
+# IE64-NEXT:          addi.d    $a0, $a0, 1064
+# IE64-NEXT:          ld.d      $ra, $a0, 0
+# IE64-NEXT:          jirl      $ra, $ra, 0
+# IE64-NEXT:          add.d     $a1, $a0, $tp
+## &.got[b]-. = 0x30458 - 0x2030c: 0x10 pages, page offset 0x458
+# IE64-NEXT:   2030c: pcalau12i $a0, 16
+# IE64-NEXT:          addi.d    $a0, $a0, 1112
+# IE64-NEXT:          ld.d      $ra, $a0, 0
+# IE64-NEXT:          jirl      $ra, $ra, 0
+# IE64-NEXT:          add.d     $a2, $a0, $tp
+## &.got[c]-. = 0x30438 - 0x20320: 0x10 pages, page offset 0x438
+# IE64-NEXT:   20320: pcalau12i $a0, 16
+# IE64-NEXT:          addi.d    $a0, $a0, 1080
+# IE64-NEXT:          ld.d      $ra, $a0, 0
+# IE64-NEXT:          jirl      $ra, $ra, 0
+# IE64-NEXT:          add.d     $a3, $a0, $tp
+## &.got[d]-. = 0x30448 - 0x20334: 0x10 pages, page offset 0x448
+# IE64-NEXT:   20334: pcalau12i $a0, 16
+# IE64-NEXT:          addi.d    $a0, $a0, 1096
+# IE64-NEXT:          ld.d      $ra, $a0, 0
+# IE64-NEXT:          jirl      $ra, $ra, 0
+# IE64-NEXT:          add.d     $a4, $a0, $tp
+
+# GD32-REL:      .rel.dyn {
+# GD32-REL-NEXT:    0x202A4 R_LARCH_TLS_DESC32 -
+# GD32-REL-NEXT:    0x2028C R_LARCH_TLS_DESC32 a
+# GD32-REL-NEXT:    0x20294 R_LARCH_TLS_DESC32 c
+# GD32-REL-NEXT:    0x2029C R_LARCH_TLS_DESC32 d
+# GD32-REL-NEXT: }
+# GD32-REL:      Hex dump of section '.got':
+# GD32-REL-NEXT: 0x0002028c 00000000 00000000 00000000 00000000 .
+# GD32-REL-NEXT: 0x0002029c 00000000 00000000 00000000 ff070000 .
+
+#--- a.s
+.macro add dst, src1, src2
+.ifdef ELF32
+add.w \dst, \src1, \src2
+.else
+add.d \dst, \src1, \src2
+.endif
+.endm
+
+la.tls.desc $a0, a
+add $a1, $a0, $tp
+
+la.tls.desc $a0, b
+add $a2, $a0, $tp
+
+la.tls.desc $a0, c
+add $a3, $a0, $tp
+
+la.tls.desc $a0, d
+add $a4, $a0, $tp
+
+.section .tbss,"awT", at nobits
+.globl a
+.zero 8
+a:
+.zero 2039  ## Place b at 0x7ff
+b:
+.zero 1
+
+#--- c.s
+.section .tbss,"awT", at nobits
+.globl c, d
+c:
+.zero 2048  ## Place d at 0x1000
+d:
+.zero 4

>From a48a2b989d747754b0aa33f4f8d0f13a7e7c696c Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Thu, 2 Jan 2025 08:48:52 +0800
Subject: [PATCH 3/6] Relax desc_pc_hi20+desc_pc_lo12 ==> desc_pcrel_20

---
 lld/ELF/Arch/LoongArch.cpp             | 37 +++-------------
 lld/test/ELF/loongarch-relax-tlsdesc.s | 60 +++++++++++---------------
 2 files changed, 31 insertions(+), 66 deletions(-)

diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index a6db15bbf1efd4..ec09437404eddc 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -762,9 +762,12 @@ static bool isPairRelaxable(ArrayRef<Relocation> relocs, size_t i) {
 // Relax code sequence.
 // From:
 //   pcalau12i     $a0, %pc_hi20(sym) | %ld_pc_hi20(sym)  | %gd_pc_hi20(sym)
+//                    | %desc_pc_hi20(sym)
 //   addi.w/d $a0, $a0, %pc_lo12(sym) | %got_pc_lo12(sym) | %got_pc_lo12(sym)
+//                    | %desc_pc_lo12(sym)
 // To:
-//   pcaddi $a0, %pc_lo12(sym) | %got_pc_lo12(sym) | %got_pc_lo12(sym)
+//   pcaddi        $a0, %pc_lo12(sym) | %got_pc_lo12(sym) | %got_pc_lo12(sym)
+//                    | %desc_pcrel_20(sym)
 //
 // From:
 //   pcalau12i $a0, %got_pc_hi20(sym_got)
@@ -909,33 +912,6 @@ static void relaxTlsLe(Ctx &ctx, const InputSection &sec, size_t i,
   }
 }
 
-// Relax TLSDESC code sequence. In LoongArch, the conversion of TLSDESC GD/LD to
-// LE/IE is closely tied to relaxation, similar to how GCC handles it. (Due to
-// the lack of an efficient way for handling conversions in the extreme code
-// model and the difficulty in determining whether the extreme code model is
-// being used in handleTlsRelocation, this approach may seem like a workaround).
-// Consequently, the resulting code sequence depends on whether the conversion
-// to LE/IE is performed.
-//
-// Original code sequence:
-//  * pcalau12i  $a0, %desc_pc_hi20(sym_desc)
-//  * addi.d     $a0, $a0, %desc_pc_lo12(sym_desc)
-//  * ld.d       $ra, $a0, %desc_ld(sym_desc)
-//  * jirl       $ra, $ra, %desc_call(sym_desc)
-//
-// Cannot convert to LE/IE, but relax:
-//  * pcaddi     $a0, %desc_pcrel_20(sym_desc)
-//  * ld.d       $ra, $a0, %desc_ld(sym_desc)
-//  * jirl       $ra, $ra, %desc_call(sym_desc)
-//
-// FIXME: Implement TLSDESC GD/LD to LE/IE.
-static void relaxTlsdesc(Ctx &ctx, const InputSection &sec, size_t i,
-                         uint64_t loc, Relocation &rHi20, Relocation &rLo12,
-                         uint32_t &remove) {
-  if (ctx.arg.shared && rHi20.type == R_LARCH_TLS_DESC_PC_HI20)
-    return relaxPCHi20Lo12(ctx, sec, i, loc, rHi20, rLo12, remove);
-}
-
 static bool relax(Ctx &ctx, InputSection &sec) {
   const uint64_t secAddr = sec.getVA();
   const MutableArrayRef<Relocation> relocs = sec.relocs();
@@ -978,6 +954,7 @@ static bool relax(Ctx &ctx, InputSection &sec) {
     case R_LARCH_GOT_PC_HI20:
     case R_LARCH_TLS_GD_PC_HI20:
     case R_LARCH_TLS_LD_PC_HI20:
+    case R_LARCH_TLS_DESC_PC_HI20:
       // The overflow check for i+2 will be carried out in isPairRelaxable.
       if (isPairRelaxable(relocs, i))
         relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove);
@@ -992,10 +969,6 @@ static bool relax(Ctx &ctx, InputSection &sec) {
       if (relaxable(relocs, i))
         relaxTlsLe(ctx, sec, i, loc, r, remove);
       break;
-    case R_LARCH_TLS_DESC_PC_HI20:
-      if (isPairRelaxable(relocs, i))
-        relaxTlsdesc(ctx, sec, i, loc, r, relocs[i + 2], remove);
-      break;
     }
 
     // For all anchors whose offsets are <= r.offset, they are preceded by
diff --git a/lld/test/ELF/loongarch-relax-tlsdesc.s b/lld/test/ELF/loongarch-relax-tlsdesc.s
index 6470bdf35cb223..f9f509d8d93f90 100644
--- a/lld/test/ELF/loongarch-relax-tlsdesc.s
+++ b/lld/test/ELF/loongarch-relax-tlsdesc.s
@@ -65,78 +65,70 @@
 # GD64-NEXT:          add.d   $a4, $a0, $tp
 
 # LE64-RELA:      .rela.dyn {
-# LE64-RELA-NEXT:   0x30278 R_LARCH_TLS_DESC64 - 0x8
-# LE64-RELA-NEXT:   0x30288 R_LARCH_TLS_DESC64 - 0x800
-# LE64-RELA-NEXT:   0x30298 R_LARCH_TLS_DESC64 - 0x1000
-# LE64-RELA-NEXT:   0x302A8 R_LARCH_TLS_DESC64 - 0x7FF
+# LE64-RELA-NEXT:   0x30268 R_LARCH_TLS_DESC64 - 0x8
+# LE64-RELA-NEXT:   0x30278 R_LARCH_TLS_DESC64 - 0x800
+# LE64-RELA-NEXT:   0x30288 R_LARCH_TLS_DESC64 - 0x1000
+# LE64-RELA-NEXT:   0x30298 R_LARCH_TLS_DESC64 - 0x7FF
 # LE64-RELA-NEXT: }
 # LE64-RELA:      Hex dump of section '.got':
+# LE64-RELA-NEXT: 0x00030268 00000000 00000000 00000000 00000000 .
 # LE64-RELA-NEXT: 0x00030278 00000000 00000000 00000000 00000000 .
 # LE64-RELA-NEXT: 0x00030288 00000000 00000000 00000000 00000000 .
 # LE64-RELA-NEXT: 0x00030298 00000000 00000000 00000000 00000000 .
-# LE64-RELA-NEXT: 0x000302a8 00000000 00000000 00000000 00000000 .
 
 # LE64-LABEL: <.text>:
-## &.got[a]-. = 0x30278 - 0x20228: 0x10 pages, page offset 0x278
-# LE64-NEXT:   20228: pcalau12i $a0, 16
-# LE64-NEXT:          addi.d    $a0, $a0, 632
+## &.got[a]-. = 0x30268 - 0x20228 = 16400<<2
+# LE64-NEXT:   20228: pcaddi    $a0, 16400
 # LE64-NEXT:          ld.d      $ra, $a0, 0
 # LE64-NEXT:          jirl      $ra, $ra, 0
 # LE64-NEXT:          add.d     $a1, $a0, $tp
-## &.got[b]-. = 0x302a8 - 0x2023c: 0x10 pages, page offset 0x2a8
-# LE64-NEXT:   2023c: pcalau12i $a0, 16
-# LE64-NEXT:          addi.d    $a0, $a0, 680
+## &.got[b]-. = 0x30298 - 0x20238 = 16408<<2
+# LE64-NEXT:   20238: pcaddi    $a0, 16408
 # LE64-NEXT:          ld.d      $ra, $a0, 0
 # LE64-NEXT:          jirl      $ra, $ra, 0
 # LE64-NEXT:          add.d     $a2, $a0, $tp
-## &.got[c]-. = 0x30288 - 0x20250: 0x10 pages, page offset 0x288
-# LE64-NEXT:   20250: pcalau12i $a0, 16
-# LE64-NEXT:          addi.d    $a0, $a0, 648
+## &.got[c]-. = 0x30278 - 0x20248 = 16396<<2
+# LE64-NEXT:   20248: pcaddi    $a0, 16396
 # LE64-NEXT:          ld.d      $ra, $a0, 0
 # LE64-NEXT:          jirl      $ra, $ra, 0
 # LE64-NEXT:          add.d     $a3, $a0, $tp
-## &.got[d]-. = 0x30298 - 0x20264: 0x10 pages, page offset 0x298
-# LE64-NEXT:   20264: pcalau12i $a0, 16
-# LE64-NEXT:          addi.d    $a0, $a0, 664
+## &.got[d]-. = 0x30288 - 0x20258 = 16396<<2
+# LE64-NEXT:   20258: pcaddi    $a0, 16396
 # LE64-NEXT:          ld.d      $ra, $a0, 0
 # LE64-NEXT:          jirl      $ra, $ra, 0
 # LE64-NEXT:          add.d     $a4, $a0, $tp
 
 # IE64-RELA:      .rela.dyn {
-# IE64-RELA-NEXT:   0x30428 R_LARCH_TLS_DESC64 - 0x8
-# IE64-RELA-NEXT:   0x30458 R_LARCH_TLS_DESC64 - 0x7FF
-# IE64-RELA-NEXT:   0x30438 R_LARCH_TLS_DESC64 c 0x0
-# IE64-RELA-NEXT:   0x30448 R_LARCH_TLS_DESC64 d 0x0
+# IE64-RELA-NEXT:   0x30418 R_LARCH_TLS_DESC64 - 0x8
+# IE64-RELA-NEXT:   0x30448 R_LARCH_TLS_DESC64 - 0x7FF
+# IE64-RELA-NEXT:   0x30428 R_LARCH_TLS_DESC64 c 0x0
+# IE64-RELA-NEXT:   0x30438 R_LARCH_TLS_DESC64 d 0x0
 # IE64-RELA-NEXT: }
 # IE64-RELA:      Hex dump of section '.got':
+# IE64-RELA-NEXT: 0x00030418 00000000 00000000 00000000 00000000 .
 # IE64-RELA-NEXT: 0x00030428 00000000 00000000 00000000 00000000 .
 # IE64-RELA-NEXT: 0x00030438 00000000 00000000 00000000 00000000 .
 # IE64-RELA-NEXT: 0x00030448 00000000 00000000 00000000 00000000 .
-# IE64-RELA-NEXT: 0x00030458 00000000 00000000 00000000 00000000 .
 
 ## a and b are optimized to use LE. c and d are optimized to IE.
 # IE64-LABEL: <.text>:
-## &.got[a]-. = 0x30428 - 0x202f8: 0x10 pages, page offset 0x428
-# IE64-NEXT:   202f8: pcalau12i $a0, 16
-# IE64-NEXT:          addi.d    $a0, $a0, 1064
+## &.got[a]-. = 0x30418 - 0x202f8 = 16456<<2
+# IE64-NEXT:   202f8: pcaddi    $a0, 16456
 # IE64-NEXT:          ld.d      $ra, $a0, 0
 # IE64-NEXT:          jirl      $ra, $ra, 0
 # IE64-NEXT:          add.d     $a1, $a0, $tp
-## &.got[b]-. = 0x30458 - 0x2030c: 0x10 pages, page offset 0x458
-# IE64-NEXT:   2030c: pcalau12i $a0, 16
-# IE64-NEXT:          addi.d    $a0, $a0, 1112
+## &.got[b]-. = 0x30448 - 0x20308 = 16464<<2
+# IE64-NEXT:   20308: pcaddi    $a0, 16464
 # IE64-NEXT:          ld.d      $ra, $a0, 0
 # IE64-NEXT:          jirl      $ra, $ra, 0
 # IE64-NEXT:          add.d     $a2, $a0, $tp
-## &.got[c]-. = 0x30438 - 0x20320: 0x10 pages, page offset 0x438
-# IE64-NEXT:   20320: pcalau12i $a0, 16
-# IE64-NEXT:          addi.d    $a0, $a0, 1080
+## &.got[c]-. = 0x30428 - 0x20318 = 16452<<2
+# IE64-NEXT:   20318: pcaddi    $a0, 16452
 # IE64-NEXT:          ld.d      $ra, $a0, 0
 # IE64-NEXT:          jirl      $ra, $ra, 0
 # IE64-NEXT:          add.d     $a3, $a0, $tp
-## &.got[d]-. = 0x30448 - 0x20334: 0x10 pages, page offset 0x448
-# IE64-NEXT:   20334: pcalau12i $a0, 16
-# IE64-NEXT:          addi.d    $a0, $a0, 1096
+## &.got[d]-. = 0x30438 - 0x20328 = 16452<<2
+# IE64-NEXT:   20328: pcaddi    $a0, 16452
 # IE64-NEXT:          ld.d      $ra, $a0, 0
 # IE64-NEXT:          jirl      $ra, $ra, 0
 # IE64-NEXT:          add.d     $a4, $a0, $tp

>From 576773c8e2c67bc89cd653f3a52b894446ef590e Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Sat, 4 Jan 2025 09:47:34 +0800
Subject: [PATCH 4/6] Modify test loongarch-relax-tlsdesc.s

---
 lld/test/ELF/loongarch-relax-tlsdesc.s | 319 ++++++++++++++++---------
 1 file changed, 209 insertions(+), 110 deletions(-)

diff --git a/lld/test/ELF/loongarch-relax-tlsdesc.s b/lld/test/ELF/loongarch-relax-tlsdesc.s
index f9f509d8d93f90..6561066ebeb5ca 100644
--- a/lld/test/ELF/loongarch-relax-tlsdesc.s
+++ b/lld/test/ELF/loongarch-relax-tlsdesc.s
@@ -3,166 +3,265 @@
 # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.64.o
 # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax c.s -o c.64.o
 # RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so
-# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax --defsym ELF32=1 a.s -o a.32.o
-# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax --defsym ELF32=1 c.s -o c.32.o
-# RUN: ld.lld -shared -soname=c.32.so c.32.o -o c.32.so
 
 ## Test the TLSDESC relaxation. Also check --emit-relocs.
 # RUN: ld.lld -shared --emit-relocs -z now a.64.o c.64.o -o a.64.so
 # RUN: llvm-readobj -r -x .got a.64.so | FileCheck --check-prefix=GD64-RELA %s
-# RUN: llvm-objdump --no-show-raw-insn -dr a.64.so | FileCheck %s --check-prefix=GD64
+# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.so | FileCheck %s --check-prefix=GD64
 
 ## FIXME: The transition frome TLSDESC to IE/LE has not yet been implemented.
 ## Keep the dynamic relocations and hand them over to dynamic linker.
 
 # RUN: ld.lld -e 0 -z now --emit-relocs a.64.o c.64.o -o a.64.le
 # RUN: llvm-readobj -r -x .got a.64.le | FileCheck --check-prefix=LE64-RELA %s
-# RUN: llvm-objdump --no-show-raw-insn -d a.64.le | FileCheck %s --check-prefix=LE64
+# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.le | FileCheck %s --check-prefix=LE64
+
+# RUN: ld.lld -e 0 -z now --no-relax a.64.o c.64.o -o a.64.le.norelax
+# RUN: llvm-objdump --no-show-raw-insn -d -h a.64.le.norelax | FileCheck %s --check-prefix=LE64-NORELAX
 
 # RUN: ld.lld -e 0 -z now --emit-relocs a.64.o c.64.so -o a.64.ie
 # RUN: llvm-readobj -r -x .got a.64.ie | FileCheck --check-prefix=IE64-RELA %s
-# RUN: llvm-objdump --no-show-raw-insn -d a.64.ie | FileCheck %s --check-prefix=IE64
-
-## 32-bit code is mostly the same. We only test a few variants.
+# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.ie | FileCheck %s --check-prefix=IE64
 
-# RUN: ld.lld -shared -z now a.32.o c.32.o -o rel.32.so -z rel
-# RUN: llvm-readobj -r -x .got rel.32.so | FileCheck --check-prefix=GD32-REL %s
+# RUN: ld.lld -e 0 -z now --no-relax a.64.o c.64.so -o a.64.ie.norelax
+# RUN: llvm-objdump --no-show-raw-insn -d -h a.64.ie.norelax | FileCheck %s --check-prefix=IE64-NORELAX
 
 # GD64-RELA:      .rela.dyn {
-# GD64-RELA-NEXT:   0x20448 R_LARCH_TLS_DESC64 - 0x7FF
-# GD64-RELA-NEXT:   0x20418 R_LARCH_TLS_DESC64 a 0x0
-# GD64-RELA-NEXT:   0x20428 R_LARCH_TLS_DESC64 c 0x0
-# GD64-RELA-NEXT:   0x20438 R_LARCH_TLS_DESC64 d 0x0
+# GD64-RELA-NEXT:   0x20460 R_LARCH_TLS_DESC64 - 0x7FF
+# GD64-RELA-NEXT:   0x20430 R_LARCH_TLS_DESC64 a 0x0
+# GD64-RELA-NEXT:   0x20440 R_LARCH_TLS_DESC64 c 0x0
+# GD64-RELA-NEXT:   0x20450 R_LARCH_TLS_DESC64 d 0x0
 # GD64-RELA-NEXT: }
 # GD64-RELA:      Hex dump of section '.got':
-# GD64-RELA-NEXT: 0x00020418 00000000 00000000 00000000 00000000 .
-# GD64-RELA-NEXT: 0x00020428 00000000 00000000 00000000 00000000 .
-# GD64-RELA-NEXT: 0x00020438 00000000 00000000 00000000 00000000 .
-# GD64-RELA-NEXT: 0x00020448 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020430 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020440 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020450 00000000 00000000 00000000 00000000 .
+# GD64-RELA-NEXT: 0x00020460 00000000 00000000 00000000 00000000 .
+
+# GD64:   .got    00000040 0000000000020430
 
-## &.got[a]-. = 0x20418 - 0x10318 = 16448<<2
-# GD64:        10318: pcaddi  $a0, 16448
+## &.got[a]-. = 0x20430 - 0x10318 = 16454<<2
+# GD64:        10318: pcaddi  $a0, 16454
 # GD64-NEXT:          ld.d    $ra, $a0, 0
 # GD64-NEXT:          jirl    $ra, $ra, 0
 # GD64-NEXT:          add.d   $a1, $a0, $tp
 
-## &.got[b]-. = 0x20418+48 - 0x10328 = 16456<<2
-# GD64:        10328: pcaddi  $a0, 16456
+## &.got[b]-. = 0x20430+48 - 0x10328: 0x10 pages, page offset 0x460
+## R_LARCH_RELAX does not appear in pairs. No relaxation.
+# GD64:        10328: pcalau12i $a0, 16
+# GD64-NEXT:          addi.d  $a0, $a0, 1120
 # GD64-NEXT:          ld.d    $ra, $a0, 0
 # GD64-NEXT:          jirl    $ra, $ra, 0
 # GD64-NEXT:          add.d   $a2, $a0, $tp
 
-## &.got[c]-. = 0x20418+16 - 0x10338 = 16444<<2
-# GD64:        10338: pcaddi  $a0, 16
+## &.got[c]-. = 0x20430+16 - 0x1033c: 0x10 pages, page offset 0x440
+## Without R_LARCH_RELAX relocation. No relaxation.
+# GD64:        1033c: pcalau12i $a0, 16
+# GD64-NEXT:          addi.d  $t0, $zero, 0
+# GD64-NEXT:          addi.d  $a0, $a0, 1088
+# GD64-NEXT:          addi.d  $t0, $t0, 1
 # GD64-NEXT:          ld.d    $ra, $a0, 0
+# GD64-NEXT:          addi.d  $t0, $t0, 1
 # GD64-NEXT:          jirl    $ra, $ra, 0
 # GD64-NEXT:          add.d   $a3, $a0, $tp
 
-## &.got[d]-. = 0x20418+32 - 0x10348 = 16444<<2
-# GD64:        10348: pcaddi  $a0, 16444
+## &.got[d]-. = 0x20430+32 - 0x1035c = 16445<<2
+# GD64:        1035c: pcaddi  $a0, 16445
 # GD64-NEXT:          ld.d    $ra, $a0, 0
 # GD64-NEXT:          jirl    $ra, $ra, 0
 # GD64-NEXT:          add.d   $a4, $a0, $tp
 
 # LE64-RELA:      .rela.dyn {
-# LE64-RELA-NEXT:   0x30268 R_LARCH_TLS_DESC64 - 0x8
-# LE64-RELA-NEXT:   0x30278 R_LARCH_TLS_DESC64 - 0x800
-# LE64-RELA-NEXT:   0x30288 R_LARCH_TLS_DESC64 - 0x1000
-# LE64-RELA-NEXT:   0x30298 R_LARCH_TLS_DESC64 - 0x7FF
+# LE64-RELA-NEXT:   0x30280 R_LARCH_TLS_DESC64 - 0x8
+# LE64-RELA-NEXT:   0x30290 R_LARCH_TLS_DESC64 - 0x800
+# LE64-RELA-NEXT:   0x302A0 R_LARCH_TLS_DESC64 - 0x1000
+# LE64-RELA-NEXT:   0x302B0 R_LARCH_TLS_DESC64 - 0x7FF
 # LE64-RELA-NEXT: }
 # LE64-RELA:      Hex dump of section '.got':
-# LE64-RELA-NEXT: 0x00030268 00000000 00000000 00000000 00000000 .
-# LE64-RELA-NEXT: 0x00030278 00000000 00000000 00000000 00000000 .
-# LE64-RELA-NEXT: 0x00030288 00000000 00000000 00000000 00000000 .
-# LE64-RELA-NEXT: 0x00030298 00000000 00000000 00000000 00000000 .
-
-# LE64-LABEL: <.text>:
-## &.got[a]-. = 0x30268 - 0x20228 = 16400<<2
-# LE64-NEXT:   20228: pcaddi    $a0, 16400
-# LE64-NEXT:          ld.d      $ra, $a0, 0
-# LE64-NEXT:          jirl      $ra, $ra, 0
-# LE64-NEXT:          add.d     $a1, $a0, $tp
-## &.got[b]-. = 0x30298 - 0x20238 = 16408<<2
-# LE64-NEXT:   20238: pcaddi    $a0, 16408
-# LE64-NEXT:          ld.d      $ra, $a0, 0
-# LE64-NEXT:          jirl      $ra, $ra, 0
-# LE64-NEXT:          add.d     $a2, $a0, $tp
-## &.got[c]-. = 0x30278 - 0x20248 = 16396<<2
-# LE64-NEXT:   20248: pcaddi    $a0, 16396
-# LE64-NEXT:          ld.d      $ra, $a0, 0
-# LE64-NEXT:          jirl      $ra, $ra, 0
-# LE64-NEXT:          add.d     $a3, $a0, $tp
-## &.got[d]-. = 0x30288 - 0x20258 = 16396<<2
-# LE64-NEXT:   20258: pcaddi    $a0, 16396
-# LE64-NEXT:          ld.d      $ra, $a0, 0
-# LE64-NEXT:          jirl      $ra, $ra, 0
-# LE64-NEXT:          add.d     $a4, $a0, $tp
+# LE64-RELA-NEXT: 0x00030280 00000000 00000000 00000000 00000000 .
+# LE64-RELA-NEXT: 0x00030290 00000000 00000000 00000000 00000000 .
+# LE64-RELA-NEXT: 0x000302a0 00000000 00000000 00000000 00000000 .
+# LE64-RELA-NEXT: 0x000302b0 00000000 00000000 00000000 00000000 .
+
+# LE64:   .got    00000040 0000000000030280
+
+## &.got[a]-. = 0x30280 - 0x20228 = 16406<<2
+# LE64:        20228: pcaddi  $a0, 16406
+# LE64-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NEXT:          jirl    $ra, $ra, 0
+# LE64-NEXT:          add.d   $a1, $a0, $tp
+
+## &.got[b]-. = 0x30280+48 - 0x20238: 0x10 pages, page offset 0x2b0
+## R_LARCH_RELAX does not appear in pairs. No relaxation.
+# LE64:        20238: pcalau12i $a0, 16
+# LE64-NEXT:          addi.d  $a0, $a0, 688
+# LE64-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NEXT:          jirl    $ra, $ra, 0
+# LE64-NEXT:          add.d   $a2, $a0, $tp
+
+## &.got[c]-. = 0x30280+16 - 0x2024c: 0x10 pages, page offset 0x290
+## Without R_LARCH_RELAX relocation. No relaxation.
+# LE64:        2024c: pcalau12i $a0, 16
+# LE64-NEXT:          addi.d  $t0, $zero, 0
+# LE64-NEXT:          addi.d  $a0, $a0, 656
+# LE64-NEXT:          addi.d  $t0, $t0, 1
+# LE64-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NEXT:          addi.d  $t0, $t0, 1
+# LE64-NEXT:          jirl    $ra, $ra, 0
+# LE64-NEXT:          add.d   $a3, $a0, $tp
+
+## &.got[d]-. = 0x30280+32 - 0x2026c = 16397<<2
+# LE64:        2026c: pcaddi  $a0, 16397
+# LE64-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NEXT:          jirl    $ra, $ra, 0
+# LE64-NEXT:          add.d   $a4, $a0, $tp
+
+# LE64-NORELAX: .got    00000040 0000000000030288
+
+## &.got[a]-. = 0x30288 - 0x20228 = 0x10 pages, page offset 0x288
+# LE64-NORELAX:        20228: pcalau12i $a0, 16
+# LE64-NORELAX-NEXT:          addi.d  $a0, $a0, 648
+# LE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# LE64-NORELAX-NEXT:          add.d   $a1, $a0, $tp
+
+## &.got[b]-. = 0x30288+48 - 0x2023c: 0x10 pages, page offset 0x2b8
+## R_LARCH_RELAX does not appear in pairs. No relaxation.
+# LE64-NORELAX:        2023c: pcalau12i $a0, 16
+# LE64-NORELAX-NEXT:          addi.d  $a0, $a0, 696
+# LE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# LE64-NORELAX-NEXT:          add.d   $a2, $a0, $tp
+
+## &.got[c]-. = 0x30288+16 - 0x20250: 0x10 pages, page offset 0x298
+## Without R_LARCH_RELAX relocation. No relaxation.
+# LE64-NORELAX:        20250: pcalau12i $a0, 16
+# LE64-NORELAX-NEXT:          addi.d  $t0, $zero, 0
+# LE64-NORELAX-NEXT:          addi.d  $a0, $a0, 664
+# LE64-NORELAX-NEXT:          addi.d  $t0, $t0, 1
+# LE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NORELAX-NEXT:          addi.d  $t0, $t0, 1
+# LE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# LE64-NORELAX-NEXT:          add.d   $a3, $a0, $tp
+
+## &.got[d]-. = 0x30288+32 - 0x20270: 0x10 pages, page offset 0x2a8
+# LE64-NORELAX:        20270: pcalau12i $a0, 16
+# LE64-NORELAX-NEXT:          addi.d  $a0, $a0, 680
+# LE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# LE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# LE64-NORELAX-NEXT:          add.d   $a4, $a0, $tp
 
 # IE64-RELA:      .rela.dyn {
-# IE64-RELA-NEXT:   0x30418 R_LARCH_TLS_DESC64 - 0x8
-# IE64-RELA-NEXT:   0x30448 R_LARCH_TLS_DESC64 - 0x7FF
-# IE64-RELA-NEXT:   0x30428 R_LARCH_TLS_DESC64 c 0x0
-# IE64-RELA-NEXT:   0x30438 R_LARCH_TLS_DESC64 d 0x0
+# IE64-RELA-NEXT:   0x30430 R_LARCH_TLS_DESC64 - 0x8
+# IE64-RELA-NEXT:   0x30460 R_LARCH_TLS_DESC64 - 0x7FF
+# IE64-RELA-NEXT:   0x30440 R_LARCH_TLS_DESC64 c 0x0
+# IE64-RELA-NEXT:   0x30450 R_LARCH_TLS_DESC64 d 0x0
 # IE64-RELA-NEXT: }
 # IE64-RELA:      Hex dump of section '.got':
-# IE64-RELA-NEXT: 0x00030418 00000000 00000000 00000000 00000000 .
-# IE64-RELA-NEXT: 0x00030428 00000000 00000000 00000000 00000000 .
-# IE64-RELA-NEXT: 0x00030438 00000000 00000000 00000000 00000000 .
-# IE64-RELA-NEXT: 0x00030448 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030430 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030440 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030450 00000000 00000000 00000000 00000000 .
+# IE64-RELA-NEXT: 0x00030460 00000000 00000000 00000000 00000000 .
+
+# IE64:   .got           00000040 0000000000030430
 
 ## a and b are optimized to use LE. c and d are optimized to IE.
-# IE64-LABEL: <.text>:
-## &.got[a]-. = 0x30418 - 0x202f8 = 16456<<2
-# IE64-NEXT:   202f8: pcaddi    $a0, 16456
-# IE64-NEXT:          ld.d      $ra, $a0, 0
-# IE64-NEXT:          jirl      $ra, $ra, 0
-# IE64-NEXT:          add.d     $a1, $a0, $tp
-## &.got[b]-. = 0x30448 - 0x20308 = 16464<<2
-# IE64-NEXT:   20308: pcaddi    $a0, 16464
-# IE64-NEXT:          ld.d      $ra, $a0, 0
-# IE64-NEXT:          jirl      $ra, $ra, 0
-# IE64-NEXT:          add.d     $a2, $a0, $tp
-## &.got[c]-. = 0x30428 - 0x20318 = 16452<<2
-# IE64-NEXT:   20318: pcaddi    $a0, 16452
-# IE64-NEXT:          ld.d      $ra, $a0, 0
-# IE64-NEXT:          jirl      $ra, $ra, 0
-# IE64-NEXT:          add.d     $a3, $a0, $tp
-## &.got[d]-. = 0x30438 - 0x20328 = 16452<<2
-# IE64-NEXT:   20328: pcaddi    $a0, 16452
-# IE64-NEXT:          ld.d      $ra, $a0, 0
-# IE64-NEXT:          jirl      $ra, $ra, 0
-# IE64-NEXT:          add.d     $a4, $a0, $tp
-
-# GD32-REL:      .rel.dyn {
-# GD32-REL-NEXT:    0x202A4 R_LARCH_TLS_DESC32 -
-# GD32-REL-NEXT:    0x2028C R_LARCH_TLS_DESC32 a
-# GD32-REL-NEXT:    0x20294 R_LARCH_TLS_DESC32 c
-# GD32-REL-NEXT:    0x2029C R_LARCH_TLS_DESC32 d
-# GD32-REL-NEXT: }
-# GD32-REL:      Hex dump of section '.got':
-# GD32-REL-NEXT: 0x0002028c 00000000 00000000 00000000 00000000 .
-# GD32-REL-NEXT: 0x0002029c 00000000 00000000 00000000 ff070000 .
+## &.got[a]-. = 0x30430 - 0x202f8 = 16462<<2
+# IE64:        202f8: pcaddi  $a0, 16462
+# IE64-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NEXT:          jirl    $ra, $ra, 0
+# IE64-NEXT:          add.d   $a1, $a0, $tp
 
-#--- a.s
-.macro add dst, src1, src2
-.ifdef ELF32
-add.w \dst, \src1, \src2
-.else
-add.d \dst, \src1, \src2
-.endif
-.endm
+## &.got[b]-. = 0x30430+48 - 0x20308: 0x10 pages, page offset 0x460
+## R_LARCH_RELAX does not appear in pairs. No relaxation.
+# IE64:        20308: pcalau12i $a0, 16
+# IE64-NEXT:          addi.d  $a0, $a0, 1120
+# IE64-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NEXT:          jirl    $ra, $ra, 0
+# IE64-NEXT:          add.d   $a2, $a0, $tp
+
+## &.got[c]-. = 0x30430+16 - 0x2031c: 0x10 pages, page offset 0x440
+## Without R_LARCH_RELAX relocation. No relaxation.
+# IE64:        2031c: pcalau12i $a0, 16
+# IE64-NEXT:          addi.d  $t0, $zero, 0
+# IE64-NEXT:          addi.d  $a0, $a0, 1088
+# IE64-NEXT:          addi.d  $t0, $t0, 1
+# IE64-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NEXT:          addi.d  $t0, $t0, 1
+# IE64-NEXT:          jirl    $ra, $ra, 0
+# IE64-NEXT:          add.d   $a3, $a0, $tp
+
+## &.got[d]-. = 0x30430+32 - 0x2033c = 16453<<2
+# IE64:        2033c: pcaddi  $a0, 16453
+# IE64-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NEXT:          jirl    $ra, $ra, 0
+# IE64-NEXT:          add.d   $a4, $a0, $tp
+
+# IE64-NORELAX: .got    00000040 0000000000030438
 
+## &.got[a]-. = 0x30438 - 0x202f8 = 0x10 pages, page offset 0x438
+# IE64-NORELAX:        202f8: pcalau12i $a0, 16
+# IE64-NORELAX-NEXT:          addi.d  $a0, $a0, 1080
+# IE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# IE64-NORELAX-NEXT:          add.d   $a1, $a0, $tp
+
+## &.got[b]-. = 0x30438+48 - 0x2030c: 0x10 pages, page offset 0x468
+## R_LARCH_RELAX does not appear in pairs. No relaxation.
+# IE64-NORELAX:        2030c: pcalau12i $a0, 16
+# IE64-NORELAX-NEXT:          addi.d  $a0, $a0, 1128
+# IE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# IE64-NORELAX-NEXT:          add.d   $a2, $a0, $tp
+
+## &.got[c]-. = 0x30438+16 - 0x20320: 0x10 pages, page offset 0x448
+## Without R_LARCH_RELAX relocation. No relaxation.
+# IE64-NORELAX:        20320: pcalau12i $a0, 16
+# IE64-NORELAX-NEXT:          addi.d  $t0, $zero, 0
+# IE64-NORELAX-NEXT:          addi.d  $a0, $a0, 1096
+# IE64-NORELAX-NEXT:          addi.d  $t0, $t0, 1
+# IE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NORELAX-NEXT:          addi.d  $t0, $t0, 1
+# IE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# IE64-NORELAX-NEXT:          add.d   $a3, $a0, $tp
+
+## &.got[d]-. = 0x30438+32 - 0x20340: 0x10 pages, page offset 0x458
+# IE64-NORELAX:        20340: pcalau12i $a0, 16
+# IE64-NORELAX-NEXT:          addi.d  $a0, $a0, 1112
+# IE64-NORELAX-NEXT:          ld.d    $ra, $a0, 0
+# IE64-NORELAX-NEXT:          jirl    $ra, $ra, 0
+# IE64-NORELAX-NEXT:          add.d   $a4, $a0, $tp
+
+#--- a.s
 la.tls.desc $a0, a
-add $a1, $a0, $tp
+add.d $a1, $a0, $tp
 
-la.tls.desc $a0, b
-add $a2, $a0, $tp
+# ADDI.D does not have R_LARCH_RELAX. No relaxation.
+pcalau12i $a0, %desc_pc_hi20(b)
+.reloc .-4, R_LARCH_RELAX, 0
+addi.d $a0, $a0, %desc_pc_lo12(b)
+ld.d $ra, $a0, %desc_ld(b)
+jirl $ra, $ra, %desc_call(b)
+add.d $a2, $a0, $tp
 
-la.tls.desc $a0, c
-add $a3, $a0, $tp
+# TLSDESC to LE. No relaxation.
+pcalau12i $a0, %desc_pc_hi20(c)
+addi.d $t0, $zero, 0
+addi.d $a0, $a0, %desc_pc_lo12(c)
+addi.d $t0, $t0, 1
+ld.d $ra, $a0, %desc_ld(c)
+addi.d $t0, $t0, 1
+jirl $ra, $ra, %desc_call(c)
+add.d $a3, $a0, $tp
 
-la.tls.desc $a0, d
-add $a4, $a0, $tp
+# PCALAU12I and ADDI.D have R_LARCH_RELAX. We preform relaxation.
+pcalau12i $a0, %desc_pc_hi20(d)
+.reloc .-4, R_LARCH_RELAX, 0
+addi.d $a0, $a0, %desc_pc_lo12(d)
+.reloc .-4, R_LARCH_RELAX, 0
+ld.d $ra, $a0, %desc_ld(d)
+jirl $ra, $ra, %desc_call(d)
+add.d $a4, $a0, $tp
 
 .section .tbss,"awT", at nobits
 .globl a

>From b2f11e3b33a0c2650c165992c8497fd6be851113 Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Sat, 4 Jan 2025 12:35:54 +0800
Subject: [PATCH 5/6] Remove --emit-relocs in loongarch-relax-tlsdesc.s

llvm-objdump -dr cannot print the relocations, however objudmp works
well. It also occurs for RISCV.
---
 lld/test/ELF/loongarch-relax-tlsdesc.s | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lld/test/ELF/loongarch-relax-tlsdesc.s b/lld/test/ELF/loongarch-relax-tlsdesc.s
index 6561066ebeb5ca..5a8cf7acbb7de0 100644
--- a/lld/test/ELF/loongarch-relax-tlsdesc.s
+++ b/lld/test/ELF/loongarch-relax-tlsdesc.s
@@ -4,24 +4,24 @@
 # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax c.s -o c.64.o
 # RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so
 
-## Test the TLSDESC relaxation. Also check --emit-relocs.
-# RUN: ld.lld -shared --emit-relocs -z now a.64.o c.64.o -o a.64.so
+## Test the TLSDESC relaxation.
+# RUN: ld.lld -shared -z now a.64.o c.64.o -o a.64.so
 # RUN: llvm-readobj -r -x .got a.64.so | FileCheck --check-prefix=GD64-RELA %s
 # RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.so | FileCheck %s --check-prefix=GD64
 
 ## FIXME: The transition frome TLSDESC to IE/LE has not yet been implemented.
 ## Keep the dynamic relocations and hand them over to dynamic linker.
 
-# RUN: ld.lld -e 0 -z now --emit-relocs a.64.o c.64.o -o a.64.le
+# RUN: ld.lld -e 0 -z now a.64.o c.64.o -o a.64.le
 # RUN: llvm-readobj -r -x .got a.64.le | FileCheck --check-prefix=LE64-RELA %s
-# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.le | FileCheck %s --check-prefix=LE64
+# RUN: llvm-objdump --no-show-raw-insn -d -h a.64.le | FileCheck %s --check-prefix=LE64
 
 # RUN: ld.lld -e 0 -z now --no-relax a.64.o c.64.o -o a.64.le.norelax
 # RUN: llvm-objdump --no-show-raw-insn -d -h a.64.le.norelax | FileCheck %s --check-prefix=LE64-NORELAX
 
-# RUN: ld.lld -e 0 -z now --emit-relocs a.64.o c.64.so -o a.64.ie
+# RUN: ld.lld -e 0 -z now a.64.o c.64.so -o a.64.ie
 # RUN: llvm-readobj -r -x .got a.64.ie | FileCheck --check-prefix=IE64-RELA %s
-# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.ie | FileCheck %s --check-prefix=IE64
+# RUN: llvm-objdump --no-show-raw-insn -d -h a.64.ie | FileCheck %s --check-prefix=IE64
 
 # RUN: ld.lld -e 0 -z now --no-relax a.64.o c.64.so -o a.64.ie.norelax
 # RUN: llvm-objdump --no-show-raw-insn -d -h a.64.ie.norelax | FileCheck %s --check-prefix=IE64-NORELAX

>From d5c9d649c92235eab855cd7bad34ab3e1580a6fa Mon Sep 17 00:00:00 2001
From: yangzhaoxin <yangzhaoxin at loongson.cn>
Date: Fri, 17 Jan 2025 08:49:30 +0800
Subject: [PATCH 6/6] Modify test. Add --relax option.

---
 lld/test/ELF/loongarch-relax-tlsdesc.s | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lld/test/ELF/loongarch-relax-tlsdesc.s b/lld/test/ELF/loongarch-relax-tlsdesc.s
index 5a8cf7acbb7de0..f9d984ad6387a3 100644
--- a/lld/test/ELF/loongarch-relax-tlsdesc.s
+++ b/lld/test/ELF/loongarch-relax-tlsdesc.s
@@ -2,28 +2,28 @@
 # RUN: rm -rf %t && split-file %s %t && cd %t
 # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.64.o
 # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax c.s -o c.64.o
-# RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so
+# RUN: ld.lld --relax -shared -soname=c.64.so c.64.o -o c.64.so
 
 ## Test the TLSDESC relaxation.
-# RUN: ld.lld -shared -z now a.64.o c.64.o -o a.64.so
+# RUN: ld.lld --relax -shared -z now a.64.o c.64.o -o a.64.so
 # RUN: llvm-readobj -r -x .got a.64.so | FileCheck --check-prefix=GD64-RELA %s
 # RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.so | FileCheck %s --check-prefix=GD64
 
 ## FIXME: The transition frome TLSDESC to IE/LE has not yet been implemented.
 ## Keep the dynamic relocations and hand them over to dynamic linker.
 
-# RUN: ld.lld -e 0 -z now a.64.o c.64.o -o a.64.le
+# RUN: ld.lld --relax -e 0 -z now a.64.o c.64.o -o a.64.le
 # RUN: llvm-readobj -r -x .got a.64.le | FileCheck --check-prefix=LE64-RELA %s
 # RUN: llvm-objdump --no-show-raw-insn -d -h a.64.le | FileCheck %s --check-prefix=LE64
 
-# RUN: ld.lld -e 0 -z now --no-relax a.64.o c.64.o -o a.64.le.norelax
+# RUN: ld.lld --no-relax -e 0 -z now a.64.o c.64.o -o a.64.le.norelax
 # RUN: llvm-objdump --no-show-raw-insn -d -h a.64.le.norelax | FileCheck %s --check-prefix=LE64-NORELAX
 
-# RUN: ld.lld -e 0 -z now a.64.o c.64.so -o a.64.ie
+# RUN: ld.lld --relax -e 0 -z now a.64.o c.64.so -o a.64.ie
 # RUN: llvm-readobj -r -x .got a.64.ie | FileCheck --check-prefix=IE64-RELA %s
 # RUN: llvm-objdump --no-show-raw-insn -d -h a.64.ie | FileCheck %s --check-prefix=IE64
 
-# RUN: ld.lld -e 0 -z now --no-relax a.64.o c.64.so -o a.64.ie.norelax
+# RUN: ld.lld --no-relax -e 0 -z now a.64.o c.64.so -o a.64.ie.norelax
 # RUN: llvm-objdump --no-show-raw-insn -d -h a.64.ie.norelax | FileCheck %s --check-prefix=IE64-NORELAX
 
 # GD64-RELA:      .rela.dyn {



More information about the llvm-branch-commits mailing list