Commit Graph

2065 Commits

Author SHA1 Message Date
Trevor Gross
60ea5815b2 Update LLVM downloads to 20.1-2025-02-13
This matches the version used by rust-lang/rust.
2025-02-26 02:47:49 -05:00
github-actions[bot]
45c4a1d1b5 chore: release v0.1.149 2025-02-25 14:02:15 -05:00
Trevor Gross
55bbda8ff8 Make a subset of libm symbols weakly available on all platforms
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
2025-02-25 13:54:56 -05:00
github-actions[bot]
95a5ad5225 chore: release v0.1.148 2025-02-24 02:43:13 -05:00
Trevor Gross
7055198acf Update the libm submodule
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).
2025-02-24 02:33:36 -05:00
Trevor Gross
1774882738 Gate another assertion behind compiler-builtins
This is causing link errors on Windows.
2025-02-24 02:25:17 -05:00
Trevor Gross
2615971f55 Configure out remaining formatting when compiler-builtins is set
These are still causing errors in the compiler-builtins CI.
2025-02-24 01:22:26 -05:00
Trevor Gross
3f6b08ac1e Ignore unused variables when compiler-builtins is set 2025-02-24 00:28:14 -05:00
Trevor Gross
9021b2820c Resolve monomorphization errors in compiler-builtins
`compiler-builtins` is not allowed to call anything from `core`;
however, there are a couple of cases where we do so in `libm` for debug
output. Gate relevant locations behind the `compiler-builtins` Cargo
feature.
2025-02-23 23:42:28 -05:00
Martin Nordholts
49224fb9ed Enable f16 for MIPS
It seems as if `f16` works on MIPS now according to my
testing on Rust master with LLVM 20, and I was asked to
create PRs with my changes.

I only tested on the flavour of `mipsel-unknown-linux-gnu`
hardware that happens to be available to me, so I can't say
anything about other MIPS hardware, but from a casual
skimming of the LLVM code ([1], [2]) it seems like `f16`
should work on all MIPS hardware. So enable it for all MIPS
hardware.

[1]: https://github.com/rust-lang/llvm-project/blob/rustc/20.1-2025-02-13/llvm/lib/Target/Mips/MipsISelLowering.h#L370
[2]: https://github.com/rust-lang/llvm-project/blob/rustc/20.1-2025-02-13/llvm/lib/CodeGen/TargetLoweringBase.cpp#L1367-L1388
2025-02-23 22:40:57 -05:00
Trevor Gross
f42c9632a6 Eliminate the use of public_test_dep! for a third time
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
2025-02-23 22:34:40 -05:00
Trevor Gross
ba8f07282e Make the compiler-builtins test more accurately mirror compiler-builtins
In `compiler-builtins`, `libm` is contained within a `math` module. The
smoke test in this repo has a slightly different layout so some things
were passing that shouldn't be.

Change module layouts in `compiler-builtins-smoke-test` to match
`compiler-builtins` and update a few instances of broken paths.
2025-02-23 21:10:11 -05:00
Trevor Gross
c32bc8398a ci: Pin the nightly toolchain for aarch64 jobs
Pin aarch64-unknown-linux-gnu and aarch64-apple-darwin to
nightly-2025-02-07 until [1] makes it to a Rust nightly.

[1]: https://github.com/llvm/llvm-project/issues/127804
2025-02-23 21:10:11 -05:00
Trevor Gross
54e7ff15c0 Revert "ci: Pin the nightly toolchain for i686-pc-windows-gnu"
Since [1], the issue should be resolved so the workaround can be
dropped.

This reverts commit 88e83b96ad09f3cf9e2d1b4543a7d43f9c5a77c0.

[1]: https://github.com/rust-lang/compiler-builtins/pull/759
2025-02-23 03:40:11 -05:00
github-actions[bot]
f851256581 chore: release v0.1.147 2025-02-19 19:16:19 -05:00
Ralf Jung
2b6de7a68f remove win64_128bit_abi_hack 2025-02-19 15:44:43 -05:00
Trevor Gross
bade6290c8 ci: Pin the nightly toolchain for aarch64-unknown-linux-gnu
Pin aarch64-unknown-linux-gnu to nightly-2025-02-07 until [1] is
resolved.

[1]: https://github.com/llvm/llvm-project/issues/127804
2025-02-19 15:38:45 -05:00
Trevor Gross
4517c7ea90 ci: Pin the nightly toolchain for i686-pc-windows-gnu
Pin i686-pc-windows-gnu to nightly-2025-02-07 until [1] is resolved.

[1]: https://github.com/rust-lang/rust/issues/136795
2025-02-19 15:38:45 -05:00
Trevor Gross
37da10edde ci: Update actions/cache to v4
Github has deprecated v2 so this needs to be bumped.
2025-02-19 15:38:45 -05:00
Trevor Gross
bd41642818 Use git ls-files rather than manually globbing for tidy
This avoids matching build directories, ignored files, and submodules.
2025-02-12 15:38:46 -06:00
Trevor Gross
c01153d29b Make fma a trait method on Float 2025-02-12 10:27:11 +00:00
Trevor Gross
720ba18931 fma refactor 3/3: combine fma public API with its implementation
Similar to other recent changes, just put public API in the same file as
its generic implementation. To keep things slightly cleaner, split the
default implementation from the `_wide` implementation.

Also introduces a stub `fmaf16`.
2025-02-12 10:27:11 +00:00
Trevor Gross
bcbdb0b74f fma refactor 2/3: move math/generic/fma.rs to math/fma.rs
Done in stages so git tracks the moved file correctly.
2025-02-12 10:18:48 +00:00
Trevor Gross
212d463e89 fma refactor 1/3: remove math/fma.rs
Done in stages so git tracks the moved file correctly.
2025-02-12 10:18:48 +00:00
Trevor Gross
dea2ed3d1d Scale test iteration count at a later point
Currently the argument multiplier and large float multiplier happen
before selecting count based on generator. However, this means that
bivariate and trivariate functions don't get scaled at all (except for
the special cased fma).

Move this scaling to a later point.
2025-02-12 04:07:13 -06:00
Trevor Gross
e106d63516 Add a way to print inputs on failure
When there is a panic in an extensive test, tracing down where it came
from can be difficult since no information is provides (messeges are
e.g. "attempted to subtract with overflow"). Resolve this by calling the
functions within `panic::catch_unwind`, printing the input, and
continuing.
2025-02-11 22:33:08 -06:00
Trevor Gross
aa26cab257 Rename Float::exp to Float::ex
Our function to get the exponent conflicts with the inherent `exp`
function for `e^x`. Rename `exp` to `ex` to avoid confusion and usage
problems.
2025-02-11 10:41:43 -06:00
Trevor Gross
7db47c741c Check exact values for specified cases
Inputs in `case_list` shouldn't hit xfails or increased ULP tolerance.
Ensure that overrides are skipped when testing against MPFR or a
specified value and that NaNs, if any, are checked bitwise.
2025-02-11 02:27:13 -06:00
Trevor Gross
53a055049c Add roundeven{,f,f16,f128}
C23 specifies a new set of `roundeven` functions that round to the
nearest integral, with ties to even. It does not raise any floating
point exceptions.

This behavior is similar to two other functions:

1. `rint`, which rounds to the nearest integer respecting rounding mode
   and possibly raising exceptions.
2. `nearbyint`, which is identical to `rint` except it may not raise
   exceptions.

Technically `rint`, `nearbyint`, and `roundeven` all behave the same in
Rust because we assume default floating point environment. The backends
are allowed to lower to `roundeven`, however, so we should provide it in
case the fallback is needed.

Add the `roundeven` family here and convert `rint` to a function that
takes a rounding mode. This currently has no effect.
2025-02-11 00:55:22 -06:00
Trevor Gross
2a3ef8b9a2 Fix parsing of negative hex float literals in util 2025-02-11 00:55:22 -06:00
Trevor Gross
e79fb05b25 Increase allowed offset from infinity for ynf
Failed with

    called `Result::unwrap()` on an `Err` value: ynf

    Caused by:
        0:
               input:    (223, 116.89665)
               as hex:   (, 0x1.d3962cp+6)
               as bits:  (0x000000df, 0x42e9cb16)
               expected: -3.1836905e38          -0x1.df074cp+127 0xff6f83a6
               actual:   -inf                   -inf 0xff800000
        1: mismatched infinities
2025-02-10 16:17:33 -06:00
Trevor Gross
669731335e Add fminimum, fmaximum, fminimum_num, and fmaximum_num
These functions represent new operations from IEEE 754-2019. Introduce
them for all float sizes.
2025-02-10 16:17:33 -06:00
Trevor Gross
86ee1f99c9 Combine fmin{,f,f16,f128} and fmax{,f,f16,128} into a single file
These don't have much content since they now use the generic
implementation. There will be more similar functions in the near future
(fminimum, fmaximum, fminimum_num, fmaximum_num); start the pattern of
combining similar functions now so we don't have to eventually maintain
similar docs across 24 different files.
2025-02-10 14:54:53 -06:00
Trevor Gross
a6dd7980f1 Small refactor of bigint tests
Print errors immediately rather than deferring to the end, so any debug
output shows up immediately before the relevant failed test.
2025-02-10 14:20:37 -06:00
Trevor Gross
e94e987399 Eliminate the use of force_eval! in ceil, floor, and trunc 2025-02-10 12:37:25 +00:00
Trevor Gross
105cd79578 Migrate away from nonfunctional fenv stubs
Many routines have some form of handling for rounding mode and floating
point exceptions, which are implemented via a combination of stubs and
`force_eval!` use. This is suboptimal, however, because:

1. Rust does not interact with the floating point environment, so most
   of this code does nothing.
2. The parts of the code that are not dead are not testable.
3. `force_eval!` blocks optimizations, which is unnecessary because we
   do not rely on its side effects.

We cannot ensure correct rounding and exception handling in all cases
without some form of arithmetic operations that are aware of this
behavior. However, the cases where rounding mode is explicitly handled
or exceptions are explicitly raised are testable. Make this possible
here for functions that depend on `math::fenv` by moving the
implementation to a nonpublic function that takes a `Round` and returns
a `Status`.

Link: https://github.com/rust-lang/libm/issues/480
2025-02-10 12:29:59 +00:00
Trevor Gross
35f5731d62 Introduce a trait constant for the minimum positive normal value 2025-02-10 08:17:57 +00:00
Trevor Gross
2f0685a9a2 Implement u256 with two u128s rather than u64
This produces better assembly, e.g. on aarch64:

            .globl  libm::u128_wmul
            .p2align        2
    libm::u128_wmul:
    Lfunc_begin124:
            .cfi_startproc
            mul x9, x2, x0
            umulh x10, x2, x0
            umulh x11, x3, x0
            mul x12, x3, x0
            umulh x13, x2, x1
            mul x14, x2, x1
            umulh x15, x3, x1
            mul x16, x3, x1
            adds x10, x10, x14
            cinc x13, x13, hs
            adds x13, x13, x16
            cinc x14, x15, hs
            adds x10, x10, x12
            cinc x11, x11, hs
            adds x11, x13, x11
            stp x9, x10, [x8]
            cinc x9, x14, hs
            stp x11, x9, [x8, rust-lang/libm#16]
            ret

The original was ~70 instructions so the improvement is significant.
With these changes, the result is reasonably close to what LLVM
generates using `u256` operands [1].

[1]: https://llvm.godbolt.org/z/re1aGdaqY
2025-02-09 23:41:51 -06:00
Trevor Gross
b7fdce0505 ci: Pin the nightly toolchain for i686-pc-windows-gnu
Pin i686-pc-windows-gnu to nightly-2025-02-07 until [1] is resolved.

[1]: https://github.com/rust-lang/rust/issues/136795
2025-02-09 22:07:40 -06:00
Trevor Gross
1efdc96974 Increase the tolerance for jn and yn
These still fail random tests, e.g.:

    called `Result::unwrap()` on an `Err` value: jn

    Caused by:
        0:
               input:    (1068, -16013.98381387313)
               as hex:   (, -0x1.f46fded9ced39p+13)
               as bits:  (0x0000042c, 0xc0cf46fded9ced39)
               expected: 6.7603314308122506e-6  0x1.c5ad9c102d413p-18 0x3edc5ad9c102d413
               actual:   6.7603314308006335e-6  0x1.c5ad9c1029e80p-18 0x3edc5ad9c1029e80
        1: ulp 13715 > 4000

    Caused by:
        0:
               input:    (195, 42147.94)
               as hex:   (, 0x1.4947e2p+15)
               as bits:  (0x000000c3, 0x4724a3f1)
               expected: -2.13669e-7            -0x1.cad9c6p-23 0xb4656ce3
               actual:   -2.1376937e-7          -0x1.cb10f4p-23 0xb465887a
        1: ulp 7063 > 4000

    Caused by:
        0:
               input:    (194, 740.1916)
               as hex:   (, 0x1.721886p+9)
               as bits:  (0x000000c2, 0x44390c43)
               expected: 1.212096e-6            0x1.455e9ap-20 0x35a2af4d
               actual:   1.2172386e-6           0x1.46c000p-20 0x35a36000
        1: ulp 45235 > 10000

Increase allowed precision to avoid spurious failures.
2025-02-09 22:07:40 -06:00
Trevor Gross
017f1035f1 Replace an assert! with debug_assert! in u256::shr
The implementation came from the `compiler_builtins` port but this
should be weakened to match other integer types.
2025-02-08 05:55:03 -06:00
Trevor Gross
900b61f363 Change how operators are black_boxed
For some reason, the upcoming limb changes in [1] seem to ignore the
black boxing when applied to the operator function. Changing to instead
black box the inputs appears to fix this.

[1]: https://github.com/rust-lang/libm/pull/503
2025-02-08 04:49:44 -06:00
Trevor Gross
0a43f24a30 Add simple icount benchmarks for u256 operations 2025-02-08 02:02:45 -06:00
Trevor Gross
35c201c37f Decrease the allowed error for cbrt
With the correctly rounded implementation, we can reduce the ULP
requirement for `cbrt` to zero. There is still an override required for
`i586` because of the imprecise FMA.
2025-02-07 23:04:53 +00:00
Trevor Gross
2fa2b10ba4 Port the CORE-MATH version of cbrt
Replace our current implementation with one that is correctly rounded.

Source: 81d447bb1c/src/binary64/cbrt/cbrt.c
2025-02-07 23:04:53 +00:00
Trevor Gross
f1afc26b8a Add an enum representation of rounding mode
We only round using nearest, but some incoming code has more handling of
rounding modes that would be nice to `match` on. Rather than checking
integer values, add an enum representation.
2025-02-07 23:04:53 +00:00
Trevor Gross
f45cc66e8e Work arouind iai-callgrind apt failures
Usually `cargo binstall iai-callgrind-runner` handles apt dependencies.
However, the following has been happening:

    Err:11 mirror+file:/etc/apt/apt-mirrors.txt noble-updates/main amd64 libc6-dbg amd64 2.39-0ubuntu8.3
      404  Not Found [IP: 40.81.13.82 80]
    E: Failed to fetch mirror+file:/etc/apt/apt-mirrors.txt/pool/main/g/glibc/libc6-dbg_2.39-0ubuntu8.3_amd64.deb  404  Not Found [IP: 40.81.13.82 80]
    Fetched 19.8 MB in 6s (3138 kB/s)
    E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

Installing the dependencies manually seems to resolve the issue.
2025-02-07 17:04:26 -06:00
Trevor Gross
9169216f41 Uncomment some hex float tests that should work now 2025-02-07 17:04:26 -06:00
Trevor Gross
aa4ae487d4 Convert fmaf to a generic implementation
Introduce a version of generic `fma` that works when there is a larger
hardware-backed float type available to compute the result with more
precision. This is currently used only for `f32`, but with some minor
adjustments it should work for `f16` as well.
2025-02-06 22:51:42 -06:00
Trevor Gross
3e2de21344 Remove or reduce the scope of allow(unused) where possible
Now that we have more in this crate making use of traits, try to be more
specific about what is actually unused.
2025-02-06 21:57:17 -06:00