[llvm] c9e8899 - [LoongArch] Generate more PCRel relocations for resolvable sub-symbols

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 10 18:07:30 PDT 2026


Author: wanglei
Date: 2026-09-11T09:07:25+08:00
New Revision: c9e8899e31dba827a9c738252de1762f3b6fd3df

URL: https://github.com/llvm/llvm-project/commit/c9e8899e31dba827a9c738252de1762f3b6fd3df
DIFF: https://github.com/llvm/llvm-project/commit/c9e8899e31dba827a9c738252de1762f3b6fd3df.diff

LOG: [LoongArch] Generate more PCRel relocations for resolvable sub-symbols

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

Fixes #210052

Reviewers: SixWeining, MaskRay

Reviewed By: MaskRay

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

Added: 
    

Modified: 
    llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
    llvm/test/MC/LoongArch/Relocations/sub-expr.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 3e0ad792d6fab..4581da3c7b9c3 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -407,48 +407,25 @@ bool LoongArchAsmBackend::isPCRelFixupResolved(const MCSymbol *SymA,
 void LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
                                    const MCValue &Target, uint64_t &FixedValue,
                                    bool IsResolved) {
-  auto Fallback = [&]() {
-    MCAsmBackend::maybeAddReloc(F, Fixup, Target, FixedValue, IsResolved);
-    return;
-  };
   uint64_t FixedValueA, FixedValueB;
   if (Target.getSubSym()) {
-    // It's possible for Target to have (SymB != nullptr && SymA == nullptr).
-    // Go to the fallback path when we encounter this. See also #196927.
-    if (!Target.getAddSym())
-      return Fallback();
-
     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();
-
-      // In SecA == SecB case. If the section is not linker-relaxable, the
-      // FixedValue has already been calculated out in evaluateFixup,
-      // return true and avoid record relocations.
-      if (&SecA == &SecB && !SecA.isLinkerRelaxable())
-        return;
-    }
+    // For generate R_LARCH_{32/64}_PCREL relocation.
+    auto Fallback = [&]() {
+      MCAsmBackend::maybeAddReloc(F, Fixup, Target, FixedValue, IsResolved);
+      return;
+    };
+    // Check if SubSym (SubSym) 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 = [&]() {
+      const MCSymbol *SubSym = Target.getSubSym();
+      return SubSym->isInSection() && &SubSym->getSection() == F.getParent() &&
+             isPCRelFixupResolved(SubSym, F);
+    };
 
+    std::pair<MCFixupKind, MCFixupKind> FK;
     switch (Fixup.getKind()) {
     case FK_Data_1:
       FK = getRelocPairForSize(8);
@@ -457,9 +434,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 8f2c0210b25c1..78305852d1a50 100644
--- a/llvm/test/MC/LoongArch/Relocations/sub-expr.s
+++ b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
@@ -40,6 +40,9 @@
 # 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_32_PCREL extsym 0x8
+# CHECK-NEXT:       0x4C R_LARCH_64_PCREL extsym 0xC
+
 # CHECK-NEXT:     }
 # NORELAX-NEXT:   Section ({{.*}}) .rela.sy {
 # NORELAX-NEXT:     0x0 R_LARCH_CALL36 foo 0x0
@@ -75,6 +78,8 @@ la.pcrel $a0, z
 .4byte 0xbeef-1b
 1:
 .8byte 0xbeef-1b
+.4byte extsym-1b
+.8byte extsym-1b
 
 .section .sy,"ax"
 call36 foo


        


More information about the llvm-commits mailing list