[llvm-branch-commits] [lld] [lld][LoongArch] Support TLSDESC GD/LD to IE/LE. (PR #123715)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jan 21 01:02:24 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
Author: Zhaoxin Yang (ylzsx)
<details>
<summary>Changes</summary>
Support TLSDESC to initial-exec or local-exec optimizations. Introduce a new hook RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC and use existing R_RELAX_TLS_GD_TO_IE_ABS to support TLSDESC => IE, while use existing R_RELAX_TLS_GD_TO_LE to support TLSDESC => LE.
In normal or medium code model, there are two forms of code sequences:
* 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)
------
* pcaddi $a0, %desc_pcrel_20(sym_desc)
* ld.d $ra, $a0, %desc_ld(sym_desc)
* jirl $ra, $ra, %desc_call(sym_desc)
Convert to IE:
* pcalau12i $a0, %ie_pc_hi20(sym_ie)
* ld.[wd] $a0, $a0, %ie_pc_lo12(sym_ie)
Convert to LE:
* lu12i.w $a0, %le_hi20(sym_le) # le_hi20 != 0, otherwise nop
* ori $a0 $a0, %le_lo12(sym_le)
Simplicity, whether tlsdescToIe or tlsdescToLe, we always tend to convert the preceding instructions to NOPs, due to both forms of code sequence (corresponding to relocation combinations: R_LARCH_TLS_DESC_PC_HI20+R_LARCH_TLS_DESC_PC_LO12 and R_LARCH_TLS_DESC_PCREL20_S2) have same process.
FIXME: When relaxation enables, redundant NOPs can be removed. It will be implemented in a future patch.
Note: All forms of TLSDESC code sequences should not appear interleaved in the normal, medium or extreme code model, which compilers do not generate and lld is unsupported. This is thanks to the guard in PostRASchedulerList.cpp in llvm.
```
Calls are not scheduling boundaries before register allocation,
but post-ra we don't gain anything by scheduling across calls
since we don't need to worry about register pressure.
```
---
Patch is 33.17 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123715.diff
7 Files Affected:
- (modified) lld/ELF/Arch/LoongArch.cpp (+145-1)
- (modified) lld/ELF/InputSection.cpp (+1)
- (modified) lld/ELF/Relocations.cpp (+22-16)
- (modified) lld/ELF/Relocations.h (+1)
- (modified) lld/test/ELF/loongarch-relax-tlsdesc.s (+141-115)
- (modified) lld/test/ELF/loongarch-tlsdesc-pcrel20-s2.s (+40-19)
- (modified) lld/test/ELF/loongarch-tlsdesc.s (+46-19)
``````````diff
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index ef25e741901d93..37614c3e9615d6 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -39,11 +39,14 @@ class LoongArch final : public TargetInfo {
void relocate(uint8_t *loc, const Relocation &rel,
uint64_t val) const override;
bool relaxOnce(int pass) const override;
+ RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override;
void relocateAlloc(InputSectionBase &sec, uint8_t *buf) const override;
void finalizeRelax(int passes) const override;
private:
void tlsIeToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
+ void tlsdescToIe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
+ void tlsdescToLe(uint8_t *loc, const Relocation &rel, uint64_t val) const;
};
} // end anonymous namespace
@@ -61,6 +64,7 @@ enum Op {
LU12I_W = 0x14000000,
PCADDI = 0x18000000,
PCADDU12I = 0x1c000000,
+ PCALAU12I = 0x1a000000,
LD_W = 0x28800000,
LD_D = 0x28c00000,
JIRL = 0x4c000000,
@@ -72,6 +76,7 @@ enum Reg {
R_ZERO = 0,
R_RA = 1,
R_TP = 2,
+ R_A0 = 4,
R_T0 = 12,
R_T1 = 13,
R_T2 = 14,
@@ -962,7 +967,8 @@ static bool relax(Ctx &ctx, InputSection &sec) {
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))
+ if (r.expr != RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC &&
+ r.expr != R_RELAX_TLS_GD_TO_LE && isPairRelaxable(relocs, i))
relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove);
break;
case R_LARCH_CALL36:
@@ -1047,6 +1053,103 @@ void LoongArch::tlsIeToLe(uint8_t *loc, const Relocation &rel,
}
}
+// Convert TLSDESC GD/LD to IE.
+// In normal or medium code model, there are two forms of code sequences:
+// * 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)
+// ------
+// * pcaddi $a0, %desc_pcrel_20(a)
+// * load $ra, $a0, %desc_ld(a)
+// * jirl $ra, $ra, %desc_call(a)
+//
+// The code sequence obtained is as follows:
+// * pcalau12i $a0, %ie_pc_hi20(sym_ie)
+// * ld.[wd] $a0, $a0, %ie_pc_lo12(sym_ie)
+//
+// Simplicity, whether tlsdescToIe or tlsdescToLe, we always tend to convert the
+// preceding instructions to NOPs, due to both forms of code sequence
+// (corresponding to relocation combinations:
+// R_LARCH_TLS_DESC_PC_HI20+R_LARCH_TLS_DESC_PC_LO12 and
+// R_LARCH_TLS_DESC_PCREL20_S2) have same process.
+//
+// When relaxation enables, redundant NOPs can be removed.
+void LoongArch::tlsdescToIe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const {
+ switch (rel.type) {
+ case R_LARCH_TLS_DESC_PC_HI20:
+ case R_LARCH_TLS_DESC_PC_LO12:
+ case R_LARCH_TLS_DESC_PCREL20_S2:
+ write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop
+ break;
+ case R_LARCH_TLS_DESC_LD:
+ write32le(loc, insn(PCALAU12I, R_A0, 0, 0)); // pcalau12i $a0, %ie_pc_hi20
+ relocateNoSym(loc, R_LARCH_TLS_IE_PC_HI20, val);
+ break;
+ case R_LARCH_TLS_DESC_CALL:
+ write32le(loc, insn(ctx.arg.is64 ? LD_D : LD_W, R_A0, R_A0,
+ 0)); // ld.[wd] $a0, $a0, %ie_pc_lo12
+ relocateNoSym(loc, R_LARCH_TLS_IE_PC_LO12, val);
+ break;
+ default:
+ llvm_unreachable("unsupported relocation for TLSDESC to IE");
+ }
+}
+
+// Convert TLSDESC GD/LD to LE.
+// The code sequence obtained in the normal or medium code model is as follows:
+// * lu12i.w $a0, %le_hi20(sym_le) # le_hi20 != 0
+// * ori $a0 $a0, %le_lo12(sym_le)
+// See the comment in tlsdescToIe for detailed information.
+void LoongArch::tlsdescToLe(uint8_t *loc, const Relocation &rel,
+ uint64_t val) const {
+ assert(isInt<32>(val) &&
+ "val exceeds the range of medium code model in tlsdescToLe");
+
+ bool isUInt12 = isUInt<12>(val);
+ switch (rel.type) {
+ case R_LARCH_TLS_DESC_PC_HI20:
+ case R_LARCH_TLS_DESC_PC_LO12:
+ case R_LARCH_TLS_DESC_PCREL20_S2:
+ write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop
+ break;
+ case R_LARCH_TLS_DESC_LD:
+ if (isUInt12)
+ write32le(loc, insn(ANDI, R_ZERO, R_ZERO, 0)); // nop
+ else
+ write32le(loc, insn(LU12I_W, R_A0, extractBits(val, 31, 12),
+ 0)); // lu12i.w $a0, %le_hi20
+ break;
+ case R_LARCH_TLS_DESC_CALL:
+ if (isUInt12)
+ write32le(loc, insn(ORI, R_A0, R_ZERO, val)); // ori $a0, $r0, %le_lo12
+ else
+ write32le(loc,
+ insn(ORI, R_A0, R_A0, lo12(val))); // ori $a0, $a0, %le_lo12
+ break;
+ default:
+ llvm_unreachable("unsupported relocation for TLSDESC to LE");
+ }
+}
+
+// During TLSDESC GD_TO_IE, the converted code sequence always includes an
+// instruction related to the Lo12 relocation (ld.[wd]). To obtain correct val
+// in `getRelocTargetVA`, expr of this instruction should be adjusted to
+// R_RELAX_TLS_GD_TO_IE_ABS, while expr of other instructions related to the
+// Hi20 relocation (pcalau12i) should be adjusted to
+// RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC. Specifically, in the normal or
+// medium code model, the instruction with relocation R_LARCH_TLS_DESC_CALL is
+// the candidate of Lo12 relocation.
+RelExpr LoongArch::adjustTlsExpr(RelType type, RelExpr expr) const {
+ if (expr == R_RELAX_TLS_GD_TO_IE) {
+ if (type != R_LARCH_TLS_DESC_CALL)
+ return RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC;
+ return R_RELAX_TLS_GD_TO_IE_ABS;
+ }
+ return expr;
+}
+
void LoongArch::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
const unsigned bits = ctx.arg.is64 ? 64 : 32;
uint64_t secAddr = sec.getOutputSection()->addr;
@@ -1089,6 +1192,47 @@ void LoongArch::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
tlsIeToLe(loc, rel, val);
}
continue;
+ case RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC:
+ if (rel.type == R_LARCH_TLS_DESC_PC_HI20) {
+ // LoongArch does not support TLSDESC GD/LD to LE/IE optimization in the
+ // extreme code model. In these cases, the relocs are as follows:
+ //
+ // * i -- R_LARCH_TLS_DESC_PC_HI20
+ // * i+1 -- R_LARCH_TLS_DESC_PC_LO12
+ // * i+2 -- R_LARCH_TLS_DESC64_PC_LO20
+ // * i+3 -- R_LARCH_TLS_DESC64_PC_HI12
+ isExtreme =
+ (i + 2 < size && relocs[i + 2].type == R_LARCH_TLS_DESC64_PC_LO20);
+ }
+ [[fallthrough]];
+ case R_RELAX_TLS_GD_TO_IE_ABS:
+ if (isExtreme) {
+ if (rel.type == R_LARCH_TLS_DESC_CALL)
+ continue;
+ rel.expr = getRelExpr(rel.type, *rel.sym, loc);
+ val = SignExtend64(sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset),
+ bits);
+ relocateNoSym(loc, rel.type, val);
+ } else {
+ tlsdescToIe(loc, rel, val);
+ }
+ continue;
+ case R_RELAX_TLS_GD_TO_LE:
+ if (rel.type == R_LARCH_TLS_DESC_PC_HI20) {
+ isExtreme =
+ (i + 2 < size && relocs[i + 2].type == R_LARCH_TLS_DESC64_PC_LO20);
+ }
+ if (isExtreme) {
+ if (rel.type == R_LARCH_TLS_DESC_CALL)
+ continue;
+ rel.expr = getRelExpr(rel.type, *rel.sym, loc);
+ val = SignExtend64(sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset),
+ bits);
+ relocateNoSym(loc, rel.type, val);
+ } else {
+ tlsdescToLe(loc, rel, val);
+ }
+ continue;
default:
break;
}
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index efa7ba3e7cb063..238f64c815df3a 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -825,6 +825,7 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
case R_GOTPLT_PC:
return r.sym->getGotPltVA(ctx) + a - p;
case RE_LOONGARCH_GOT_PAGE_PC:
+ case RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC:
if (r.sym->hasFlag(NEEDS_TLSGD))
return getLoongArchPageDelta(ctx.in.got->getGlobalDynAddr(*r.sym) + a, p,
r.type);
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index c16e4f9598ad8c..871d3b4e63e90d 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1316,22 +1316,10 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
if (ctx.arg.emachine == EM_MIPS)
return handleMipsTlsRelocation(ctx, type, sym, *sec, offset, addend, expr);
- // LoongArch does not yet implement transition from TLSDESC to LE/IE, so
- // generate TLSDESC dynamic relocation for the dynamic linker to handle.
- if (ctx.arg.emachine == EM_LOONGARCH &&
- oneof<RE_LOONGARCH_TLSDESC_PAGE_PC, R_TLSDESC, R_TLSDESC_PC,
- R_TLSDESC_CALL>(expr)) {
- if (expr != R_TLSDESC_CALL) {
- sym.setFlags(NEEDS_TLSDESC);
- sec->addReloc({expr, type, offset, addend, &sym});
- }
- return 1;
- }
-
bool isRISCV = ctx.arg.emachine == EM_RISCV;
if (oneof<RE_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
- R_TLSDESC_GOTPLT>(expr) &&
+ R_TLSDESC_GOTPLT, RE_LOONGARCH_TLSDESC_PAGE_PC>(expr) &&
ctx.arg.shared) {
// R_RISCV_TLSDESC_{LOAD_LO12,ADD_LO12_I,CALL} reference a label. Do not
// set NEEDS_TLSDESC on the label.
@@ -1343,10 +1331,14 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
return 1;
}
- // LoongArch support IE to LE optimization in non-extreme code model.
+ // LoongArch support IE to LE, DESC GD/LD to IE/LE optimizations in
+ // non-extreme code model.
bool execOptimizeInLoongArch =
ctx.arg.emachine == EM_LOONGARCH &&
- (type == R_LARCH_TLS_IE_PC_HI20 || type == R_LARCH_TLS_IE_PC_LO12);
+ (type == R_LARCH_TLS_IE_PC_HI20 || type == R_LARCH_TLS_IE_PC_LO12 ||
+ type == R_LARCH_TLS_DESC_PC_HI20 || type == R_LARCH_TLS_DESC_PC_LO12 ||
+ type == R_LARCH_TLS_DESC_LD || type == R_LARCH_TLS_DESC_CALL ||
+ type == R_LARCH_TLS_DESC_PCREL20_S2);
// ARM, Hexagon, LoongArch and RISC-V do not support GD/LD to IE/LE
// optimizations.
@@ -1405,9 +1397,23 @@ unsigned RelocationScanner::handleTlsRelocation(RelExpr expr, RelType type,
return 1;
}
+ // LoongArch does not support transition from TLSDESC to LE/IE in the extreme
+ // code model, in which NEEDS_TLSDESC should set, rather than NEEDS_TLSGD. So
+ // we check independently.
+ if (ctx.arg.emachine == EM_LOONGARCH &&
+ oneof<RE_LOONGARCH_TLSDESC_PAGE_PC, R_TLSDESC, R_TLSDESC_PC,
+ R_TLSDESC_CALL>(expr) &&
+ !execOptimize) {
+ if (expr != R_TLSDESC_CALL) {
+ sym.setFlags(NEEDS_TLSDESC);
+ sec->addReloc({expr, type, offset, addend, &sym});
+ }
+ return 1;
+ }
+
if (oneof<RE_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC,
- RE_LOONGARCH_TLSGD_PAGE_PC>(expr)) {
+ RE_LOONGARCH_TLSGD_PAGE_PC, RE_LOONGARCH_TLSDESC_PAGE_PC>(expr)) {
if (!execOptimize) {
sym.setFlags(NEEDS_TLSGD);
sec->addReloc({expr, type, offset, addend, &sym});
diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h
index fde25a230b72e6..39036295ef17ce 100644
--- a/lld/ELF/Relocations.h
+++ b/lld/ELF/Relocations.h
@@ -129,6 +129,7 @@ enum RelExpr {
RE_LOONGARCH_GOT_PAGE_PC,
RE_LOONGARCH_TLSGD_PAGE_PC,
RE_LOONGARCH_TLSDESC_PAGE_PC,
+ RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC,
};
// Architecture-neutral representation of relocation.
diff --git a/lld/test/ELF/loongarch-relax-tlsdesc.s b/lld/test/ELF/loongarch-relax-tlsdesc.s
index f9d984ad6387a3..5e538985d1402c 100644
--- a/lld/test/ELF/loongarch-relax-tlsdesc.s
+++ b/lld/test/ELF/loongarch-relax-tlsdesc.s
@@ -9,19 +9,18 @@
# 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 --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
+## FIXME: IE/LE relaxation have not yet been implemented, --relax/--no-relax obtain the same results.
+## Transition from TLSDESC to IE/LE. Also check --emit-relocs.
+# RUN: ld.lld --relax -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 2>&1 | FileCheck --check-prefix=LE64-RELA %s
+# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.le | FileCheck %s --check-prefix=LE64
# 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 --relax -e 0 -z now a.64.o c.64.so -o a.64.ie
+# RUN: ld.lld --relax -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 -h a.64.ie | FileCheck %s --check-prefix=IE64
+# RUN: llvm-objdump --no-show-raw-insn -dr -h a.64.ie | FileCheck %s --check-prefix=IE64
# 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
@@ -71,172 +70,199 @@
# GD64-NEXT: jirl $ra, $ra, 0
# GD64-NEXT: add.d $a4, $a0, $tp
-# LE64-RELA: .rela.dyn {
-# 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: 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-RELA: could not find section '.got'
+
+## a at tprel = 0x8
+# LE64: 20158: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_HI20 a
+# LE64-NEXT: R_LARCH_RELAX *ABS*
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_LO12 a
+# LE64-NEXT: R_LARCH_RELAX *ABS*
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_LD a
+# LE64-NEXT: R_LARCH_RELAX *ABS*
+# LE64-NEXT: ori $a0, $zero, 8
+# LE64-NEXT: R_LARCH_TLS_DESC_CALL a
+# LE64-NEXT: R_LARCH_RELAX *ABS*
# 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
+## b at tprel = 0x7ff
+# LE64: 2016c: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_HI20 b
+# LE64-NEXT: R_LARCH_RELAX *ABS*
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_LO12 b
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_LD b
+# LE64-NEXT: ori $a0, $zero, 2047
+# LE64-NEXT: R_LARCH_TLS_DESC_CALL b
# LE64-NEXT: add.d $a2, $a0, $tp
-## &.got[c]-. = 0x30280+16 - 0x2024c: 0x10 pages, page offset 0x290
+## c at tprel = 0x800
## Without R_LARCH_RELAX relocation. No relaxation.
-# LE64: 2024c: pcalau12i $a0, 16
+# LE64: 20180: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_HI20 c
# LE64-NEXT: addi.d $t0, $zero, 0
-# LE64-NEXT: addi.d $a0, $a0, 656
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_LO12 c
# LE64-NEXT: addi.d $t0, $t0, 1
-# LE64-NEXT: ld.d $ra, $a0, 0
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_LD c
# LE64-NEXT: addi.d $t0, $t0, 1
-# LE64-NEXT: jirl $ra, $ra, 0
+# LE64-NEXT: ori $a0, $zero, 2048
+# LE64-NEXT: R_LARCH_TLS_DESC_CALL c
# 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
+## d at tprel = 0x1000
+# LE64: 201a0: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_HI20 d
+# LE64-NEXT: R_LARCH_RELAX *ABS*
+# LE64-NEXT: nop
+# LE64-NEXT: R_LARCH_TLS_DESC_PC_LO12 d
+# LE64-NEXT: R_LARCH_RELAX *ABS*
+# LE64-NEXT: lu12i.w $a0, 1
+# LE64-NEXT: R_LARCH_TLS_DESC_LD d
+# LE64-NEXT: ori $a0, $a0, 0
+# LE64-NEXT: R_LARCH_TLS_DESC_CALL d
# 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
+## a at tprel = 0x8
+# LE64-NORELAX: 20158: nop
+# LE64-NORELAX-NEXT: nop
+# LE64-NORELAX-NEXT: nop
+# LE64-NORELAX-NEXT: ori $a0, $zero, 8
# 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
+## b at tprel = 0x7ff
+# LE64-NORELAX: 2016c: nop
+# LE64-NORELAX-NEXT: nop
+# LE64-NORELAX-NEXT: nop
+# LE64-NORELAX-NEXT: ori $a0, $zero, 2047
# LE64-NORELAX-NEXT: add.d $a2, $a0, $tp
-## &.got[c]-. = 0x30288+16 - 0x20250: 0x10 pages, page offset 0x298
+## c at tprel = 0x800
## Without R_LARCH_RELAX relocation. No relaxation.
-# LE64-NORELAX: 20250: pcalau12i $a0, 16
+# LE64-NORELAX: 20180: nop
# LE64-NORELAX-NEXT: addi.d $t0, $zero, 0
-# LE64-NORELAX-NEXT: addi.d $a0, $a0, 664
+# LE64-NORELAX-NEXT: nop
# LE64-NORELAX-NEXT: addi.d $t0, $t0, 1
-# LE64-NORELAX-NEXT: ld.d $ra, $a0, 0
+# LE64-NORELAX-NEXT: nop
# LE64-NORELAX-NEXT: addi.d $t0, $t0, 1
-# LE64-NORELAX-NEXT: jirl $ra, $ra, 0
+# LE64-NORELAX-NEXT: ori $a0, $zero, 2048
# 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
+## d at tprel = 0x1000
+# LE64-NORELAX: 201a0: nop
+# LE64-NORELAX-NEXT: nop
+# LE64-NORELAX-NEXT: lu12i.w $a0, 1
+# LE64-NORELAX-NEXT: ori $a0, $a0, 0
# LE64-NORELAX-NEXT: add.d $a4, $a0, $tp
# IE64-RELA: .rela.dyn {
-# 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: 0x30408 R_LARCH_TLS_TPREL64 c 0x0
+# IE64-RELA-NEXT: 0x30410 R_LARCH_TLS_TPREL64 d 0x0
# IE64-RELA-NEXT: }
# IE64-RELA: Hex dump of section '.got':
-# 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 000000...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/123715
More information about the llvm-branch-commits
mailing list