[llvm-branch-commits] [lld] [lld][LoongArch] Relax TLS LE/GD/LD (PR #123600)

WÁNG Xuěruì via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Feb 16 17:44:04 PST 2025


================
@@ -863,6 +874,35 @@ static void relaxCall36(Ctx &ctx, const InputSection &sec, size_t i,
   }
 }
 
+// Relax code sequence.
+// From:
+//   lu12i.w $rd, %le_hi20_r(sym)
+//   add.w/d $rd, $rd, $tp, %le_add_r(sym)
+//   addi/ld/st.w/d $rd, $rd, %le_lo12_r(sym)
+// To:
+//   addi/ld/st.w/d $rd, $tp, %le_lo12_r(sym)
+static void relaxTlsLe(Ctx &ctx, const InputSection &sec, size_t i,
+                       uint64_t loc, Relocation &r, uint32_t &remove) {
+  uint64_t val = r.sym->getVA(ctx, r.addend);
+  // Check if the val exceeds the range of addi/ld/st.
+  if (!isInt<12>(val))
+    return;
+  uint32_t currInsn = read32le(sec.content().data() + r.offset);
+  switch (r.type) {
+  case R_LARCH_TLS_LE_HI20_R:
+  case R_LARCH_TLS_LE_ADD_R:
+    sec.relaxAux->relocTypes[i] = R_LARCH_RELAX;
+    remove = 4;
+    break;
+  case R_LARCH_TLS_LE_LO12_R:
+    currInsn =
+        insn(extractBits(currInsn, 31, 22) << 22, getD5(currInsn), R_TP, 0);
+    sec.relaxAux->writes.push_back(currInsn);
----------------
xen0n wrote:

It's probably better to add a `setJ` helper (near the `setJ20` helper maybe) and use it instead, so that the expression becomes shorter and no need to change the `currInsn` variable.

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


More information about the llvm-branch-commits mailing list