Skip to content

[MC] Relaxable Fragments Can be Linker Relaxable #150096

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/lib/MC/MCAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,14 @@ bool MCAssembler::relaxInstruction(MCFragment &F) {
getEmitter().encodeInstruction(Relaxed, Data, Fixups, *F.getSubtargetInfo());
F.setVarContents(Data);
F.setVarFixups(Fixups);

for (const auto &Fixup : Fixups) {
if (!Fixup.isLinkerRelaxable())
continue;
F.setLinkerRelaxable();
F.getParent()->setLinkerRelaxable();
}
Comment on lines +781 to +786
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not cope with the other direction correctly, but I'm not sure we can.

The other direction is when a linker relaxable fixup is replaced by a non-linker-relaxable fixup in relaxation, which might need the fragment to be marked as not linker relaxable. I'm not sure this will ever happen though.


return true;
}

Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/MC/MCExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ bool MCExpr::evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
return IsRelocatable && Value.isAbsolute() && Value.getSpecifier() == 0;
}

/// Helper method for \see EvaluateSymbolAdd().
/// Helper method for \see evaluateSymbolicAdd().
static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
bool InSet, const MCSymbol *&A,
const MCSymbol *&B,
Expand Down Expand Up @@ -361,6 +361,10 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
if (BBeforeRelax && AAfterRelax)
return;
}
if (F->getKind() == MCFragment::FT_Relaxable && Asm->hasFinalLayout() &&
F->isLinkerRelaxable())
// FIXME: More accurate calculation of AAfterRelax/BBeforeRelax?
return;
if (&*F == FA) {
// If FA and FB belong to the same subsection, the loop will find FA and
// we can resolve the difference.
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/MC/MCFragment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ LLVM_DUMP_METHOD void MCFragment::dump() const {
OS << "\n Fixup @" << F.getOffset() << " Value:";
F.getValue()->print(OS, nullptr);
OS << " Kind:" << F.getKind();
if (F.isLinkerRelaxable())
OS << " LinkerRelaxable";
}
};

Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/MC/MCSection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ LLVM_DUMP_METHOD void MCSection::dump(
raw_ostream &OS = errs();

OS << "MCSection Name:" << getName();
if (isLinkerRelaxable())
OS << " LinkerRelaxable";
for (auto &F : *this) {
OS << '\n';
F.dump();
Expand Down
18 changes: 18 additions & 0 deletions llvm/test/MC/RISCV/linker-relaxation-pr150071.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# RUN: llvm-mc --triple=riscv32 -mattr=+relax,+experimental-xqcilb \
# RUN: %s -filetype=obj -o - -riscv-add-build-attributes \
# RUN: | llvm-objdump -dr - \
# RUN: | FileCheck %s

.global foo

bar:
jal x1, foo
# CHECK: qc.e.jal 0x0 <bar>
# CHECK-NEXT: R_RISCV_VENDOR QUALCOMM
# CHECK-NEXT: R_RISCV_CUSTOM195 foo
# CHECK-NEXT: R_RISCV_RELAX *ABS*
bne a0, a1, bar
# CHECK-NEXT: bne a0, a1, 0x6 <bar+0x6>
# CHECK-NEXT: R_RISCV_BRANCH bar
ret
# CHECK-NEXT: ret
Loading