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

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 27 05:26:16 PST 2023


================
@@ -651,6 +651,20 @@ 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. We need to make sure that
+  // all of the possible accesses are relaxed or none are. This prevents
+  // relaxing the hi relocation and being unable to relax one of the low
+  // relocations. 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 (!isInt<12>(r.sym->getVA() + alignAdjust - gp->getVA()))
----------------
nemanjai wrote:

This is absolutely true. If the addend on the `HI20` is higher than the addend on the `LO12`, there is no guarantee whatsoever that we can't get into the same situation (relaxing and removing the HI instruction even though we need it for the LO instruction). Of course, this isn't new with this patch, the issue already existed.
I think that to be on the safe side, we should reject a relaxation of the `HI20` if the addend is non-zero. What do you think?

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


More information about the llvm-commits mailing list