[lld] [lld][LoongArch] Fix relaxation for R_LARCH_GOT_PC_{HI20, LO12} (PR #151264)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 29 18:01:54 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
Author: Zhaoxin Yang (ylzsx)
<details>
<summary>Changes</summary>
We could relax codes when the addends of both relocations are zero for R_LARCH_GOT_PC_{HI20,LO12}.
Note: For `ld.bfd`, GOT references with non-zero addends will trigger an assert in LoongArch, but `lld` handles these cases without any errors.
```
ld.bfd: BFD (GNU Binutils) 2.44.0 assertion fail
/usr/src/debug/binutils/binutils-gdb/bfd/elfnn-loongarch.c:4248
```
---
Full diff: https://github.com/llvm/llvm-project/pull/151264.diff
2 Files Affected:
- (modified) lld/ELF/Arch/LoongArch.cpp (+6-3)
- (modified) lld/test/ELF/loongarch-relax-pc-hi20-lo12.s (+25-3)
``````````diff
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 15dcddb13baf7..a14553018fc36 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -809,10 +809,13 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i,
// address.
// Meanwhile skip undefined, preemptible and STT_GNU_IFUNC symbols, because
// these symbols may be resolve in runtime.
+ // Moreover, relaxation can only occur if the addends of both relocations are
+ // zero for GOT references.
if (rHi20.type == R_LARCH_GOT_PC_HI20 &&
- (!rHi20.sym->isDefined() || rHi20.sym->isPreemptible ||
- rHi20.sym->isGnuIFunc() ||
- (ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section)))
+ (!rHi20.sym || rHi20.sym != rLo12.sym || !rHi20.sym->isDefined() ||
+ rHi20.sym->isPreemptible || rHi20.sym->isGnuIFunc() ||
+ (ctx.arg.isPic && !cast<Defined>(*rHi20.sym).section) ||
+ rHi20.addend != 0 || rLo12.addend != 0))
return;
uint64_t dest = 0;
diff --git a/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s b/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s
index a417d89e9fa2e..d5bec595bbfd7 100644
--- a/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s
+++ b/lld/test/ELF/loongarch-relax-pc-hi20-lo12.s
@@ -1,12 +1,12 @@
# REQUIRES: loongarch
-# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax %s -o %t.32.o
+# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+relax --defsym ELF32=1 %s -o %t.32.o
# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t.64.o
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.32.o -o %t.32
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.64.o -o %t.64
-# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck --check-prefixes=RELAX %s
-# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck --check-prefixes=RELAX %s
+# RUN: llvm-objdump -td --no-show-raw-insn %t.32 | FileCheck --check-prefixes=RELAX,RELAX32 %s
+# RUN: llvm-objdump -td --no-show-raw-insn %t.64 | FileCheck --check-prefixes=RELAX,RELAX64 %s
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.32.o -shared -o %t.32s
# RUN: ld.lld --section-start=.text=0x10000 --section-start=.data=0x14000 %t.64.o -shared -o %t.64s
@@ -25,6 +25,11 @@
# RELAX-NEXT: pcaddi $a0, 4094
# RELAX-NEXT: pcaddi $a0, 4093
+# RELAX32-NEXT: pcalau12i $a0, 4
+# RELAX32-NEXT: ld.w $a0, $a0, 8
+# RELAX64-NEXT: pcalau12i $a0, 4
+# RELAX64-NEXT: ld.d $a0, $a0, 12
+
# NORELAX32-LABEL: <_start>:
## offset exceed range of pcaddi
## offset = 0x410000 - 0x10000: 0x400 pages, page offset 0
@@ -36,6 +41,8 @@
# NORELAX32-NEXT: addi.w $a0, $a0, 0
# NORELAX32-NEXT: pcalau12i $a0, 1024
# NORELAX32-NEXT: ld.w $a0, $a0, 4
+# NORELAX32-NEXT: pcalau12i $a0, 1024
+# NORELAX32-NEXT: ld.w $a0, $a0, 8
# NORELAX64-LABEL: <_start>:
## offset exceed range of pcaddi
@@ -48,6 +55,16 @@
# NORELAX64-NEXT: addi.d $a0, $a0, 0
# NORELAX64-NEXT: pcalau12i $a0, 1024
# NORELAX64-NEXT: ld.d $a0, $a0, 8
+# NORELAX64-NEXT: pcalau12i $a0, 1024
+# NORELAX64-NEXT: ld.d $a0, $a0, 12
+
+.macro ld dst, src1, src2
+.ifdef ELF32
+ld.w \dst, \src1, \src2
+.else
+ld.d \dst, \src1, \src2
+.endif
+.endm
.section .text
.global _start
@@ -57,6 +74,11 @@ _start:
la.pcrel $a0, sym
la.got $a0, sym
+ pcalau12i $a0, %got_pc_hi20(sym+4)
+ .reloc .-4, R_LARCH_RELAX, 0
+ ld $a0, $a0, %got_pc_lo12(sym+4)
+ .reloc .-4, R_LARCH_RELAX, 0
+
.section .data
sym:
.zero 4
``````````
</details>
https://github.com/llvm/llvm-project/pull/151264
More information about the llvm-commits
mailing list