[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