[llvm] [AVR] Force relocations for non-encodable jumps (PR #121498)
Patryk Wychowaniec via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 2 23:15:15 PST 2025
================
@@ -512,14 +535,25 @@ bool AVRAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
const MCFixup &Fixup,
const MCValue &Target,
+ const uint64_t Value,
const MCSubtargetInfo *STI) {
switch ((unsigned)Fixup.getKind()) {
default:
return Fixup.getKind() >= FirstLiteralRelocationKind;
+
case AVR::fixup_7_pcrel:
- case AVR::fixup_13_pcrel:
- // Always resolve relocations for PC-relative branches
- return false;
+ case AVR::fixup_13_pcrel: {
+ uint64_t ValueEx = Value;
+ uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize;
+
+ // If the jump is too large to encode it, fall back to a relocation.
----------------
Patryk27 wrote:
The issue is that we're overzealous, we're emitting "out of range" for functions that are not actually called by the user code.
Similar case can happen in C++ - imagine we've got two files: `main.c` with user code that imports `library.h`, and `library.c` that has two functions, `small` and `large`.
`main.c` only calls the `small()` function, but the compilation process consists of two calls to `clang` - first the user will have to compile `library.c`, which will cause LLVM to emit code for both the `small` and the `large` function (since it doesn't yet know the user only calls `small()`). This will fail with the `out of range` error for the `large` function even though the user doesn't actually care about it!
The same happens for Rust (with the exception that in Rust compilation unit consists of the entire crate, not single files), Zig and so on.
I think that's the reason we used to emit relocations for relative jumps in the first place - it allows us to compile all the code and let the linker perform dead-code elimination later. Following my example from before: since user doesn't call `large()`, linker will remove it from the binary and it won't try to resolve relocations for it.
There's no "postponing the error to the linking phase" - there's just nothing illegal happening here, there's no error.
https://github.com/llvm/llvm-project/pull/121498
More information about the llvm-commits
mailing list