RISC-V and LoongArch ELF psABIs define a kind of
RELAX relocations which are expected to have a normal
relocation at the same address.
Change-Id: I5737bfcfd3e5041fb6ab7d193c9fc57eeca1eec8
Our implementation did the classic add-sub rounding trick `(y = x +/- C =+ C - x)`
with `C = 1 / eps(T) = 2^(mantissa - 1)`. This approach only works for values whose
magnitude is below the rounding capacity of the constant. For a 64-bit mantissa
(like f80 has), `C = 2^63` only rounds for `|x| < 2^63`. Before we allowed this to
be ran on `e < bias + 64` aka `|x| < 2^64`. And because it isn't large enough,
we lose a bit to rounding.
For reference, the musl implementation does the same thing, using `mantissa - 1`:
https://git.musl-libc.org/cgit/musl/tree/src/math/ceill.c#n18
where `LDBL_MANT_DIG` is 64 for `long double` on x86.
This commit also combines the floor and ceil implementations into one generic one.
Following up on #30571
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30724
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: Steven Casper <sebastiancasper3@gmail.com>
Co-committed-by: Steven Casper <sebastiancasper3@gmail.com>
The option should probably still be implemented properly at some point, but LLD
has ignored this for years and nobody seems to mind, so just do the same for
now.
This unblocks using zig cc with CMake on OpenBSD, among other use cases.
ref https://github.com/ziglang/zig/issues/18713
Previously these functions made the assumption that
when performing a on the input digits,
there could be no collisions between the less
significant digits being larger than '9', and the
upper digits being small enough to get past the
checks.
Now we perform a correct check across all of the
digits to ensure they're in between '0'-'9', at
a minimal cost, since all digits are checked in
parallel.
Necessary to work around this:
error: ld.lld: /home/ci/.cache/act/f23fdcb74e58cd75/hostexecutor/zig-global-cache/o/c67e3042d116da0f73d3129d377044bf/libc++abi.a(/home/ci/.cache/act/f23fdcb74e58cd75/hostexecutor/zig-global-cache/o/61dd7765ab891b4db54a5e49b8ab8c86/cxa_thread_atexit.o):(function __cxa_thread_atexit: .text.__cxa_thread_atexit+0x40): relocation R_PPC64_REL24_NOTOC out of range: -251925824 is not in [-33554432, 33554431]; references '__cxa_thread_atexit_impl'
note: referenced by cxa_thread_atexit.cpp:116 (/home/ci/.cache/act/f23fdcb74e58cd75/hostexecutor/lib/libcxxabi/src/cxa_thread_atexit.cpp:116)
note: defined in /home/ci/.cache/act/f23fdcb74e58cd75/hostexecutor/zig-global-cache/o/c67e3042d116da0f73d3129d377044bf/libc++abi.a(/home/ci/.cache/act/f23fdcb74e58cd75/hostexecutor/zig-global-cache/o/61dd7765ab891b4db54a5e49b8ab8c86/cxa_thread_atexit.o)
This is only a problem for now because we link libLLVM; once we start invoking
llc instead, we won't need this workaround anymore.
It has been observed in practice on powerpc64(le)-linux that zig.o (in various
stages and build modes) is large enough that the +/- 32MB branch range of
PowerPC is insufficient to reach from one end of the code section to the other.
With LLVM 21, this leads to silent miscompiles that then crash at runtime. With
LLVM 22, it will at least lead to branch range errors that fail the compilation,
but that gets us no closer to a working compiler.
By using these options, we give the linker much greater flexibility to move code
and data around to satisfy these range constraints; without them, the linker is
not allowed to split up the huge code and data sections of zig.o to do so.
Similar issues have also been observed on powerpc-linux (32-bit), hexagon-linux,
and some variations of mips(64)(el)-linux. But let's be conservative for now;
those other targets can be added to the condition later.
As a data point to support this change, it's worth noting that LLD started
enabling these options for LTO precisely because the resulting large compilation
units ran into these range issues. In some abstract sense, Zig can be seen as
doing a limited form of "LTO" in the frontend, so it's not surprising that we
would hit the same issues.
We already did this for some of them; this just makes us consistent. Doing this
gives the linker more flexibility to rearrange code/data, but more importantly,
allows --gc-sections to get rid of all the unused code, which is a real concern
for these libraries in particular.