https://github.com/ylzsx updated https://github.com/llvm/llvm-project/pull/123576
>From f1f995b5fc8e90126b5825d52b9c75cd45d27cfc Mon Sep 17 00:00:00 2001 From: yangzhaoxin <yangzhao...@loongson.cn> Date: Thu, 26 Dec 2024 11:32:33 +0800 Subject: [PATCH 1/5] Relax call36/tail36. Instructions with relocation `R_LARCH_CALL36` may be relax as follows: ``` From: pcaddu18i $dest, %call36(foo) R_LARCH_CALL36, R_LARCH_RELAX jirl $r, $dest, 0 To: b/bl foo # bl if r=$ra, b if r=$zero R_LARCH_B26 ``` --- lld/ELF/Arch/LoongArch.cpp | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp index b999e7fd27ae9..0aa0cf5b657a0 100644 --- a/lld/ELF/Arch/LoongArch.cpp +++ b/lld/ELF/Arch/LoongArch.cpp @@ -58,6 +58,8 @@ enum Op { LD_W = 0x28800000, LD_D = 0x28c00000, JIRL = 0x4c000000, + B = 0x50000000, + BL = 0x54000000, }; enum Reg { @@ -830,6 +832,37 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i, remove = 4; } +// Relax code sequence. +// From: +// pcaddu18i $ra, %call36(foo) +// jirl $ra, $ra, 0 +// To: +// b/bl foo +static void relaxCall36(Ctx &ctx, const InputSection &sec, size_t i, + uint64_t loc, Relocation &r, uint32_t &remove) { + const uint64_t symLocal = + (r.expr == R_PLT_PC ? r.sym->getPltVA(ctx) : r.sym->getVA(ctx)) + + r.addend; + + const int64_t distance = symLocal - loc; + // Check if the distance aligns 4 bytes or exceeds the range of b[l]. + if ((distance & 0x3) != 0 || !isInt<28>(distance)) + return; + + const uint32_t nextInsn = read32le(sec.content().data() + r.offset + 4); + if (getD5(nextInsn) == R_RA) { + // convert jirl to bl + sec.relaxAux->relocTypes[i] = R_LARCH_B26; + sec.relaxAux->writes.push_back(insn(BL, 0, 0, 0)); + remove = 4; + } else if (getD5(nextInsn) == R_ZERO) { + // convert jirl to b + sec.relaxAux->relocTypes[i] = R_LARCH_B26; + sec.relaxAux->writes.push_back(insn(B, 0, 0, 0)); + remove = 4; + } +} + static bool relax(Ctx &ctx, InputSection &sec) { const uint64_t secAddr = sec.getVA(); const MutableArrayRef<Relocation> relocs = sec.relocs(); @@ -874,6 +907,10 @@ static bool relax(Ctx &ctx, InputSection &sec) { if (isPairRelaxable(relocs, i)) relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove); break; + case R_LARCH_CALL36: + if (relaxable(relocs, i)) + relaxCall36(ctx, sec, i, loc, r, remove); + break; } // For all anchors whose offsets are <= r.offset, they are preceded by @@ -977,6 +1014,10 @@ void LoongArch::finalizeRelax(int passes) const { // RelExpr is needed for relocating. r.expr = r.sym->hasFlag(NEEDS_PLT) ? R_PLT_PC : R_PC; break; + case R_LARCH_B26: + skip = 4; + write32le(p, aux.writes[writesIdx++]); + break; default: llvm_unreachable("unsupported type"); } >From f227ae532236e20148a872c811721a8de4e16318 Mon Sep 17 00:00:00 2001 From: yangzhaoxin <yangzhao...@loongson.cn> Date: Fri, 27 Dec 2024 14:37:40 +0800 Subject: [PATCH 2/5] modify test for call36/tail36. --- lld/test/ELF/loongarch-relax-call36-2.s | 63 +++++++++ lld/test/ELF/loongarch-relax-call36.s | 135 +++++++++++++++++++ lld/test/ELF/loongarch-relax-emit-relocs-2.s | 61 +++++++++ 3 files changed, 259 insertions(+) create mode 100644 lld/test/ELF/loongarch-relax-call36-2.s create mode 100644 lld/test/ELF/loongarch-relax-call36.s create mode 100644 lld/test/ELF/loongarch-relax-emit-relocs-2.s diff --git a/lld/test/ELF/loongarch-relax-call36-2.s b/lld/test/ELF/loongarch-relax-call36-2.s new file mode 100644 index 0000000000000..1c216a9bdc35e --- /dev/null +++ b/lld/test/ELF/loongarch-relax-call36-2.s @@ -0,0 +1,63 @@ +# 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.o + +# RUN: ld.lld -T lds a.o -o a +# RUN: llvm-objdump -d --no-show-raw-insn a | FileCheck %s --check-prefixes=RELAX,RELAX-MID + +## Unsure whether this needs a diagnostic. GNU ld allows this. +# RUN: ld.lld -T lds -pie a.o -o a.pie +# RUN: llvm-objdump -d --no-show-raw-insn a.pie | FileCheck %s --check-prefixes=RELAX,RELAX-MID + +# RUN: ld.lld -T lds -pie -z notext -z ifunc-noplt a.o -o a.ifunc-noplt +# RUN: llvm-objdump -d --no-show-raw-insn a.ifunc-noplt | FileCheck %s --check-prefixes=RELAX,NORELAX-MID + +# RELAX-LABEL: <_start>: +## offset = 0x10000000 - 0x8000000 = 0x8000000(134217728), hi=512, lo18=0 +# RELAX-NEXT: 8000000: pcaddu18i $ra, 512 +# RELAX-NEXT: jirl $ra, $ra, 0 +# RELAX-NEXT: bl 134217720 +# RELAX-NEXT: bl -134217728 +## offset = 12 - 0x8000010 = -0x8000004(-134217732), hi=512, lo18=-4 +# RELAX-NEXT: 8000010: pcaddu18i $ra, -512 +# RELAX-NEXT: jirl $ra, $ra, -4 +# RELAX-EMPTY: + +# RELAX-MID-LABEL: <.mid>: +## offset = 0x8010000 - 0x8008000 = 32768 +# RELAX-MID-NEXT: 8008000: bl 32768 +# RELAX-MID-NEXT: b 32764 +# RELAX-MID-EMPTY: + +# NORELAX-MID-LABEL: <.mid>: +# NORELAX-MID-NEXT: 8008000: pcaddu18i $ra, 0 +# NORELAX-MID-NEXT: jirl $ra, $ra, 0 +# NORELAX-MID-NEXT: pcaddu18i $t0, 0 +# NORELAX-MID-NEXT: jr $t0 +# NORELAX-MID-EMPTY: + +#--- a.s +.global _start, ifunc +_start: + call36 pos # exceed positive range (.text+0x7fffffc), not relaxed + call36 pos # relaxed + call36 neg # relaxed + call36 neg # exceed negative range (.text+16-0x8000000), not relaxed + +.section .mid,"ax",@progbits +.balign 16 + call36 ifunc@plt # enable ifunc, not relaxed + tail36 $t0, ifunc@plt # enable ifunc, not relaxed + +.type ifunc, @gnu_indirect_function +ifunc: + ret + +#--- lds +SECTIONS { + .text 0x8000000 : { *(.text) } + .mid 0x8008000 : { *(.mid) } + .iplt 0x8010000 : { *(.iplt) } +} +neg = 12; +pos = 0x10000000; diff --git a/lld/test/ELF/loongarch-relax-call36.s b/lld/test/ELF/loongarch-relax-call36.s new file mode 100644 index 0000000000000..57ed214c9eb2e --- /dev/null +++ b/lld/test/ELF/loongarch-relax-call36.s @@ -0,0 +1,135 @@ +# 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 b.s -o b.64.o +# RUN: ld.lld -shared -soname=b.so b.64.o -o b.64.so +# RUN: ld.lld -T lds a.64.o b.64.so -o 64 +# RUN: llvm-objdump -td --no-show-raw-insn 64 | FileCheck %s --check-prefix=RELAX + +## --no-relax disables relaxation. +# RUN: ld.lld -T lds a.64.o b.64.so --no-relax -o 64.norelax +# RUN: llvm-objdump -td --no-show-raw-insn 64.norelax | FileCheck %s --check-prefix=NORELAX + +# RELAX: {{0*}}00010000 g .text {{0*}}0000001c _start +# RELAX: {{0*}}0001001c g .text {{0*}}00000000 _start_end +# RELAX: {{0*}}00010808 g .mid {{0*}}00000000 mid_end +# RELAX: {{0*}}10010010 g .high {{0*}}00000000 high_end + +# RELAX-LABEL: <_start>: +## offset = 0x10018 - 0x10000 = 24 +# RELAX-NEXT: 10000: bl 24 <a> +# RELAX-NEXT: b 20 <a> +# RELAX-NEXT: nop +# RELAX-NEXT: nop +## offset = .plt(0x10400)+32 - 0x10010 = 1040 +# RELAX-NEXT: 10010: bl 1040 <bar+0x10420> +# RELAX-NEXT: b 1036 <bar+0x10420> +# RELAX-EMPTY: +# RELAX-NEXT: <a>: +# RELAX-NEXT: 10018: ret +# RELAX-EMPTY: + +# RELAX-LABEL: <.mid>: +## offset = 0x10000 - 0x10800 = -2048 +# RELAX-NEXT: 10800: bl -2048 <_start> +# RELAX-NEXT: b -2052 <_start> +# RELAX-EMPTY: + +# RELAX-LABEL: <.mid2>: +## offset = 0x10000 - 0x1010000 = -16777216 +# RELAX-NEXT: 1010000: bl -16777216 <_start> +# RELAX-NEXT: b -16777220 <_start> +# RELAX-EMPTY: + +# RELAX-LABEL: <.high>: +## offset = 0x10000 - 0x10010000 = -0x10000000, hi=-1024, lo18=0 +# RELAX-NEXT: 10010000: pcaddu18i $ra, -1024 +# RELAX-NEXT: jirl $ra, $ra, 0 +# RELAX-NEXT: pcaddu18i $t0, -1024 +# RELAX-NEXT: jirl $zero, $t0, -8 +# RELAX-EMPTY: + + +# NORELAX-LABEL: <_start>: +## offset = 0x10020 - 0x10000 = 0x20, hi=0, lo18=32 +# NORELAX-NEXT: 10000: pcaddu18i $ra, 0 +# NORELAX-NEXT: jirl $ra, $ra, 32 +## offset = 0x10020 - 0x10008 = 0x18, hi=0, lo18=24 +# NORELAX-NEXT: 10008: pcaddu18i $t0, 0 +# NORELAX-NEXT: jirl $zero, $t0, 24 +## offset = .plt(0x10400)+32 - 0x10010 = 0x410, hi=0, lo18=1040 +# NORELAX-NEXT: 10010: pcaddu18i $ra, 0 +# NORELAX-NEXT: jirl $ra, $ra, 1040 +## offset = .plt(0x10400)+32 - 0x10018 = 0x408, hi=0, lo18=1032 +# NORELAX-NEXT: 10018: pcaddu18i $t0, 0 +# NORELAX-NEXT: jirl $zero, $t0, 1032 +# NORELAX-EMPTY: +# NORELAX-NEXT: <a>: +# NORELAX-NEXT: 10020: ret +# NORELAX-EMPTY: + +# NORELAX-LABEL: <.mid>: +## offset = 0x10000 - 0x10800 = -0x800, hi=0, lo18=-2048 +# NORELAX-NEXT: 10800: pcaddu18i $ra, 0 +# NORELAX-NEXT: jirl $ra, $ra, -2048 +# NORELAX-NEXT: pcaddu18i $t0, 0 +# NORELAX-NEXT: jirl $zero, $t0, -2056 +# NORELAX-EMPTY: + +# NORELAX-LABEL: <.mid2>: +## offset = 0x10000 - 0x1010000 = -0x1000000, hi=-64, lo18=0 +# NORELAX-NEXT: 1010000: pcaddu18i $ra, -64 +# NORELAX-NEXT: jirl $ra, $ra, 0 +# NORELAX-NEXT: pcaddu18i $t0, -64 +# NORELAX-NEXT: jirl $zero, $t0, -8 +# NORELAX-EMPTY: + +# NORELAX-LABEL: <.high>: +## offset = 0x10000 - 0x10010000 = -0x10000000, hi=-1024, lo18=0 +# NORELAX-NEXT: 10010000: pcaddu18i $ra, -1024 +# NORELAX-NEXT: jirl $ra, $ra, 0 +# NORELAX-NEXT: pcaddu18i $t0, -1024 +# NORELAX-NEXT: jirl $zero, $t0, -8 +# NORELAX-EMPTY: + +#--- a.s +.global _start, _start_end +_start: + call36 a # relaxed. la64: bl + tail36 $t0, a@plt # relaxed. la64: b +.balign 16 + call36 bar # PLT call36 can be relaxed. la64: bl + tail36 $t0, bar # PLT tail36 can be relaxed. la64: bl + +a: + ret +.size _start, . - _start +_start_end: + +.section .mid,"ax",@progbits + call36 _start@plt # relaxed. la64: bl + tail36 $t0, _start@plt # relaxed. la64: b + +.section .mid2,"ax",@progbits + call36 _start@plt # relaxed. la64: bl + tail36 $t0, _start@plt # relaxed. la64: b + +.section .high,"ax",@progbits + call36 _start@plt # exceed range, not relaxed + tail36 $t0,_start@plt # exceed range, not relaxed + +#--- b.s +.globl bar +bar: + ret + +#--- lds +SECTIONS { + .text 0x10000 : { *(.text) } + .plt 0x10400 : { *(.plt) } + .mid 0x10800 : { *(.mid); mid_end = .; } + .mid2 0x1010000 : { *(.mid2) } + .high 0x10010000 : { *(.high); high_end = .; } +} diff --git a/lld/test/ELF/loongarch-relax-emit-relocs-2.s b/lld/test/ELF/loongarch-relax-emit-relocs-2.s new file mode 100644 index 0000000000000..31cae939eca71 --- /dev/null +++ b/lld/test/ELF/loongarch-relax-emit-relocs-2.s @@ -0,0 +1,61 @@ +# REQUIRES: loongarch +## Test that we can handle --emit-relocs while relaxing. +## Call36 and tail36 need LA64 basic integer, so they donot have 32-bit version. + +# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o +# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 +# RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefix=RELAX + +## -r should keep original relocations. +# RUN: ld.lld -r %t.64.o -o %t.64.r +# RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR + +## --no-relax should keep original relocations. +# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax +# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefix=NORELAX + +# RELAX: 00010000 <_start>: +# RELAX-NEXT: bl 0 +# RELAX-NEXT: R_LARCH_B26 _start +# RELAX-NEXT: R_LARCH_RELAX *ABS* +# RELAX-NEXT: b -4 +# RELAX-NEXT: R_LARCH_B26 _start +# RELAX-NEXT: R_LARCH_RELAX *ABS* +# RELAX-NEXT: nop +# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc +# RELAX-NEXT: nop +# RELAX-NEXT: ret + +# CHECKR: <_start>: +# CHECKR-NEXT: pcaddu18i $ra, 0 +# CHECKR-NEXT: R_LARCH_CALL36 _start +# CHECKR-NEXT: R_LARCH_RELAX *ABS* +# CHECKR-NEXT: jirl $ra, $ra, 0 +# CHECKR-NEXT: pcaddu18i $t0, 0 +# CHECKR-NEXT: R_LARCH_CALL36 _start +# CHECKR-NEXT: R_LARCH_RELAX *ABS* +# CHECKR-NEXT: jr $t0 +# CHECKR-NEXT: nop +# CHECKR-NEXT: R_LARCH_ALIGN *ABS*+0xc +# CHECKR-NEXT: nop +# CHECKR-NEXT: nop +# CHECKR-NEXT: ret + +# NORELAX: <_start>: +# NORELAX-NEXT: pcaddu18i $ra, 0 +# NORELAX-NEXT: R_LARCH_CALL36 _start +# NORELAX-NEXT: R_LARCH_RELAX *ABS* +# NORELAX-NEXT: jirl $ra, $ra, 0 +# NORELAX-NEXT: pcaddu18i $t0, 0 +# NORELAX-NEXT: R_LARCH_CALL36 _start +# NORELAX-NEXT: R_LARCH_RELAX *ABS* +# NORELAX-NEXT: jirl $zero, $t0, -8 +# NORELAX-NEXT: ret +# NORELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc + +.global _start +_start: + call36 _start + tail36 $t0, _start + .p2align 4 + ret >From f2aae15f701863d03edd32657824a97f66696e8d Mon Sep 17 00:00:00 2001 From: yangzhaoxin <yangzhao...@loongson.cn> Date: Thu, 16 Jan 2025 21:50:14 +0800 Subject: [PATCH 3/5] Modify test. Add the option --relax. --- lld/test/ELF/loongarch-relax-call36-2.s | 6 +++--- lld/test/ELF/loongarch-relax-call36.s | 6 +++--- lld/test/ELF/loongarch-relax-emit-relocs-2.s | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lld/test/ELF/loongarch-relax-call36-2.s b/lld/test/ELF/loongarch-relax-call36-2.s index 1c216a9bdc35e..71650aefe9432 100644 --- a/lld/test/ELF/loongarch-relax-call36-2.s +++ b/lld/test/ELF/loongarch-relax-call36-2.s @@ -2,14 +2,14 @@ # RUN: rm -rf %t && split-file %s %t && cd %t # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.o -# RUN: ld.lld -T lds a.o -o a +# RUN: ld.lld --relax -T lds a.o -o a # RUN: llvm-objdump -d --no-show-raw-insn a | FileCheck %s --check-prefixes=RELAX,RELAX-MID ## Unsure whether this needs a diagnostic. GNU ld allows this. -# RUN: ld.lld -T lds -pie a.o -o a.pie +# RUN: ld.lld --relax -T lds -pie a.o -o a.pie # RUN: llvm-objdump -d --no-show-raw-insn a.pie | FileCheck %s --check-prefixes=RELAX,RELAX-MID -# RUN: ld.lld -T lds -pie -z notext -z ifunc-noplt a.o -o a.ifunc-noplt +# RUN: ld.lld --relax -T lds -pie -z notext -z ifunc-noplt a.o -o a.ifunc-noplt # RUN: llvm-objdump -d --no-show-raw-insn a.ifunc-noplt | FileCheck %s --check-prefixes=RELAX,NORELAX-MID # RELAX-LABEL: <_start>: diff --git a/lld/test/ELF/loongarch-relax-call36.s b/lld/test/ELF/loongarch-relax-call36.s index 57ed214c9eb2e..bda0c4f05da91 100644 --- a/lld/test/ELF/loongarch-relax-call36.s +++ b/lld/test/ELF/loongarch-relax-call36.s @@ -4,12 +4,12 @@ # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.64.o # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax b.s -o b.64.o -# RUN: ld.lld -shared -soname=b.so b.64.o -o b.64.so -# RUN: ld.lld -T lds a.64.o b.64.so -o 64 +# RUN: ld.lld --relax -shared -soname=b.so b.64.o -o b.64.so +# RUN: ld.lld --relax -T lds a.64.o b.64.so -o 64 # RUN: llvm-objdump -td --no-show-raw-insn 64 | FileCheck %s --check-prefix=RELAX ## --no-relax disables relaxation. -# RUN: ld.lld -T lds a.64.o b.64.so --no-relax -o 64.norelax +# RUN: ld.lld --no-relax -T lds a.64.o b.64.so -o 64.norelax # RUN: llvm-objdump -td --no-show-raw-insn 64.norelax | FileCheck %s --check-prefix=NORELAX # RELAX: {{0*}}00010000 g .text {{0*}}0000001c _start diff --git a/lld/test/ELF/loongarch-relax-emit-relocs-2.s b/lld/test/ELF/loongarch-relax-emit-relocs-2.s index 31cae939eca71..eddfc46b1ad08 100644 --- a/lld/test/ELF/loongarch-relax-emit-relocs-2.s +++ b/lld/test/ELF/loongarch-relax-emit-relocs-2.s @@ -3,15 +3,15 @@ ## Call36 and tail36 need LA64 basic integer, so they donot have 32-bit version. # RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o -# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 +# RUN: ld.lld --relax -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 # RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefix=RELAX ## -r should keep original relocations. -# RUN: ld.lld -r %t.64.o -o %t.64.r +# RUN: ld.lld --relax -r %t.64.o -o %t.64.r # RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR ## --no-relax should keep original relocations. -# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax +# RUN: ld.lld --no-relax -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64.norelax # RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefix=NORELAX # RELAX: 00010000 <_start>: >From b9c2ea1ad26ad6c81213ee9d563bd1448ed4a097 Mon Sep 17 00:00:00 2001 From: yangzhaoxin <yangzhao...@loongson.cn> Date: Fri, 14 Feb 2025 09:43:07 +0800 Subject: [PATCH 4/5] Revert "Modify test. Add the option --relax." This reverts commit f2aae15f701863d03edd32657824a97f66696e8d. --- lld/test/ELF/loongarch-relax-call36-2.s | 6 +++--- lld/test/ELF/loongarch-relax-call36.s | 6 +++--- lld/test/ELF/loongarch-relax-emit-relocs-2.s | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lld/test/ELF/loongarch-relax-call36-2.s b/lld/test/ELF/loongarch-relax-call36-2.s index 71650aefe9432..1c216a9bdc35e 100644 --- a/lld/test/ELF/loongarch-relax-call36-2.s +++ b/lld/test/ELF/loongarch-relax-call36-2.s @@ -2,14 +2,14 @@ # RUN: rm -rf %t && split-file %s %t && cd %t # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.o -# RUN: ld.lld --relax -T lds a.o -o a +# RUN: ld.lld -T lds a.o -o a # RUN: llvm-objdump -d --no-show-raw-insn a | FileCheck %s --check-prefixes=RELAX,RELAX-MID ## Unsure whether this needs a diagnostic. GNU ld allows this. -# RUN: ld.lld --relax -T lds -pie a.o -o a.pie +# RUN: ld.lld -T lds -pie a.o -o a.pie # RUN: llvm-objdump -d --no-show-raw-insn a.pie | FileCheck %s --check-prefixes=RELAX,RELAX-MID -# RUN: ld.lld --relax -T lds -pie -z notext -z ifunc-noplt a.o -o a.ifunc-noplt +# RUN: ld.lld -T lds -pie -z notext -z ifunc-noplt a.o -o a.ifunc-noplt # RUN: llvm-objdump -d --no-show-raw-insn a.ifunc-noplt | FileCheck %s --check-prefixes=RELAX,NORELAX-MID # RELAX-LABEL: <_start>: diff --git a/lld/test/ELF/loongarch-relax-call36.s b/lld/test/ELF/loongarch-relax-call36.s index bda0c4f05da91..57ed214c9eb2e 100644 --- a/lld/test/ELF/loongarch-relax-call36.s +++ b/lld/test/ELF/loongarch-relax-call36.s @@ -4,12 +4,12 @@ # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.64.o # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax b.s -o b.64.o -# RUN: ld.lld --relax -shared -soname=b.so b.64.o -o b.64.so -# RUN: ld.lld --relax -T lds a.64.o b.64.so -o 64 +# RUN: ld.lld -shared -soname=b.so b.64.o -o b.64.so +# RUN: ld.lld -T lds a.64.o b.64.so -o 64 # RUN: llvm-objdump -td --no-show-raw-insn 64 | FileCheck %s --check-prefix=RELAX ## --no-relax disables relaxation. -# RUN: ld.lld --no-relax -T lds a.64.o b.64.so -o 64.norelax +# RUN: ld.lld -T lds a.64.o b.64.so --no-relax -o 64.norelax # RUN: llvm-objdump -td --no-show-raw-insn 64.norelax | FileCheck %s --check-prefix=NORELAX # RELAX: {{0*}}00010000 g .text {{0*}}0000001c _start diff --git a/lld/test/ELF/loongarch-relax-emit-relocs-2.s b/lld/test/ELF/loongarch-relax-emit-relocs-2.s index eddfc46b1ad08..31cae939eca71 100644 --- a/lld/test/ELF/loongarch-relax-emit-relocs-2.s +++ b/lld/test/ELF/loongarch-relax-emit-relocs-2.s @@ -3,15 +3,15 @@ ## Call36 and tail36 need LA64 basic integer, so they donot have 32-bit version. # RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o -# RUN: ld.lld --relax -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 +# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 # RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefix=RELAX ## -r should keep original relocations. -# RUN: ld.lld --relax -r %t.64.o -o %t.64.r +# RUN: ld.lld -r %t.64.o -o %t.64.r # RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR ## --no-relax should keep original relocations. -# RUN: ld.lld --no-relax -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64.norelax +# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax # RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefix=NORELAX # RELAX: 00010000 <_start>: >From 11018299e150c7c6f20fc47ff2673d8f963eb199 Mon Sep 17 00:00:00 2001 From: yangzhaoxin <yangzhao...@loongson.cn> Date: Fri, 14 Feb 2025 11:23:30 +0800 Subject: [PATCH 5/5] Fixes for reviews. --- lld/ELF/Arch/LoongArch.cpp | 8 +-- lld/test/ELF/loongarch-relax-call36-2.s | 2 + lld/test/ELF/loongarch-relax-call36.s | 1 + lld/test/ELF/loongarch-relax-emit-relocs-2.s | 61 -------------------- lld/test/ELF/loongarch-relax-emit-relocs.s | 43 +++++++++++--- 5 files changed, 43 insertions(+), 72 deletions(-) delete mode 100644 lld/test/ELF/loongarch-relax-emit-relocs-2.s diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp index 0aa0cf5b657a0..c1e2229c3f9a7 100644 --- a/lld/ELF/Arch/LoongArch.cpp +++ b/lld/ELF/Arch/LoongArch.cpp @@ -840,13 +840,13 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i, // b/bl foo static void relaxCall36(Ctx &ctx, const InputSection &sec, size_t i, uint64_t loc, Relocation &r, uint32_t &remove) { - const uint64_t symLocal = + const uint64_t dest = (r.expr == R_PLT_PC ? r.sym->getPltVA(ctx) : r.sym->getVA(ctx)) + r.addend; - const int64_t distance = symLocal - loc; - // Check if the distance aligns 4 bytes or exceeds the range of b[l]. - if ((distance & 0x3) != 0 || !isInt<28>(distance)) + const int64_t displace = dest - loc; + // Check if the displace aligns 4 bytes or exceeds the range of b[l]. + if ((displace & 0x3) != 0 || !isInt<28>(displace)) return; const uint32_t nextInsn = read32le(sec.content().data() + r.offset + 4); diff --git a/lld/test/ELF/loongarch-relax-call36-2.s b/lld/test/ELF/loongarch-relax-call36-2.s index 1c216a9bdc35e..482eed2ebd111 100644 --- a/lld/test/ELF/loongarch-relax-call36-2.s +++ b/lld/test/ELF/loongarch-relax-call36-2.s @@ -1,4 +1,6 @@ # REQUIRES: loongarch +## Relax R_LARCH_CALL36. This test tests boundary cases and some special symbols. + # RUN: rm -rf %t && split-file %s %t && cd %t # RUN: llvm-mc -filetype=obj -triple=loongarch64 -mattr=+relax a.s -o a.o diff --git a/lld/test/ELF/loongarch-relax-call36.s b/lld/test/ELF/loongarch-relax-call36.s index 57ed214c9eb2e..0f0ba26b15f30 100644 --- a/lld/test/ELF/loongarch-relax-call36.s +++ b/lld/test/ELF/loongarch-relax-call36.s @@ -1,4 +1,5 @@ # REQUIRES: loongarch +## Relax R_LARCH_CALL36, which involves the macro instructions call36/tail36. # RUN: rm -rf %t && split-file %s %t && cd %t diff --git a/lld/test/ELF/loongarch-relax-emit-relocs-2.s b/lld/test/ELF/loongarch-relax-emit-relocs-2.s deleted file mode 100644 index 31cae939eca71..0000000000000 --- a/lld/test/ELF/loongarch-relax-emit-relocs-2.s +++ /dev/null @@ -1,61 +0,0 @@ -# REQUIRES: loongarch -## Test that we can handle --emit-relocs while relaxing. -## Call36 and tail36 need LA64 basic integer, so they donot have 32-bit version. - -# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o -# RUN: ld.lld -Ttext=0x10000 --emit-relocs %t.64.o -o %t.64 -# RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefix=RELAX - -## -r should keep original relocations. -# RUN: ld.lld -r %t.64.o -o %t.64.r -# RUN: llvm-objdump -dr %t.64.r | FileCheck %s --check-prefix=CHECKR - -## --no-relax should keep original relocations. -# RUN: ld.lld -Ttext=0x10000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax -# RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefix=NORELAX - -# RELAX: 00010000 <_start>: -# RELAX-NEXT: bl 0 -# RELAX-NEXT: R_LARCH_B26 _start -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: b -4 -# RELAX-NEXT: R_LARCH_B26 _start -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: nop -# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc -# RELAX-NEXT: nop -# RELAX-NEXT: ret - -# CHECKR: <_start>: -# CHECKR-NEXT: pcaddu18i $ra, 0 -# CHECKR-NEXT: R_LARCH_CALL36 _start -# CHECKR-NEXT: R_LARCH_RELAX *ABS* -# CHECKR-NEXT: jirl $ra, $ra, 0 -# CHECKR-NEXT: pcaddu18i $t0, 0 -# CHECKR-NEXT: R_LARCH_CALL36 _start -# CHECKR-NEXT: R_LARCH_RELAX *ABS* -# CHECKR-NEXT: jr $t0 -# CHECKR-NEXT: nop -# CHECKR-NEXT: R_LARCH_ALIGN *ABS*+0xc -# CHECKR-NEXT: nop -# CHECKR-NEXT: nop -# CHECKR-NEXT: ret - -# NORELAX: <_start>: -# NORELAX-NEXT: pcaddu18i $ra, 0 -# NORELAX-NEXT: R_LARCH_CALL36 _start -# NORELAX-NEXT: R_LARCH_RELAX *ABS* -# NORELAX-NEXT: jirl $ra, $ra, 0 -# NORELAX-NEXT: pcaddu18i $t0, 0 -# NORELAX-NEXT: R_LARCH_CALL36 _start -# NORELAX-NEXT: R_LARCH_RELAX *ABS* -# NORELAX-NEXT: jirl $zero, $t0, -8 -# NORELAX-NEXT: ret -# NORELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc - -.global _start -_start: - call36 _start - tail36 $t0, _start - .p2align 4 - ret diff --git a/lld/test/ELF/loongarch-relax-emit-relocs.s b/lld/test/ELF/loongarch-relax-emit-relocs.s index a02cd272aba5b..d7f444470f0f9 100644 --- a/lld/test/ELF/loongarch-relax-emit-relocs.s +++ b/lld/test/ELF/loongarch-relax-emit-relocs.s @@ -2,11 +2,11 @@ ## Test that we can handle --emit-relocs while relaxing. # RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax %s -o %t.32.o -# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s -o %t.64.o +# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax --defsym ELF64=1 %s -o %t.64.o # RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs --relax %t.32.o -o %t.32 # RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs --relax %t.64.o -o %t.64 -# RUN: llvm-objdump -dr %t.32 | FileCheck %s --check-prefix=RELAX -# RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefix=RELAX +# RUN: llvm-objdump -dr %t.32 | FileCheck %s --check-prefixes=RELAX,RELAX32 +# RUN: llvm-objdump -dr %t.64 | FileCheck %s --check-prefixes=RELAX,RELAX64 ## -r should keep original relocations. # RUN: ld.lld --relax -r %t.64.o -o %t.64.r @@ -27,10 +27,19 @@ # RELAX-NEXT: R_LARCH_RELAX *ABS* # RELAX-NEXT: R_LARCH_PCREL20_S2 _start # RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: nop -# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc -# RELAX-NEXT: nop -# RELAX-NEXT: ret +# RELAX32-NEXT: nop +# RELAX32-NEXT: R_LARCH_ALIGN *ABS*+0xc +# RELAX32-NEXT: nop +# RELAX32-NEXT: ret + +# RELAX64-NEXT: bl -8 +# RELAX64-NEXT: R_LARCH_B26 _start +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: b -12 +# RELAX64-NEXT: R_LARCH_B26 _start +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: ret +# RELAX64-NEXT: R_LARCH_ALIGN *ABS*+0xc # NORELAX: <_start>: # NORELAX-NEXT: pcalau12i $a0, 0 @@ -45,6 +54,14 @@ # NORELAX-NEXT: ld.d $a0, $a0, 0 # NORELAX-NEXT: R_LARCH_GOT_PC_LO12 _start # NORELAX-NEXT: R_LARCH_RELAX *ABS* +# NORELAX-NEXT: pcaddu18i $ra, 0 +# NORELAX-NEXT: R_LARCH_CALL36 _start +# NORELAX-NEXT: R_LARCH_RELAX *ABS* +# NORELAX-NEXT: jirl $ra, $ra, -16 +# NORELAX-NEXT: pcaddu18i $a0, 0 +# NORELAX-NEXT: R_LARCH_CALL36 _start +# NORELAX-NEXT: R_LARCH_RELAX *ABS* +# NORELAX-NEXT: jirl $zero, $a0, -24 # NORELAX-NEXT: ret # NORELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc @@ -61,6 +78,14 @@ # CHECKR-NEXT: ld.d $a0, $a0, 0 # CHECKR-NEXT: R_LARCH_GOT_PC_LO12 _start # CHECKR-NEXT: R_LARCH_RELAX *ABS* +# CHECKR-NEXT: pcaddu18i $ra, 0 +# CHECKR-NEXT: R_LARCH_CALL36 _start +# CHECKR-NEXT: R_LARCH_RELAX *ABS* +# CHECKR-NEXT: jirl $ra, $ra, 0 +# CHECKR-NEXT: pcaddu18i $a0, 0 +# CHECKR-NEXT: R_LARCH_CALL36 _start +# CHECKR-NEXT: R_LARCH_RELAX *ABS* +# CHECKR-NEXT: jr $a0 # CHECKR-NEXT: nop # CHECKR-NEXT: R_LARCH_ALIGN *ABS*+0xc # CHECKR-NEXT: nop @@ -71,5 +96,9 @@ _start: la.pcrel $a0, _start la.got $a0, _start +.ifdef ELF64 + call36 _start + tail36 $a0, _start +.endif .p2align 4 ret _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits