018616e78b ("Always have math functions but with `weak` linking
attribute if we can") made all math symbols available on platforms that
support weak linkage. This caused some unexpected regressions, however,
because our less accurate and sometimes slow routines were being
selected over the system `libm`, which also tends to be weak [1]. Thus,
0fab77e8d7 ("Don't include `math` for `unix` and `wasi` targets") was
applied to undo these changes on many platforms.
Now that some improvements have been made to `libm`, add back a subset
of these functions:
* cbrt
* ceil
* copysign
* fabs
* fdim
* floor
* fma
* fmax
* fmaximum
* fmin
* fminimum
* fmod
* rint
* round
* roundeven
* sqrt
* trunc
This list includes only functions that produce exact results (verified
with exhaustive / extensive tests, and also required by IEEE in most
cases), and for which benchmarks indicate performance similar to or
better than Musl's soft float math routines [^1]. All except `cbrt` also
have `f16` and `f128` implementations. Once more routines meet these
criteria, we can move them from platform-specific availability to always
available.
Once this change makes it to rust-lang/rust, we will also be able to
move the relevant functions from `std` to `core`.
[^1]: We still rely on the backend to provide optimized assmebly
routines when available.
[1]: https://github.com/rust-lang/rust/issues/128386
This requires privately reexporting `libm`'s `support` module at crate
root, where it is expected for macros. Once `libm` is made always
available, the reexport can be simplified.
This delta adds a lot of routines to `f16` and `f128`:
* ceil
* floor
* fma (f128 only)
* fmax
* fmin
* fmod
* ldexp
* rint
* round
* scalbn
* sqrt
Additionally, the following new API was added for all four float types:
* fmaximum
* fmaximum_num
* fminimum
* fminimum_num
* roundeven
There are also some significant performance improvements for `sqrt` and
`sqrtf`, as well as precision improvements for `cbrt` (both `f32` and
`f64` versions of this function are now always correctly rounded).
Replace `public_test_dep!` by placing optionally public items into new
modules, then controlling what is exported with the `public-test-deps`
feature.
This is nicer for automatic formatting and diagnostics.
This is a reland of 2e2a9255 ("Eliminate the use of
`public_test_dep!`"), which was reverted in 47e50fd2 ('Revert "Eliminate
the use of..."') due to a bug exposed at [1], reapplied in d4abaf4efa
because the issue should have been fixed in [2], then reverted again in
f6eef07f53 because [2] did not actually fix the issue.
[3] has landed in rust-lang/rust since then, which should resolve the
last problem remaining after [2]. So, apply this change for what is
hopefully the final time.
[1]: https://github.com/rust-lang/rust/pull/128691
[2]: https://github.com/rust-lang/rust/pull/135278
[3]: https://github.com/rust-lang/rust/pull/135501
[1] has not gone forward, so this needs to be reverted again in order to
unblock a compiler-builtins upgrade that is necessary for the LLVM 20
upgrade.
This reverts commit a2494f14e99ae90c964f12bf0c059d63ccc07c2a.
[1]: https://github.com/rust-lang/rust/pull/135501
https://github.com/llvm/llvm-project/pull/116706 added Windows
support to cpu_model. Compiling for UEFI also goes through that
code path, because we treat it as a windows target. However,
including windows.h is not actually going to work (and the used
API would not be available in an UEFI environment).
Disable building of cpu_model on UEFI to fix this.
`#![feature(start)]` was removed in [1], but we make use of it in the
intrinsics example. Replace use of this feature with `#[no_mangle]`
applied to `#[main]`.
We don't actually run this example so it is not a problem if this is not
entirely accurate. Currently the example does not run to completion,
instead invoking `rust_begin_unwind`.
[1]: https://github.com/rust-lang/rust/pull/134299
Replace `public_test_dep!` by placing optionally public items into new
modules, then controlling what is exported with the `public-test-deps`
feature.
This is nicer for automatic formatting and diagnostics.
This is a reland of 2e2a9255 ("Eliminate the use of
`public_test_dep!`"), which was reverted in 47e50fd2 ('Revert "Eliminate
the use of..."') due to a bug exposed at [1]. This was fixed in [2], so
the cleanup should be able to be applied again.
[1]: https://github.com/rust-lang/rust/pull/128691
[2]: https://github.com/rust-lang/rust/pull/135278
Most of our Rust-specific overflowing intrinsics currently return
`(i128, bool)`, which is not guaranteed to have a stable ABI. Switch to
returning the overflow via a mutable parameter and only directly
returning the integer result.
`__rust_i128_mulo` now matches the function signature of `__muloti4`,
but they do not share the same ABI on Windows so we cannot easily
deduplicate them.
"Maximum" is technically correct here with regards to what the
bitpattern can represent, but it is not the numeric maximum value of the
exponent which has a relationship with the bias. So, replace the maximum
terminology with "saturated" to indicate it only means the full
bitpattern.
This change is more relevant to `libm` than `compiler-builtins`.
Change `SIGNIFICAND_*` to `SIG_*` and `EXPONENT_*` to `EXP_*`. This
makes things more consistent with `libm`, and terseness is convenient
here since there isn't anything to confuse.
`compiler_builtins` fails to compile to amdgpu if f128 is enabled.
The reason seems to be that compiler_builtins uses libcalls in the
implementation. I’m not really familiar with what libcalls are, but the
LLVM amdgpu backend explicitly does not support them.
Error message:
```
LLVM ERROR: unsupported libcall legalization
```
These implementations of `abs_diff` were added in c2ff1b3119
("Completely overhaul fuzz testing"), but the signed implementation is
wrong when |x| + |y| exceeds the integer's limits (e.g.
`(-128).abs_diff(1)` should be 128 but currently these return 127.
Resolve this by just using `std`'s implementation since that is stable
now. This isn't used anywhere critical, we probably just weren't hitting
the edge case.
This crate isn't meant for direct use, but having an easy way to see
what changed between versions would still be helpful when this crate is
updated in rust-lang/rust.
Disable `f161` for LoongArch64 due to incorrect code generation on LLVM 19,
which causes failures in `testcrate/tests/conv.rs`. This workaround will
remain in place until llvm/llvm-project#109093 is merged or we upgrade to
LLVM 20.