I noticed that the calculation of the Relocation Functions for R_RISCV_HI20 and R_RISCV_PCREL_HI20 are the same. This made me wonder because the RISC-V ELF documentation documents the formula S + A for R_RISCV_HI20 and S + A - P for R_RISCV_PCREL_HI20 in Table 3.
So I wanted to kindly ask where the program counter is subtracted?
The code you link to in RISCV::relocate is applying a calculated value to the instructions themselves.
This is called from relocateAlloc, which for those relocations, first calls sec.getRelocTargetVA(ctx, rel, secAddr + rel.offset), and then passes the result of that call into the third argument of RISCV::relocate (val).
In getRelocTargetVA, the switch uses rel.expr, rather than rel.type - for R_RISCV_HI20, the rel.expr is R_ABS, whereas for R_RISCV_PCREL_HI20, the rel.expr is R_PC. R_ABS is handled in a reasonably straightforward way (just get the VA), R_PC has some complexity because of undefined weak symbols, but broadly you can see that the handling for R_PC gets the VA and subtracts p, the current location, as you are expecting.