[PATCH] D146554: [BOLT][RISCV] Implement R_RISCV_ADD32/SUB32

Job Noorman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 21 01:18:15 PDT 2023


jobnoorman added inline comments.


================
Comment at: bolt/lib/Rewrite/RewriteInstance.cpp:2906
+      (opts::ForceToDataRelocations && checkMaxDataRelocations()) ||
+      // RISC-V has ADD/SUB data-to-data relocations
+      BC->isRISCV())
----------------
rafauler wrote:
> Aren't these data-to-code relocs? (BOLT doesn't need to update data-to-data relocs).
> Aren't these data-to-code relocs?

The relevant relocations in the `reloc-jt.s` test case look like this:

```
Relocation section '.rela.data' at offset 0x2068 contains 2 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000002000  000300000023 R_RISCV_ADD32     000000000000100e .LBB0_1 + 0
000000002000  000200000027 R_RISCV_SUB32     0000000000002000 .LJTI0_0 + 0
```

`.LJTI0_0` is a label in `.data` so the `R_RISCV_SUB32` is a data-to-data relocation.

> BOLT doesn't need to update data-to-data relocs

iiuc, BOLT //usually// doesn't need to update data-to-data relocs because the `.data` section is not relocated, correct?

In this case, however, the data-to-data reloc gets composed (see D146546) with a data-to-code reloc (`R_RISCV_ADD32`) so BOLT needs to process it to ensure the linker can properly update the value.

The condition here might be a bit coarse-grained, though, as //all// data-to-data relocs on RISC-V will now be processed even though it might not always be necessary. I suppose this doesn't really matter as the linker will just overwrite data contents with its original value. Or am I missing something here?


================
Comment at: bolt/test/RISCV/reloc-jt.s:13-14
+.LBB0_0:
+  auipc a1, %pcrel_hi(.LJTI0_0)
+  addi a1, a1, %pcrel_lo(.LBB0_0)
+  lw a0, (a1)
----------------
rafauler wrote:
> I'm not sure I get that. Aren't the two relocs supposed to point to the same symbol (.LJTI0_0)?
> Aren't the two relocs supposed to point to the same symbol (.LJTI0_0)?

No, they aren't, but this is something that also used to confuse me :)

Creating a 32-bit PC-relative address on RISC-V works as follows:

1. `auipc` ("add upper immediate to PC") with a `R_RISCV_PCREL_HI20` reloc pointing to the target symbol (`.LJTI0_0` in this case). The result only has the upper 20-bits filled, the lower 12 are set to 0.
2. `addi` (or another instruction with a 12-bit immediate, like `lw`) with a `R_RISCV_PCREL_LO12_I` pointing to the corresponding `auipc` (`.LBB0_0` in this case) to fill in the lower 12-bits.

The psABI has a [good explanation](https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses) for why it works this way (an important reason is that the `auipc` and `addi` are not necessarily consecutive).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146554/new/

https://reviews.llvm.org/D146554



More information about the llvm-commits mailing list