Skip to content

[lld][LoongArch] Support relaxation during IE to LE conversion #123702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 11, 2025
10 changes: 9 additions & 1 deletion lld/ELF/Arch/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,11 @@ static bool relax(Ctx &ctx, InputSection &sec) {
if (relaxable(relocs, i))
relaxTlsLe(ctx, sec, i, loc, r, remove);
break;
case R_LARCH_TLS_IE_PC_HI20:
if (relaxable(relocs, i) && r.expr == R_RELAX_TLS_IE_TO_LE &&
isUInt<12>(r.sym->getVA(ctx, r.addend)))
remove = 4;
break;
}

// For all anchors whose offsets are <= r.offset, they are preceded by
Expand Down Expand Up @@ -1048,7 +1053,7 @@ void LoongArch::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
secAddr += s->outSecOff;
else if (auto *ehIn = dyn_cast<EhInputSection>(&sec))
secAddr += ehIn->getParent()->outSecOff;
bool isExtreme = false;
bool isExtreme = false, isRelax = false;
const MutableArrayRef<Relocation> relocs = sec.relocs();
for (size_t i = 0, size = relocs.size(); i != size; ++i) {
Relocation &rel = relocs[i];
Expand Down Expand Up @@ -1077,6 +1082,9 @@ void LoongArch::relocateAlloc(InputSectionBase &sec, uint8_t *buf) const {
bits);
relocateNoSym(loc, rel.type, val);
} else {
isRelax = relaxable(relocs, i);
if (isRelax && rel.type == R_LARCH_TLS_IE_PC_HI20 && isUInt<12>(val))
continue;
tlsIeToLe(loc, rel, val);
}
continue;
Expand Down
28 changes: 25 additions & 3 deletions lld/test/ELF/loongarch-relax-tls-ie.s
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s -o %t.o

## FIXME: IE relaxation has not yet been implemented.
## --relax/--no-relax has the same result. Also check --emit-relocs.
## Also check --emit-relocs.
# RUN: ld.lld --emit-relocs %t.o -o %t
# RUN: llvm-readelf -x .got %t 2>&1 | FileCheck --check-prefix=LE-GOT %s
# RUN: llvm-objdump -dr --no-show-raw-insn %t | FileCheck --check-prefixes=LE %s
# RUN: llvm-objdump -dr --no-show-raw-insn %t | FileCheck --check-prefixes=LER %s

# RUN: ld.lld --emit-relocs --no-relax %t.o -o %t.norelax
# RUN: llvm-readelf -x .got %t.norelax 2>&1 | FileCheck --check-prefix=LE-GOT %s
Expand Down Expand Up @@ -42,6 +41,29 @@
# LE-NEXT: add.d $a2, $a2, $tp
# LE-NEXT: add.d $a3, $a3, $tp

# LER: 20158: ori $a0, $zero, 4095
# LER-NEXT: R_LARCH_TLS_IE_PC_HI20 a
# LER-NEXT: R_LARCH_RELAX *ABS*
# LER-NEXT: R_LARCH_TLS_IE_PC_LO12 a
# LER-NEXT: R_LARCH_RELAX *ABS*
# LER-NEXT: add.d $a0, $a0, $tp
# LER-NEXT: 20160: lu12i.w $a1, 1
# LER-NEXT: R_LARCH_TLS_IE_PC_HI20 b
# LER-NEXT: ori $a1, $a1, 0
# LER-NEXT: R_LARCH_TLS_IE_PC_LO12 b
# LER-NEXT: add.d $a1, $a1, $tp
# LER-NEXT: 2016c: lu12i.w $a3, 1
# LER-NEXT: R_LARCH_TLS_IE_PC_HI20 a
# LER-NEXT: R_LARCH_RELAX *ABS*
# LER-NEXT: R_LARCH_TLS_IE_PC_HI20 b
# LER-NEXT: R_LARCH_RELAX *ABS*
# LER-NEXT: ori $a2, $zero, 4095
# LER-NEXT: R_LARCH_TLS_IE_PC_LO12 a
# LER-NEXT: ori $a3, $a3, 0
# LER-NEXT: R_LARCH_TLS_IE_PC_LO12 b
# LER-NEXT: add.d $a2, $a2, $tp
# LER-NEXT: add.d $a3, $a3, $tp

la.tls.ie $a0, a # relax
add.d $a0, $a0, $tp

Expand Down