[lld] [RISCV] Disable gp relaxation if part of object unreachable (PR #72655)
Nemanja Ivanovic via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 18 02:32:19 PST 2023
================
@@ -651,12 +651,38 @@ static void relaxHi20Lo12(const InputSection &sec, size_t i, uint64_t loc,
if (!isInt<12>(r.sym->getVA(r.addend) - gp->getVA()))
return;
+ // The symbol may be accessed in multiple pieces with different addends.
+ // If we are relaxing the HI20 relocation, we need to ensure that we only
+ // relax (and delete the instruction) if all possible LO12 relocations
+ // that depend on it will be relaxable. The compiler will only access multiple
+ // pieces of an object with low relocations on the memory op if the alignment
+ // allows it. Therefore it should suffice to check that the smaller of the
+ // alignment and size can be reached from GP.
+ uint32_t alignAdjust =
+ r.sym->getOutputSection() ? r.sym->getOutputSection()->addralign : 0;
+ alignAdjust = std::min<uint32_t>(alignAdjust, r.sym->getSize());
+ if (alignAdjust)
+ alignAdjust--;
+
switch (r.type) {
- case R_RISCV_HI20:
+ case R_RISCV_HI20: {
+ uint64_t hiAddr = r.sym->getVA(r.addend);
+ // If the addend is zero, the LO12 relocations can only be accessing the
+ // range [base, base+alignAdjust] (where base == r.sym->getVA()).
+ if (r.addend == 0 && !isInt<12>(hiAddr + alignAdjust - gp->getVA()))
----------------
nemanjai wrote:
The logic here was that only this direction involves a functional problem. Relaxing the `LO12` and not relaxing the `HI20` leaves a redundant `HI20`, but that's about it. Whereas the other way is the crux of the problem. However, if you'd prefer that I implement the `LO12` pessimistically as well, I am not against it.
https://github.com/llvm/llvm-project/pull/72655
More information about the llvm-commits
mailing list