[lld] [llvm] [RISCV][LLD] Add RISCV zcmt optimise in linker relaxation (PR #77884)

Simon Cook via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 6 05:11:32 PST 2024


================
@@ -731,6 +751,30 @@ void elf::initSymbolAnchors() {
   }
 }
 
+static bool relaxTableJump(const InputSection &sec, size_t i, uint64_t loc,
+                           Relocation &r, uint32_t &remove) {
+  if (!in.riscvTableJumpSection || !in.riscvTableJumpSection->isFinalized)
+    return false;
+
+  const auto jalr = sec.contentMaybeDecompress().data()[r.offset + 4];
+  const uint8_t rd = extractBits(jalr, 11, 7);
----------------
simonpcook wrote:

1. The loading value of this `jalr` register is indexing an array of `uint8_t`s so actually is only getting the least significant bit of `rd`, so any `jalr` using anything other than zero/ra will be converted. This isn't being picked up in tests because the encoding of ra is 1.
2. This assumes that the `jalr` instruction is 4 bytes after the relocation offset. This is true for `R_RISCV_CALL`, but `R_RISCV_JAL` relocations are also processed via this function. This means the instruction after the `jal` instruction is both processed for its bits in the `rd` field and deleted if the branch target is in the table.

The same issues appear in `scanTableJumpEntries`, but commented once for brevity.

https://github.com/llvm/llvm-project/pull/77884


More information about the llvm-commits mailing list