[lld] [lld][LoongArch] Relax call36/tail36: R_LARCH_CALL36 (PR #123576)
Zhaoxin Yang via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 17 23:47:30 PST 2025
================
@@ -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 dest =
+ (r.expr == R_PLT_PC ? r.sym->getPltVA(ctx) : r.sym->getVA(ctx)) +
+ r.addend;
+
+ 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);
----------------
ylzsx wrote:
After further consideration and revisiting the manual again(https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc),

the generated `pcaddu18i` and `jirl` by GCC and Clang must be adjacent.
As for the interoperability you mentioned, `lld` handles instruction sequences generated by `gas`. And `gas` should not generate non-contiguous instruction sequences either. Therefore, we think that adding a check in `lld` is unnecessary.
Additionally, if `jirl` check is added here, other relaxations (such as R_LARCH_{PCALA,GOT_PC}_{HI20,LO12}, etc) would also need to check the instructions, which contradicts the principle of avoiding instruction checks unless absolutely necessary.
https://github.com/llvm/llvm-project/pull/123576
More information about the llvm-commits
mailing list