[lld] [RISCV] Disable gp relaxation if part of object unreachable (PR #72655)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 14 23:09:59 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()))
----------------
MaskRay wrote:

R_RISCV_HI20 and R_RISCV_LO12_I/R_RISCV_LO12_S should have consistent decisions on whether to do relaxation. Placing the condition only at R_RISCV_HI20 could lead to inconsistent results.

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


More information about the llvm-commits mailing list