[lld] [RISCV] Disable gp relaxation if part of object unreachable (PR #72655)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 18 14:46:09 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()))
+ return;
+
+ // However, if the addend is non-zero, the LO12 relocations may be accessing
+ // the range [HI-alignAdjust-1, HI+alignAdjust].
+ if (r.addend != 0 && (!isInt<12>(hiAddr - alignAdjust - 1 - gp->getVA()) ||
----------------
MaskRay wrote:
I want to hear from others about the reliability.
Ultimately I hope that we can derive some rules that are simple (ideally no `addend==0`/`addend!=0` distinction), even if we give up some legitimate opportunities.
https://github.com/llvm/llvm-project/pull/72655
More information about the llvm-commits
mailing list