[llvm-branch-commits] [LoongArch] Generate more PCRel relocations for resolvable sub-symbols (PR #211754)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jul 24 02:19:19 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: wanglei (wangleiat)

<details>
<summary>Changes</summary>

Use PC-relative relocations when the sub-symbol offset can be resolved
during assembly, avoiding ADD/SUB relocation pairs.


---
Full diff: https://github.com/llvm/llvm-project/pull/211754.diff


2 Files Affected:

- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp (+17-20) 
- (modified) llvm/test/MC/LoongArch/Relocations/sub-expr.s (+2-4) 


``````````diff
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 0b988a5257253..392f2ddd191a1 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -414,38 +414,31 @@ void LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
 
     assert(Target.getSpecifier() == 0 &&
            "relocatable SymA-SymB cannot have relocation specifier");
-    std::pair<MCFixupKind, MCFixupKind> FK;
     const MCSymbol &SA = *Target.getAddSym();
     const MCSymbol &SB = *Target.getSubSym();
 
-    bool force = !SA.isInSection() || !SB.isInSection();
-    if (!force) {
-      const MCSection &SecA = SA.getSection();
-      const MCSection &SecB = SB.getSection();
-      const MCSection &SecCur = *F.getParent();
-
-      // To handle the case of A - B which B is same section with the current,
-      // generate PCRel relocations is better than ADD/SUB relocation pair.
-      // We can resolve it as A - PC + PC - B. The A - PC will be resolved
-      // as a PCRel relocation, while PC - B will serve as the addend.
-      // If the linker relaxation is disabled, it can be done directly since
-      // PC - B is constant. Otherwise, we should evaluate whether PC - B
-      // is constant. If it can be resolved as PCRel, use Fallback which
-      // generates R_LARCH_{32,64}_PCREL relocation later.
-      if (&SecA != &SecB && &SecB == &SecCur &&
-          isPCRelFixupResolved(Target.getSubSym(), F))
-        return Fallback();
+    // Check if SubSym (SB) is in the same section as the current fragment and
+    // the PC-relative offset can be resolved. In that case, we can generate a
+    // PCRel relocation (A - PC + PC - B) instead of ADD/SUB pairs.
+    auto CanResolveSubSymAsPCRel = [&]() {
+      return SB.isInSection() && &SB.getSection() == F.getParent() &&
+             isPCRelFixupResolved(&SB, F);
+    };
 
-      if (&SecA == &SecB) {
+    if (SA.isInSection() && SB.isInSection()) {
+      const MCSection &SecA = SA.getSection();
+      if (&SecA == &SB.getSection()) {
         // If the section is not linker-relaxable, or if the fixup is in a .dwo
         // section (where relocations are forbidden), we must resolve the
         // difference directly. The computed Value in evaluateFixup is correct
         // based on the current layout.
-        if (!SecA.isLinkerRelaxable() || SecCur.getName().ends_with(".dwo"))
+        if (!SecA.isLinkerRelaxable() ||
+            F.getParent()->getName().ends_with(".dwo"))
           return;
       }
     }
 
+    std::pair<MCFixupKind, MCFixupKind> FK;
     switch (Fixup.getKind()) {
     case FK_Data_1:
       FK = getRelocPairForSize(8);
@@ -454,9 +447,13 @@ void LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
       FK = getRelocPairForSize(16);
       break;
     case FK_Data_4:
+      if (CanResolveSubSymAsPCRel())
+        return Fallback();
       FK = getRelocPairForSize(32);
       break;
     case FK_Data_8:
+      if (CanResolveSubSymAsPCRel())
+        return Fallback();
       FK = getRelocPairForSize(64);
       break;
     case FK_Data_leb128:
diff --git a/llvm/test/MC/LoongArch/Relocations/sub-expr.s b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
index 2989bfd9135e5..78305852d1a50 100644
--- a/llvm/test/MC/LoongArch/Relocations/sub-expr.s
+++ b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
@@ -40,10 +40,8 @@
 # CHECK-NEXT:       0x38 R_LARCH_SUB32 y 0x0
 # CHECK-NEXT:       0x3C R_LARCH_32_PCREL - 0xBEEF
 # CHECK-NEXT:       0x40 R_LARCH_64_PCREL - 0xBEEF
-# CHECK-NEXT:       0x48 R_LARCH_ADD32 extsym 0x0
-# CHECK-NEXT:       0x48 R_LARCH_SUB32 .Ltmp1 0x0
-# CHECK-NEXT:       0x4C R_LARCH_ADD64 extsym 0x0
-# CHECK-NEXT:       0x4C R_LARCH_SUB64 .Ltmp1 0x0
+# CHECK-NEXT:       0x48 R_LARCH_32_PCREL extsym 0x8
+# CHECK-NEXT:       0x4C R_LARCH_64_PCREL extsym 0xC
 
 # CHECK-NEXT:     }
 # NORELAX-NEXT:   Section ({{.*}}) .rela.sy {

``````````

</details>


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


More information about the llvm-branch-commits mailing list