Commit Graph

689 Commits

Author SHA1 Message Date
Trevor Gross
5778643174 libm-test: Fix unintentional skips in binop_common
`binop_common` emits a `SKIP` that is intended to apply only to
`copysign`, but is instead applying to all binary operators. Correct the
general case but leave the currently-failing `maximum_num` tests as a
FIXME, to be resolved separately in [1].

Also simplify skip logic and NaN checking, and add a few more `copysign`
checks.

[1]: https://github.com/rust-lang/compiler-builtins/pull/939
2025-06-02 22:47:15 +00:00
Trevor Gross
e83ca86341 cleanup: Use x.biteq(y) rather than x.to_bits() == y.to_bits() 2025-06-02 16:10:49 +00:00
Trevor Gross
c6df6a72d8 Fix new dead_code warnings from recent nightlies 2025-06-01 19:54:30 +00:00
Trevor Gross
877feef541 Reuse libm's Caat and CastFrom in compiler-builtins 2025-05-29 03:56:08 +00:00
Trevor Gross
851aa05aa0 cleanup: Reuse MinInt and Int from libm in compiler-builtins
Since the two crates are now in the same repo, it is easier to share
code. Begin some deduplication with the integer traits.
2025-05-29 03:04:59 +00:00
Trevor Gross
5978b8b875 aarch64: Add a note saying why we use frintx rather than frintn 2025-05-28 21:10:28 +00:00
Dario Damiani
c04f133858 Typo in README.md
Link to Apache License changed from htps:// to https://
2025-05-28 15:51:49 -04:00
Trevor Gross
4c264c96ae Update CmpResult to use a pointer-sized return type
As seen at [1], LLVM uses `long long` on LLP64 (to get a 64-bit integer
matching pointer size) and `long` on everything else, with exceptions
for AArch64 and AVR. Our current logic always uses an `i32`. This
happens to work because LLVM uses 32-bit instructions to check the
output on x86-64, but the GCC checks the full 64-bit register so garbage
in the upper half leads to incorrect results.

Update our return type to be `isize`, with exceptions for AArch64 and
AVR.

Fixes: https://github.com/rust-lang/compiler-builtins/issues/919

[1]: 0cf3c437c1/compiler-rt/lib/builtins/fp_compare_impl.inc (L11-L27)
2025-05-28 02:58:42 -04:00
Trevor Gross
db21837095 libm: Clean up unused files
These were deleted during refactoring in 0a2dc5d9 ("Combine the source
files for more generic implementations") but got added back by accident
in 54bac411 ("refactor: Move the libm crate to a subdirectory"). Remove
them again here.
2025-05-22 13:22:51 +02:00
Tobias Decking
d16c82dba1 Fix i256::MAX 2025-05-13 15:01:51 +02:00
github-actions[bot]
0d63b99799 chore: release 2025-05-06 19:37:58 -04:00
Trevor Gross
61a14fcea0 Require target_has_atomic = "ptr" for runtime feature detection
The `feature_detect` module is currently being built on all targets, but
the use of `AtomicU32` causes a problem if atomics are not available
(such as with `bpfel-unknown-none`). Gate this module behind
`target_has_atomic = "ptr"`.

The below now completes successfully:

    cargo build -p compiler_builtins --target=bpfel-unknown-none -Z build-std=core

Fixes: https://github.com/rust-lang/compiler-builtins/issues/908
2025-05-06 17:59:03 -04:00
Trevor Gross
687902c1af Replace super::super with crate::support where possible
Since `crate::support` now works in both `compiler-builtins` and `libm`,
we can get rid of some of these unusual paths.
2025-05-05 02:31:52 -04:00
github-actions[bot]
16150ebb31 chore: release 2025-05-04 18:52:58 -04:00
Trevor Gross
8995ac0448 Use runtime feature detection for fma routines on x86
Get performance closer to the glibc implementations by adding assembly
fma routines, with runtime feature detection so they are used even if
not compiled with `+fma` (as the distributed standard library is often
not). Glibc uses ifuncs, this implementation stores a function pointer
in an atomic.

Results of CPU flags are also cached in order to avoid repeating the
startup time in calls to different functions. The feature detection code
is a slightly simplified version of `std-detect`.

Musl sources were used as a reference [1].

Fixes: https://github.com/rust-lang/rust/issues/140452 once synced

[1]: c47ad25ea3/src/math/x32/fma.c
2025-05-03 14:17:49 -04:00
Trevor Gross
4a1dc96652 Rename the i686 module to x86
This module is used for both i686 and x86-64.
2025-05-03 14:17:49 -04:00
Trevor Gross
caf337d467 Refactor the fma modules
Move implementations to `generic/` like the other functions. This also
allows us to combine the `fma` and `fma_wide` modules.
2025-04-29 19:09:50 -04:00
Trevor Gross
6d83a3226f Move fma implementations to mod generic
This will not build correctly, the move is done as a separate step from
the rest of refactoring so git's history is cleaner.
2025-04-29 19:09:50 -04:00
Trevor Gross
8d789ea8f1 Resolve unnecessary_transmutes lints
These appeared in a later nightly. In compiler-builtins we can apply the
suggestion, but in `libm` we need to ignore them since `fx::from_bits`
is not `const` at the MSRV.

`clippy::uninlined_format_args` also seems to have gotten stricter, so
fix those here.
2025-04-29 18:15:02 -04:00
Trevor Gross
5028ecd025 chore: Release libm v0.2.13 2025-04-22 04:44:00 -04:00
github-actions[bot]
1fa9d0fce3 chore: release builtins 0.1.156 and libm 0.2.12 2025-04-22 01:34:46 -04:00
quaternic
e075e9fbde Reimplement the generic fmod 2025-04-22 00:53:56 -04:00
Trevor Gross
94448a6ff6 Update README and CONTRIBUTING for the new repository layout 2025-04-21 06:16:12 -04:00
Trevor Gross
8ce02e8ef5 Move README.md to compiler-builtins, CONTRIBUTING.md to root
Do this in a commit so git tracks the move; a new README will be
introduced in the root, and CONTRIBUTING will be updated to apply to
both crates.
2025-04-21 06:16:12 -04:00
Trevor Gross
8d70be87e6 Run cargo fmt on all projects
Apply the same formatting rules to both `libm` and `compiler-builtins`.
2025-04-19 19:05:49 -04:00
Trevor Gross
569b40209d Add a .rustfmt.toml with style edition 2024
Use the 2024 style edition for all crates and enable import sorting.
2024 already applies some smaller heuristics that look good in
compiler-builtins, I have dropped `use_small_heuristics` that was set in
`libm` because it seems to negatively affect the readibility of anything
working with numbers (e.g. collapsing multiple small `if` expressions
into a single line).
2025-04-19 19:05:49 -04:00
Trevor Gross
8b8bd8a0fd libm: Flatten the libm/libm directory 2025-04-19 17:20:24 -04:00
Trevor Gross
911a70381a libm: Reorganize into compiler-builtins
Distribute everything from `libm/` to better locations in the repo.
`libm/libm/*` has not moved yet to avoid Git seeing the move as an edit
to `Cargo.toml`.

Files that remain to be merged somehow are in `etc/libm`.
2025-04-19 17:20:24 -04:00
Trevor Gross
806bb4fa6e libm: Remove compiler-builtins-smoke-test
Since `libm` is now part of the `compiler-builtins` repo, the crate to
test that they work together is no longer needed.
2025-04-19 17:20:24 -04:00
Trevor Gross
83a8482f91 Update .git-blame-ignore-revs after the libm merge 2025-04-19 20:18:22 +00:00
Trevor Gross
d794bb3492 Update submodules after the libm merge 2025-04-19 20:18:22 +00:00
Trevor Gross
cd7c76aab3 Migrate all crates except libm to edition 2024
Unfortunately this means we lose use of the convenient name `gen`, so
this includes a handful of renaming.

We can't increase the edition for `libm` yet due to MSRV, but we can
enable `unsafe_op_in_unsafe_fn` to help make that change smoother in the
future.
2025-04-18 19:00:45 -04:00
Trevor Gross
3a0b9c9f51 refactor: Introduce a virtual manifest
Move the workspace configuration to a virtual manifest. This
reorganization makes a more clear separation between package contents
and support files that don't get distributed. It will also make it
easier to merge this repository with `compiler-builtins` which is
planned (builtins had a similar update done in [1]).

LICENSE.txt and README.md are symlinkedinto the new directory to ensure
they get included in the package.

[1]: https://github.com/rust-lang/compiler-builtins/pull/702
2025-04-18 17:49:25 -04:00
Trevor Gross
7077daa6ad refactor: Move the libm crate to a subdirectory
In preparation for switching to a virtual manifest, move the `libm`
crate into a subdirectory and update paths to match.

Updating `Cargo.toml` is done in the next commit so git tracks the moved
file correctly.
2025-04-18 17:49:25 -04:00
Trevor Gross
88dcaf20b5 Mark generic functions #[inline]
Benchmarks for [1] seemed to indicate that repository organization for
some reason had an effect on performance, even though the exact same
rustc commands were running (though some with a different order). After
investigating more, it appears that dependencies may have an affect on
inlining thresholds for generic functions.

It is surprising that this happens, we more or less expect that public
functions will be standalone but everything they call will be inlined.
To help ensure this, mark all generic functions `#[inline]` if they
should be merged into the public function.

Zulip discussion at [2].

[1]: https://github.com/rust-lang/libm/pull/533
[2]: https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/Dependencies.20affecting.20codegen/with/513079387
2025-04-18 16:29:27 -04:00
Trevor Gross
3cecf22e0c Combine the source files for fmod
Since `fmod` is generic, there isn't any need to have the small wrappers
in separate files. Most operations was done in [1] but `fmod` was
omitted until now.

[1]: https://github.com/rust-lang/libm/pull/537
2025-04-18 15:14:55 -04:00
Trevor Gross
8da1290f04 Ensure all public functions are marked no_panic
Fixes: https://github.com/rust-lang/libm/issues/201
2025-04-18 04:23:00 -04:00
Trevor Gross
2db05de8fd ci: Account for PR_NUMBER being set to an empty string
This is the case for CI after merge that is no longer associated with a
pull request.
2025-04-18 03:26:38 -04:00
Trevor Gross
2585a57dc7 Ensure configure.rs changes trigger rebuilds 2025-04-18 02:47:03 -04:00
Trevor Gross
1cb17773f6 ci: Increase the timeout for extensive tests
The reorganization PR has caused this to fail once before because every
file shows up as changed. Increase the timeout so this doesn't happen.

We now cancel the job if too many extensive tests are run unless `ci:
allow-many-extensive` is in the PR description, so this helps prevent
the limit being hit by accident.
2025-04-17 23:31:06 -05:00
Trevor Gross
a0e5a7a636 ci: Require ci: allow-many-extensive if a threshold is exceeded
Error out when too many extensive tests would be run unless `ci:
allow-many-extensive` is in the PR description. This allows us to set a
much higher CI timeout with less risk that a 4+ hour job gets started by
accident.
2025-04-17 23:31:06 -05:00
Trevor Gross
cad0d6f187 ci: Allow skipping extensive tests with ci: skip-extensive
Sometimes we do refactoring that moves things around and triggers an
extensive test, even though the implementation didn't change. There
isn't any need to run full extensive CI in these cases, so add a way to
skip it from the PR message.
2025-04-17 23:31:06 -05:00
Trevor Gross
014c3e4ccb ci: Cancel jobs when a new push happens
Jobs should just cancel automatically, it isn't ideal that extensive
jobs can continue running for multiple hours after code has been
updated. Use a solution from [1] to do this.

[1]: https://stackoverflow.com/a/72408109/5380651
2025-04-17 22:57:24 -05:00
Trevor Gross
a15c8c9a3d Combine the source files for more generic implementations
Splitting into different source files by float size doesn't have any
benefit when the only content is a small function that forwards to the
generic implementation. Combine the source files for all width versions
of:

* ceil
* copysign
* fabs
* fdim
* floor
* fmaximum
* fmaximum_num
* fminimum
* fminimum_num
* ldexp
* scalbn
* sqrt
* truc

fmod is excluded to avoid conflicts with an open PR.

As part of this change move unit tests out of the generic module,
instead testing the type-specific functions (e.g. `ceilf16` rather than
`ceil::<f16>()`). This ensures that unit tests are validating whatever
we expose, such as arch-specific implementations via
`select_implementation!`, which would otherwise be skipped. (They are
still covered by integration tests).
2025-04-17 22:00:42 -05:00
Trevor Gross
579627ddd5 Make assert_biteq! not rely on having Int in scope 2025-04-17 22:00:42 -05:00
Trevor Gross
f88b7c8a46 Add NEG_NAN to Float
Introduce a constant representing NaN with a negative sign bit for use
with testing. There isn't really any guarantee that `F::NAN` is positive
but in practice it always is, which is good enough for testing purposes.
2025-04-17 22:00:42 -05:00
Trevor Gross
e4d716c848 fmod: Correct the normalization of subnormals
Discussed at [1], there was an off-by-one mistake when converting from
the loop routine to using `leading_zeros` for normalization.

Currently, using `EXP_BITS` has the effect that `ix` after the branch
has its MSB _one bit to the left_ of the implicit bit's position,
whereas a shift by `EXP_BITS + 1` ensures that the MSB is exactly at the
implicit bit's position, matching what is done for normals (where the
implicit bit is set to be explicit). This doesn't seem to have any
effect in our implementation since the failing test cases from [1]
appear to still have correct results.

Since the result of using `EXP_BITS + 1` is more consistent with what is
done for normals, apply this here.

[1]: https://github.com/rust-lang/libm/pull/469#discussion_r2012473920
2025-04-16 15:28:10 -05:00
Trevor Gross
14ab2453f2 fmod: Add regression tests for subnormal issue
From discussion at [1] our loop count calculation is incorrect, causing
an issue with subnormal numbers. Add test cases for known failures.

[1]: https://github.com/rust-lang/libm/pull/469#discussion_r2012473920
2025-04-16 15:28:10 -05:00
quaternic
b955cc691e Implement rounding for the hex float parsing and prepare to improve error handling
Parsing errors are now bubbled up part of the way, but that needs some
more work.

Rounding should be correct, and the `Status` returned by `parse_any`
should have the correct bits set. These are used for the current (unchanged)
behavior of the surface level functions like `hf64`: panic on invalid inputs, or
values that aren't exactly representable.
2025-04-15 00:46:12 +00:00
Trevor Gross
28b6df8603 Add assembly version of simple operations on aarch64
Replace `core::arch` versions of the following with handwritten
assembly, which avoids recursion issues (cg_gcc using `rint` as a
fallback) as well as problems with `aarch64be`.

* `rint`
* `rintf`

Additionally, add assembly versions of the following:

* `fma`
* `fmaf`
* `sqrt`
* `sqrtf`

If the `fp16` target feature is available, which implies `neon`, also
include the following:

* `rintf16`
* `sqrtf16`

`sqrt` is added to match the implementation for `x86`. `fma` is included
since it is used by many other routines.

There are a handful of other operations that have assembly
implementations. They are omitted here because we should have basic
float math routines available in `core` in the near future, which will
allow us to defer to LLVM for assembly lowering rather than implementing
these ourselves.
2025-04-09 00:46:53 -05:00