From 5ee79426ceb9af6c69756272c4e84996ba1b7116 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 19 Apr 2025 21:33:14 +0000 Subject: [PATCH 1/3] Add libm and libm-macros to the workspace These should build and test correctly. `libm-test` and others that depend on it are excluded since the necessary CI is not yet set up. --- Cargo.toml | 36 +++++++++++++++++++++++++++++++++--- etc/libm/Cargo.toml | 37 ------------------------------------- 2 files changed, 33 insertions(+), 40 deletions(-) delete mode 100644 etc/libm/Cargo.toml diff --git a/Cargo.toml b/Cargo.toml index 2e17c303a..155fb00b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,15 +7,45 @@ members = [ "builtins-test", "builtins-test-intrinsics", "compiler-builtins", + "crates/libm-macros", + "libm", + # FIXME(libm): disabled until tests work in CI + # "libm-test", + # "crates/musl-math-sys", + # "crates/util", ] default-members = [ - "compiler-builtins", "builtins-test", + "compiler-builtins", + "crates/libm-macros", + # FIXME(libm): disabled until tests work in CI + # "crates/libm-test" + "libm", ] [profile.release] -panic = 'abort' +panic = "abort" [profile.dev] -panic = 'abort' +panic = "abort" + +# FIXME(libm): these profiles are needed for testing +# # The default release profile is unchanged. + +# # Release mode with debug assertions +# [profile.release-checked] +# inherits = "release" +# debug-assertions = true +# overflow-checks = true + +# # Release with maximum optimizations, which is very slow to build. This is also +# # what is needed to check `no-panic`. +# [profile.release-opt] +# inherits = "release" +# codegen-units = 1 +# lto = "fat" + +# [profile.bench] +# # Required for iai-callgrind +# debug = true diff --git a/etc/libm/Cargo.toml b/etc/libm/Cargo.toml deleted file mode 100644 index 268b6fb0e..000000000 --- a/etc/libm/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[workspace] -resolver = "2" -members = [ - "libm", - "crates/libm-macros", - "crates/libm-test", - "crates/musl-math-sys", - "crates/util", -] -default-members = [ - "libm", - "crates/libm-macros", - "crates/libm-test" -] -exclude = [ - # Requires `panic = abort` so can't be a member of the workspace - "crates/compiler-builtins-smoke-test", -] - -# The default release profile is unchanged. - -# Release mode with debug assertions -[profile.release-checked] -inherits = "release" -debug-assertions = true -overflow-checks = true - -# Release with maximum optimizations, which is very slow to build. This is also -# what is needed to check `no-panic`. -[profile.release-opt] -inherits = "release" -codegen-units = 1 -lto = "fat" - -[profile.bench] -# Required for iai-callgrind -debug = true From dbdba2e988b8664ef5a2dde23ccd699465d670ff Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 19 Apr 2025 22:54:23 +0000 Subject: [PATCH 2/3] 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). --- libm/.rustfmt.toml => .rustfmt.toml | 1 - 1 file changed, 1 deletion(-) rename libm/.rustfmt.toml => .rustfmt.toml (79%) diff --git a/libm/.rustfmt.toml b/.rustfmt.toml similarity index 79% rename from libm/.rustfmt.toml rename to .rustfmt.toml index c73bb9301..79ac399c1 100644 --- a/libm/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,5 +1,4 @@ # This matches rustc style_edition = "2024" -use_small_heuristics = "Max" group_imports = "StdExternalCrate" imports_granularity = "Module" From 0662da97c6c3df34039052f128f1e0e895c4ac90 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Sat, 19 Apr 2025 22:39:00 +0000 Subject: [PATCH 3/3] Run `cargo fmt` on all projects Apply the same formatting rules to both `libm` and `compiler-builtins`. --- builtins-test-intrinsics/src/main.rs | 1 + builtins-test/benches/float_cmp.rs | 3 +- builtins-test/benches/mem_icount.rs | 3 +- builtins-test/src/bench.rs | 2 +- builtins-test/src/lib.rs | 1 - builtins-test/tests/cmp.rs | 1 - builtins-test/tests/div_rem.rs | 3 +- compiler-builtins/build.rs | 7 +- compiler-builtins/src/arm_linux.rs | 3 +- compiler-builtins/src/float/conv.rs | 3 +- compiler-builtins/src/float/div.rs | 7 +- compiler-builtins/src/float/mod.rs | 1 - compiler-builtins/src/float/pow.rs | 6 +- compiler-builtins/src/int/big.rs | 3 +- compiler-builtins/src/int/leading_zeros.rs | 6 +- compiler-builtins/src/int/mod.rs | 2 - .../src/int/specialized_div_rem/mod.rs | 1 - compiler-builtins/src/int/udiv.rs | 1 - compiler-builtins/src/mem/x86_64.rs | 3 +- crates/libm-macros/src/enums.rs | 31 +++- crates/libm-macros/src/lib.rs | 44 +++-- crates/libm-macros/src/parse.rs | 38 +++- crates/libm-macros/src/shared.rs | 175 ++++++++++++++---- crates/musl-math-sys/build.rs | 57 ++++-- crates/util/src/main.rs | 6 +- libm-test/benches/random.rs | 17 +- libm-test/examples/plot_domains.rs | 8 +- libm-test/src/domain.rs | 73 +++++--- libm-test/src/f8_impl.rs | 4 +- libm-test/src/generate.rs | 11 +- libm-test/src/generate/case_list.rs | 50 ++++- libm-test/src/generate/edge_cases.rs | 6 +- libm-test/src/generate/random.rs | 5 +- libm-test/src/generate/spaced.rs | 11 +- libm-test/src/lib.rs | 11 +- libm-test/src/num.rs | 93 ++++++++-- libm-test/src/op.rs | 2 +- libm-test/src/run_cfg.rs | 25 ++- libm-test/src/test_traits.rs | 10 +- libm-test/tests/u256.rs | 12 +- libm-test/tests/z_extensive/run.rs | 22 ++- libm/configure.rs | 10 +- libm/src/lib.rs | 5 +- libm/src/math/atanf.rs | 9 +- libm/src/math/cbrt.rs | 6 +- libm/src/math/erf.rs | 6 +- libm/src/math/erff.rs | 6 +- libm/src/math/exp10f.rs | 5 +- libm/src/math/expm1f.rs | 6 +- libm/src/math/fma.rs | 10 +- libm/src/math/fma_wide.rs | 11 +- libm/src/math/generic/ceil.rs | 9 +- libm/src/math/generic/floor.rs | 9 +- libm/src/math/generic/rint.rs | 15 +- libm/src/math/generic/sqrt.rs | 5 +- libm/src/math/generic/trunc.rs | 15 +- libm/src/math/ilogb.rs | 6 +- libm/src/math/k_sin.rs | 6 +- libm/src/math/log1p.rs | 6 +- libm/src/math/log1pf.rs | 6 +- libm/src/math/pow.rs | 48 +++-- libm/src/math/powf.rs | 12 +- libm/src/math/rem_pio2.rs | 20 +- libm/src/math/sinf.rs | 12 +- libm/src/math/support/big.rs | 30 ++- libm/src/math/support/big/tests.rs | 168 +++++++++++++++-- libm/src/math/support/env.rs | 5 +- libm/src/math/support/float_traits.rs | 81 +++++++- libm/src/math/support/hex_float.rs | 46 ++++- libm/src/math/tan.rs | 6 +- libm/src/math/tanf.rs | 6 +- 71 files changed, 1070 insertions(+), 283 deletions(-) diff --git a/builtins-test-intrinsics/src/main.rs b/builtins-test-intrinsics/src/main.rs index 21d0a083c..c4c026368 100644 --- a/builtins-test-intrinsics/src/main.rs +++ b/builtins-test-intrinsics/src/main.rs @@ -480,6 +480,7 @@ mod intrinsics { fn run() { use core::hint::black_box as bb; + use intrinsics::*; // FIXME(f16_f128): some PPC f128 <-> int conversion functions have the wrong names diff --git a/builtins-test/benches/float_cmp.rs b/builtins-test/benches/float_cmp.rs index 4493765ec..42d665239 100644 --- a/builtins-test/benches/float_cmp.rs +++ b/builtins-test/benches/float_cmp.rs @@ -1,9 +1,8 @@ #![cfg_attr(f128_enabled, feature(f128))] use builtins_test::float_bench; -use criterion::{Criterion, criterion_main}; - use compiler_builtins::float::cmp; +use criterion::{Criterion, criterion_main}; /// `gt` symbols are allowed to return differing results, they just get compared /// to 0. diff --git a/builtins-test/benches/mem_icount.rs b/builtins-test/benches/mem_icount.rs index 63045f6e1..bd88cf80c 100644 --- a/builtins-test/benches/mem_icount.rs +++ b/builtins-test/benches/mem_icount.rs @@ -239,9 +239,10 @@ mod mcmp { } mod mmove { - use super::*; use Spread::{Aligned, Large, Medium, Small}; + use super::*; + struct Cfg { len: usize, spread: Spread, diff --git a/builtins-test/src/bench.rs b/builtins-test/src/bench.rs index 45a3a1ad4..2348f6bc9 100644 --- a/builtins-test/src/bench.rs +++ b/builtins-test/src/bench.rs @@ -1,6 +1,6 @@ +use alloc::vec::Vec; use core::cell::RefCell; -use alloc::vec::Vec; use compiler_builtins::float::Float; /// Fuzz with these many items to ensure equal functions diff --git a/builtins-test/src/lib.rs b/builtins-test/src/lib.rs index a83aea562..c596ac213 100644 --- a/builtins-test/src/lib.rs +++ b/builtins-test/src/lib.rs @@ -21,7 +21,6 @@ extern crate alloc; use compiler_builtins::float::Float; use compiler_builtins::int::{Int, MinInt}; - use rand_xoshiro::Xoshiro128StarStar; use rand_xoshiro::rand_core::{RngCore, SeedableRng}; diff --git a/builtins-test/tests/cmp.rs b/builtins-test/tests/cmp.rs index dbedd213e..a904dc5f7 100644 --- a/builtins-test/tests/cmp.rs +++ b/builtins-test/tests/cmp.rs @@ -97,7 +97,6 @@ mod float_comparisons { __eqkf2 as __eqtf2, __gekf2 as __getf2, __gtkf2 as __gttf2, __lekf2 as __letf2, __ltkf2 as __lttf2, __nekf2 as __netf2, __unordkf2 as __unordtf2, }; - #[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))] use compiler_builtins::float::cmp::{ __eqtf2, __getf2, __gttf2, __letf2, __lttf2, __netf2, __unordtf2, diff --git a/builtins-test/tests/div_rem.rs b/builtins-test/tests/div_rem.rs index 6c0280a32..5ae653cc9 100644 --- a/builtins-test/tests/div_rem.rs +++ b/builtins-test/tests/div_rem.rs @@ -1,11 +1,10 @@ #![feature(f128)] #![allow(unused_macros)] +use builtins_test::*; use compiler_builtins::int::sdiv::{__divmoddi4, __divmodsi4, __divmodti4}; use compiler_builtins::int::udiv::{__udivmoddi4, __udivmodsi4, __udivmodti4, u128_divide_sparc}; -use builtins_test::*; - // Division algorithms have by far the nastiest and largest number of edge cases, and experience shows // that sometimes 100_000 iterations of the random fuzzer is needed. diff --git a/compiler-builtins/build.rs b/compiler-builtins/build.rs index d627121f3..04369a4aa 100644 --- a/compiler-builtins/build.rs +++ b/compiler-builtins/build.rs @@ -1,8 +1,11 @@ mod configure; -use std::{collections::BTreeMap, env, path::PathBuf, sync::atomic::Ordering}; +use std::collections::BTreeMap; +use std::env; +use std::path::PathBuf; +use std::sync::atomic::Ordering; -use configure::{configure_aliases, configure_f16_f128, Target}; +use configure::{Target, configure_aliases, configure_f16_f128}; fn main() { println!("cargo::rerun-if-changed=build.rs"); diff --git a/compiler-builtins/src/arm_linux.rs b/compiler-builtins/src/arm_linux.rs index aeb3ff3e5..6ce67ba71 100644 --- a/compiler-builtins/src/arm_linux.rs +++ b/compiler-builtins/src/arm_linux.rs @@ -1,6 +1,5 @@ -use core::arch; -use core::mem; use core::sync::atomic::{AtomicU32, Ordering}; +use core::{arch, mem}; // Kernel-provided user-mode helper functions: // https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt diff --git a/compiler-builtins/src/float/conv.rs b/compiler-builtins/src/float/conv.rs index 42a526bd5..f5427a113 100644 --- a/compiler-builtins/src/float/conv.rs +++ b/compiler-builtins/src/float/conv.rs @@ -1,8 +1,7 @@ use core::ops::Neg; -use crate::int::{CastFrom, CastInto, Int, MinInt}; - use super::Float; +use crate::int::{CastFrom, CastInto, Int, MinInt}; /// Conversions from integers to floats. /// diff --git a/compiler-builtins/src/float/div.rs b/compiler-builtins/src/float/div.rs index 929f29197..5df637c7e 100644 --- a/compiler-builtins/src/float/div.rs +++ b/compiler-builtins/src/float/div.rs @@ -79,11 +79,12 @@ //! //! [Newton-Raphson method]: https://en.wikipedia.org/wiki/Newton%27s_method +use core::mem::size_of; +use core::ops; + use super::HalfRep; use crate::float::Float; use crate::int::{CastFrom, CastInto, DInt, HInt, Int, MinInt}; -use core::mem::size_of; -use core::ops; fn div(a: F, b: F) -> F where @@ -487,7 +488,7 @@ where }; residual_lo += abs_result & one; // tie to even - // conditionally turns the below LT comparison into LTE + // conditionally turns the below LT comparison into LTE abs_result += u8::from(residual_lo > b_significand).into(); if F::BITS == 128 || (F::BITS == 32 && half_iterations > 0) { diff --git a/compiler-builtins/src/float/mod.rs b/compiler-builtins/src/float/mod.rs index 41b308626..f2c543bd2 100644 --- a/compiler-builtins/src/float/mod.rs +++ b/compiler-builtins/src/float/mod.rs @@ -11,6 +11,5 @@ pub mod trunc; #[cfg(not(feature = "public-test-deps"))] pub(crate) use traits::{Float, HalfRep}; - #[cfg(feature = "public-test-deps")] pub use traits::{Float, HalfRep}; diff --git a/compiler-builtins/src/float/pow.rs b/compiler-builtins/src/float/pow.rs index fe76060e0..45a4ad904 100644 --- a/compiler-builtins/src/float/pow.rs +++ b/compiler-builtins/src/float/pow.rs @@ -18,11 +18,7 @@ fn pow(a: F, b: i32) -> F { a *= a; } - if recip { - F::ONE / mul - } else { - mul - } + if recip { F::ONE / mul } else { mul } } intrinsics! { diff --git a/compiler-builtins/src/int/big.rs b/compiler-builtins/src/int/big.rs index 0ef3caaed..61f1349d9 100644 --- a/compiler-builtins/src/int/big.rs +++ b/compiler-builtins/src/int/big.rs @@ -2,9 +2,10 @@ #![allow(unused)] -use crate::int::{DInt, HInt, Int, MinInt}; use core::{fmt, ops}; +use crate::int::{DInt, HInt, Int, MinInt}; + const WORD_LO_MASK: u64 = 0x00000000ffffffff; const WORD_HI_MASK: u64 = 0xffffffff00000000; const WORD_FULL_MASK: u64 = 0xffffffffffffffff; diff --git a/compiler-builtins/src/int/leading_zeros.rs b/compiler-builtins/src/int/leading_zeros.rs index ba735aa74..a57f88184 100644 --- a/compiler-builtins/src/int/leading_zeros.rs +++ b/compiler-builtins/src/int/leading_zeros.rs @@ -60,11 +60,7 @@ mod implementation { } // the last two bisections are combined into one conditional t = x >> 1; - if t != T::ZERO { - z - 2 - } else { - z - x.cast() - } + if t != T::ZERO { z - 2 } else { z - x.cast() } // We could potentially save a few cycles by using the LUT trick from // "https://embeddedgurus.com/state-space/2014/09/ diff --git a/compiler-builtins/src/int/mod.rs b/compiler-builtins/src/int/mod.rs index 1f1be711b..5633510d3 100644 --- a/compiler-builtins/src/int/mod.rs +++ b/compiler-builtins/src/int/mod.rs @@ -12,9 +12,7 @@ mod traits; pub mod udiv; pub use big::{i256, u256}; - #[cfg(not(feature = "public-test-deps"))] pub(crate) use traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt}; - #[cfg(feature = "public-test-deps")] pub use traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt}; diff --git a/compiler-builtins/src/int/specialized_div_rem/mod.rs b/compiler-builtins/src/int/specialized_div_rem/mod.rs index a91fe6632..b81f04698 100644 --- a/compiler-builtins/src/int/specialized_div_rem/mod.rs +++ b/compiler-builtins/src/int/specialized_div_rem/mod.rs @@ -58,7 +58,6 @@ mod delegate; #[allow(unused_imports)] #[cfg(not(feature = "public-test-deps"))] pub(crate) use self::delegate::u128_divide_sparc; - #[cfg(feature = "public-test-deps")] pub use self::delegate::u128_divide_sparc; diff --git a/compiler-builtins/src/int/udiv.rs b/compiler-builtins/src/int/udiv.rs index f18537b00..4e985ba47 100644 --- a/compiler-builtins/src/int/udiv.rs +++ b/compiler-builtins/src/int/udiv.rs @@ -1,6 +1,5 @@ #[cfg(not(feature = "public-test-deps"))] pub(crate) use crate::int::specialized_div_rem::*; - #[cfg(feature = "public-test-deps")] pub use crate::int::specialized_div_rem::*; diff --git a/compiler-builtins/src/mem/x86_64.rs b/compiler-builtins/src/mem/x86_64.rs index 40b67093f..5cbe83ab1 100644 --- a/compiler-builtins/src/mem/x86_64.rs +++ b/compiler-builtins/src/mem/x86_64.rs @@ -17,8 +17,7 @@ // Note that ERMSB does not enhance the backwards (DF=1) "rep movsb". use core::arch::asm; -use core::intrinsics; -use core::mem; +use core::{intrinsics, mem}; #[inline(always)] #[cfg(target_feature = "ermsb")] diff --git a/crates/libm-macros/src/enums.rs b/crates/libm-macros/src/enums.rs index 864b625ea..b4646f984 100644 --- a/crates/libm-macros/src/enums.rs +++ b/crates/libm-macros/src/enums.rs @@ -26,7 +26,10 @@ pub fn function_enum( }; if let Some(tt) = attr.next() { - return Err(syn::Error::new(tt.span(), "unexpected token after identifier")); + return Err(syn::Error::new( + tt.span(), + "unexpected token after identifier", + )); } let enum_name = &item.ident; @@ -46,8 +49,12 @@ pub fn function_enum( // Match arm for `fn base_name(self)` matcher base_arms.push(quote! { Self::#ident => #base_enum::#bname_ident }); - let variant = - Variant { attrs: Vec::new(), ident, fields: Fields::Unit, discriminant: None }; + let variant = Variant { + attrs: Vec::new(), + ident, + fields: Fields::Unit, + discriminant: None, + }; item.variants.push(variant); } @@ -108,7 +115,10 @@ pub fn base_name_enum( return Err(syn::Error::new(sp.span(), "no attributes expected")); } - let mut base_names: Vec<_> = ALL_OPERATIONS.iter().map(|func| base_name(func.name)).collect(); + let mut base_names: Vec<_> = ALL_OPERATIONS + .iter() + .map(|func| base_name(func.name)) + .collect(); base_names.sort_unstable(); base_names.dedup(); @@ -121,8 +131,12 @@ pub fn base_name_enum( // Match arm for `fn as_str(self)` matcher as_str_arms.push(quote! { Self::#ident => #base_name }); - let variant = - Variant { attrs: Vec::new(), ident, fields: Fields::Unit, discriminant: None }; + let variant = Variant { + attrs: Vec::new(), + ident, + fields: Fields::Unit, + discriminant: None, + }; item.variants.push(variant); } @@ -147,7 +161,10 @@ pub fn base_name_enum( /// Verify that an enum is empty, otherwise return an error fn expect_empty_enum(item: &ItemEnum) -> syn::Result<()> { if !item.variants.is_empty() { - Err(syn::Error::new(item.variants.span(), "expected an empty enum")) + Err(syn::Error::new( + item.variants.span(), + "expected an empty enum", + )) } else { Ok(()) } diff --git a/crates/libm-macros/src/lib.rs b/crates/libm-macros/src/lib.rs index 3cee5385b..3cdd364e8 100644 --- a/crates/libm-macros/src/lib.rs +++ b/crates/libm-macros/src/lib.rs @@ -11,7 +11,9 @@ use syn::spanned::Spanned; use syn::visit_mut::VisitMut; use syn::{Ident, ItemEnum}; -const KNOWN_TYPES: &[&str] = &["FTy", "CFn", "CArgs", "CRet", "RustFn", "RustArgs", "RustRet"]; +const KNOWN_TYPES: &[&str] = &[ + "FTy", "CFn", "CArgs", "CRet", "RustFn", "RustArgs", "RustRet", +]; /// Populate an enum with a variant representing function. Names are in upper camel case. /// @@ -142,10 +144,17 @@ fn validate(input: &mut StructuredInput) -> syn::Result .flat_map(|map_list| map_list.iter()) .flat_map(|attr_map| attr_map.names.iter()); let only_mentions = input.only.iter().flat_map(|only_list| only_list.iter()); - let fn_extra_mentions = - input.fn_extra.iter().flat_map(|v| v.keys()).filter(|name| *name != "_"); - let all_mentioned_fns = - input.skip.iter().chain(only_mentions).chain(attr_mentions).chain(fn_extra_mentions); + let fn_extra_mentions = input + .fn_extra + .iter() + .flat_map(|v| v.keys()) + .filter(|name| *name != "_"); + let all_mentioned_fns = input + .skip + .iter() + .chain(only_mentions) + .chain(attr_mentions) + .chain(fn_extra_mentions); // Make sure that every function mentioned is a real function for mentioned in all_mentioned_fns { @@ -171,7 +180,11 @@ fn validate(input: &mut StructuredInput) -> syn::Result for func in ALL_OPERATIONS.iter() { let fn_name = func.name; // If we have an `only` list and it does _not_ contain this function name, skip it - if input.only.as_ref().is_some_and(|only| !only.iter().any(|o| o == fn_name)) { + if input + .only + .as_ref() + .is_some_and(|only| !only.iter().any(|o| o == fn_name)) + { continue; } @@ -296,8 +309,11 @@ fn expand(input: StructuredInput, fn_list: &[&MathOpInfo]) -> syn::Result { - let mut fn_extra = - map.get(&fn_name).or_else(|| map.get(&default_ident)).unwrap().clone(); + let mut fn_extra = map + .get(&fn_name) + .or_else(|| map.get(&default_ident)) + .unwrap() + .clone(); let mut v = MacroReplace::new(func.name); v.visit_expr_mut(&mut fn_extra); @@ -357,7 +373,11 @@ struct MacroReplace { impl MacroReplace { fn new(name: &'static str) -> Self { let norm_name = base_name(name); - Self { fn_name: name, norm_name: norm_name.to_owned(), error: None } + Self { + fn_name: name, + norm_name: norm_name.to_owned(), + error: None, + } } fn finish(self) -> syn::Result<()> { @@ -377,8 +397,10 @@ impl MacroReplace { "MACRO_FN_NAME" => *i = Ident::new(self.fn_name, i.span()), "MACRO_FN_NAME_NORMALIZED" => *i = Ident::new(&self.norm_name, i.span()), _ => { - self.error = - Some(syn::Error::new(i.span(), format!("unrecognized meta expression `{s}`"))); + self.error = Some(syn::Error::new( + i.span(), + format!("unrecognized meta expression `{s}`"), + )); } } } diff --git a/crates/libm-macros/src/parse.rs b/crates/libm-macros/src/parse.rs index 369bbae2f..d60d1247a 100644 --- a/crates/libm-macros/src/parse.rs +++ b/crates/libm-macros/src/parse.rs @@ -16,7 +16,9 @@ pub struct Invocation { impl Parse for Invocation { fn parse(input: ParseStream) -> syn::Result { - Ok(Self { fields: input.parse_terminated(Mapping::parse, Token![,])? }) + Ok(Self { + fields: input.parse_terminated(Mapping::parse, Token![,])?, + }) } } @@ -30,7 +32,11 @@ struct Mapping { impl Parse for Mapping { fn parse(input: ParseStream) -> syn::Result { - Ok(Self { name: input.parse()?, _sep: input.parse()?, expr: input.parse()? }) + Ok(Self { + name: input.parse()?, + _sep: input.parse()?, + expr: input.parse()?, + }) } } @@ -133,7 +139,13 @@ fn extract_fn_extra_field(expr: Expr) -> syn::Result> { return Err(e); }; - let ExprMatch { attrs, match_token: _, expr, brace_token: _, arms } = mexpr; + let ExprMatch { + attrs, + match_token: _, + expr, + brace_token: _, + arms, + } = mexpr; expect_empty_attrs(&attrs)?; @@ -146,7 +158,14 @@ fn extract_fn_extra_field(expr: Expr) -> syn::Result> { let mut res = BTreeMap::new(); for arm in arms { - let Arm { attrs, pat, guard, fat_arrow_token: _, body, comma: _ } = arm; + let Arm { + attrs, + pat, + guard, + fat_arrow_token: _, + body, + comma: _, + } = arm; expect_empty_attrs(&attrs)?; @@ -177,15 +196,20 @@ fn expect_empty_attrs(attrs: &[Attribute]) -> syn::Result<()> { return Ok(()); } - let e = - syn::Error::new(attrs.first().unwrap().span(), "no attributes allowed in this position"); + let e = syn::Error::new( + attrs.first().unwrap().span(), + "no attributes allowed in this position", + ); Err(e) } /// Extract a named field from a map, raising an error if it doesn't exist. fn expect_field(v: &mut Vec, name: &str) -> syn::Result { let pos = v.iter().position(|v| v.name == name).ok_or_else(|| { - syn::Error::new(Span::call_site(), format!("missing expected field `{name}`")) + syn::Error::new( + Span::call_site(), + format!("missing expected field `{name}`"), + ) })?; Ok(v.remove(pos).expr) diff --git a/crates/libm-macros/src/shared.rs b/crates/libm-macros/src/shared.rs index 5e58220eb..750ed1afb 100644 --- a/crates/libm-macros/src/shared.rs +++ b/crates/libm-macros/src/shared.rs @@ -7,7 +7,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `fn(f16) -> f16` FloatTy::F16, - Signature { args: &[Ty::F16], returns: &[Ty::F16] }, + Signature { + args: &[Ty::F16], + returns: &[Ty::F16], + }, None, &[ "ceilf16", @@ -23,7 +26,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `fn(f32) -> f32` FloatTy::F32, - Signature { args: &[Ty::F32], returns: &[Ty::F32] }, + Signature { + args: &[Ty::F32], + returns: &[Ty::F32], + }, None, &[ "acosf", @@ -68,7 +74,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `(f64) -> f64` FloatTy::F64, - Signature { args: &[Ty::F64], returns: &[Ty::F64] }, + Signature { + args: &[Ty::F64], + returns: &[Ty::F64], + }, None, &[ "acos", @@ -113,7 +122,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `fn(f128) -> f128` FloatTy::F128, - Signature { args: &[Ty::F128], returns: &[Ty::F128] }, + Signature { + args: &[Ty::F128], + returns: &[Ty::F128], + }, None, &[ "ceilf128", @@ -129,7 +141,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `(f16, f16) -> f16` FloatTy::F16, - Signature { args: &[Ty::F16, Ty::F16], returns: &[Ty::F16] }, + Signature { + args: &[Ty::F16, Ty::F16], + returns: &[Ty::F16], + }, None, &[ "copysignf16", @@ -146,7 +161,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `(f32, f32) -> f32` FloatTy::F32, - Signature { args: &[Ty::F32, Ty::F32], returns: &[Ty::F32] }, + Signature { + args: &[Ty::F32, Ty::F32], + returns: &[Ty::F32], + }, None, &[ "atan2f", @@ -168,7 +186,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `(f64, f64) -> f64` FloatTy::F64, - Signature { args: &[Ty::F64, Ty::F64], returns: &[Ty::F64] }, + Signature { + args: &[Ty::F64, Ty::F64], + returns: &[Ty::F64], + }, None, &[ "atan2", @@ -190,7 +211,10 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `(f128, f128) -> f128` FloatTy::F128, - Signature { args: &[Ty::F128, Ty::F128], returns: &[Ty::F128] }, + Signature { + args: &[Ty::F128, Ty::F128], + returns: &[Ty::F128], + }, None, &[ "copysignf128", @@ -207,134 +231,215 @@ const ALL_OPERATIONS_NESTED: &[(FloatTy, Signature, Option, &[&str])] ( // `(f32, f32, f32) -> f32` FloatTy::F32, - Signature { args: &[Ty::F32, Ty::F32, Ty::F32], returns: &[Ty::F32] }, + Signature { + args: &[Ty::F32, Ty::F32, Ty::F32], + returns: &[Ty::F32], + }, None, &["fmaf"], ), ( // `(f64, f64, f64) -> f64` FloatTy::F64, - Signature { args: &[Ty::F64, Ty::F64, Ty::F64], returns: &[Ty::F64] }, + Signature { + args: &[Ty::F64, Ty::F64, Ty::F64], + returns: &[Ty::F64], + }, None, &["fma"], ), ( // `(f128, f128, f128) -> f128` FloatTy::F128, - Signature { args: &[Ty::F128, Ty::F128, Ty::F128], returns: &[Ty::F128] }, + Signature { + args: &[Ty::F128, Ty::F128, Ty::F128], + returns: &[Ty::F128], + }, None, &["fmaf128"], ), ( // `(f32) -> i32` FloatTy::F32, - Signature { args: &[Ty::F32], returns: &[Ty::I32] }, + Signature { + args: &[Ty::F32], + returns: &[Ty::I32], + }, None, &["ilogbf"], ), ( // `(f64) -> i32` FloatTy::F64, - Signature { args: &[Ty::F64], returns: &[Ty::I32] }, + Signature { + args: &[Ty::F64], + returns: &[Ty::I32], + }, None, &["ilogb"], ), ( // `(i32, f32) -> f32` FloatTy::F32, - Signature { args: &[Ty::I32, Ty::F32], returns: &[Ty::F32] }, + Signature { + args: &[Ty::I32, Ty::F32], + returns: &[Ty::F32], + }, None, &["jnf", "ynf"], ), ( // `(i32, f64) -> f64` FloatTy::F64, - Signature { args: &[Ty::I32, Ty::F64], returns: &[Ty::F64] }, + Signature { + args: &[Ty::I32, Ty::F64], + returns: &[Ty::F64], + }, None, &["jn", "yn"], ), ( // `(f16, i32) -> f16` FloatTy::F16, - Signature { args: &[Ty::F16, Ty::I32], returns: &[Ty::F16] }, + Signature { + args: &[Ty::F16, Ty::I32], + returns: &[Ty::F16], + }, None, &["ldexpf16", "scalbnf16"], ), ( // `(f32, i32) -> f32` FloatTy::F32, - Signature { args: &[Ty::F32, Ty::I32], returns: &[Ty::F32] }, + Signature { + args: &[Ty::F32, Ty::I32], + returns: &[Ty::F32], + }, None, &["ldexpf", "scalbnf"], ), ( // `(f64, i64) -> f64` FloatTy::F64, - Signature { args: &[Ty::F64, Ty::I32], returns: &[Ty::F64] }, + Signature { + args: &[Ty::F64, Ty::I32], + returns: &[Ty::F64], + }, None, &["ldexp", "scalbn"], ), ( // `(f128, i32) -> f128` FloatTy::F128, - Signature { args: &[Ty::F128, Ty::I32], returns: &[Ty::F128] }, + Signature { + args: &[Ty::F128, Ty::I32], + returns: &[Ty::F128], + }, None, &["ldexpf128", "scalbnf128"], ), ( // `(f32, &mut f32) -> f32` as `(f32) -> (f32, f32)` FloatTy::F32, - Signature { args: &[Ty::F32], returns: &[Ty::F32, Ty::F32] }, - Some(Signature { args: &[Ty::F32, Ty::MutF32], returns: &[Ty::F32] }), + Signature { + args: &[Ty::F32], + returns: &[Ty::F32, Ty::F32], + }, + Some(Signature { + args: &[Ty::F32, Ty::MutF32], + returns: &[Ty::F32], + }), &["modff"], ), ( // `(f64, &mut f64) -> f64` as `(f64) -> (f64, f64)` FloatTy::F64, - Signature { args: &[Ty::F64], returns: &[Ty::F64, Ty::F64] }, - Some(Signature { args: &[Ty::F64, Ty::MutF64], returns: &[Ty::F64] }), + Signature { + args: &[Ty::F64], + returns: &[Ty::F64, Ty::F64], + }, + Some(Signature { + args: &[Ty::F64, Ty::MutF64], + returns: &[Ty::F64], + }), &["modf"], ), ( // `(f32, &mut c_int) -> f32` as `(f32) -> (f32, i32)` FloatTy::F32, - Signature { args: &[Ty::F32], returns: &[Ty::F32, Ty::I32] }, - Some(Signature { args: &[Ty::F32, Ty::MutCInt], returns: &[Ty::F32] }), + Signature { + args: &[Ty::F32], + returns: &[Ty::F32, Ty::I32], + }, + Some(Signature { + args: &[Ty::F32, Ty::MutCInt], + returns: &[Ty::F32], + }), &["frexpf", "lgammaf_r"], ), ( // `(f64, &mut c_int) -> f64` as `(f64) -> (f64, i32)` FloatTy::F64, - Signature { args: &[Ty::F64], returns: &[Ty::F64, Ty::I32] }, - Some(Signature { args: &[Ty::F64, Ty::MutCInt], returns: &[Ty::F64] }), + Signature { + args: &[Ty::F64], + returns: &[Ty::F64, Ty::I32], + }, + Some(Signature { + args: &[Ty::F64, Ty::MutCInt], + returns: &[Ty::F64], + }), &["frexp", "lgamma_r"], ), ( // `(f32, f32, &mut c_int) -> f32` as `(f32, f32) -> (f32, i32)` FloatTy::F32, - Signature { args: &[Ty::F32, Ty::F32], returns: &[Ty::F32, Ty::I32] }, - Some(Signature { args: &[Ty::F32, Ty::F32, Ty::MutCInt], returns: &[Ty::F32] }), + Signature { + args: &[Ty::F32, Ty::F32], + returns: &[Ty::F32, Ty::I32], + }, + Some(Signature { + args: &[Ty::F32, Ty::F32, Ty::MutCInt], + returns: &[Ty::F32], + }), &["remquof"], ), ( // `(f64, f64, &mut c_int) -> f64` as `(f64, f64) -> (f64, i32)` FloatTy::F64, - Signature { args: &[Ty::F64, Ty::F64], returns: &[Ty::F64, Ty::I32] }, - Some(Signature { args: &[Ty::F64, Ty::F64, Ty::MutCInt], returns: &[Ty::F64] }), + Signature { + args: &[Ty::F64, Ty::F64], + returns: &[Ty::F64, Ty::I32], + }, + Some(Signature { + args: &[Ty::F64, Ty::F64, Ty::MutCInt], + returns: &[Ty::F64], + }), &["remquo"], ), ( // `(f32, &mut f32, &mut f32)` as `(f32) -> (f32, f32)` FloatTy::F32, - Signature { args: &[Ty::F32], returns: &[Ty::F32, Ty::F32] }, - Some(Signature { args: &[Ty::F32, Ty::MutF32, Ty::MutF32], returns: &[] }), + Signature { + args: &[Ty::F32], + returns: &[Ty::F32, Ty::F32], + }, + Some(Signature { + args: &[Ty::F32, Ty::MutF32, Ty::MutF32], + returns: &[], + }), &["sincosf"], ), ( // `(f64, &mut f64, &mut f64)` as `(f64) -> (f64, f64)` FloatTy::F64, - Signature { args: &[Ty::F64], returns: &[Ty::F64, Ty::F64] }, - Some(Signature { args: &[Ty::F64, Ty::MutF64, Ty::MutF64], returns: &[] }), + Signature { + args: &[Ty::F64], + returns: &[Ty::F64, Ty::F64], + }, + Some(Signature { + args: &[Ty::F64, Ty::MutF64, Ty::MutF64], + returns: &[], + }), &["sincos"], ), ]; diff --git a/crates/musl-math-sys/build.rs b/crates/musl-math-sys/build.rs index f06d84ee2..b00dbc73e 100644 --- a/crates/musl-math-sys/build.rs +++ b/crates/musl-math-sys/build.rs @@ -8,7 +8,10 @@ const LIB_NAME: &str = "musl_math_prefixed"; /// Files that have more than one symbol. Map of file names to the symbols defined in that file. const MULTIPLE_SYMBOLS: &[(&str, &[&str])] = &[ - ("__invtrigl", &["__invtrigl", "__invtrigl_R", "__pio2_hi", "__pio2_lo"]), + ( + "__invtrigl", + &["__invtrigl", "__invtrigl_R", "__pio2_hi", "__pio2_lo"], + ), ("__polevll", &["__polevll", "__p1evll"]), ("erf", &["erf", "erfc"]), ("erff", &["erff", "erfcf"]), @@ -82,9 +85,16 @@ impl Config { let musl_dir = manifest_dir.join("musl"); let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let musl_arch = if target_arch == "x86" { "i386".to_owned() } else { target_arch.clone() }; + let musl_arch = if target_arch == "x86" { + "i386".to_owned() + } else { + target_arch.clone() + }; - println!("cargo::rerun-if-changed={}/c_patches", manifest_dir.display()); + println!( + "cargo::rerun-if-changed={}/c_patches", + manifest_dir.display() + ); println!("cargo::rerun-if-changed={}", musl_dir.display()); Self { @@ -108,7 +118,10 @@ fn build_musl_math(cfg: &Config) { let musl_dir = &cfg.musl_dir; let math = musl_dir.join("src/math"); let arch_dir = musl_dir.join("arch").join(&cfg.musl_arch); - assert!(math.exists(), "musl source not found. Is the submodule up to date?"); + assert!( + math.exists(), + "musl source not found. Is the submodule up to date?" + ); let source_map = find_math_source(&math, cfg); let out_path = cfg.out_dir.join(format!("lib{LIB_NAME}.a")); @@ -125,7 +138,11 @@ fn build_musl_math(cfg: &Config) { .stderr(Stdio::inherit()) .output() .unwrap(); - assert!(sed_stat.status.success(), "sed command failed: {:?}", sed_stat.status); + assert!( + sed_stat.status.success(), + "sed command failed: {:?}", + sed_stat.status + ); fs::write(obj_include.join("bits/alltypes.h"), sed_stat.stdout).unwrap(); @@ -163,8 +180,9 @@ fn build_musl_math(cfg: &Config) { // Trickery! Redefine the symbol names to have the prefix `musl_`, which allows us to // differentiate these symbols from whatever we provide. - if let Some((_names, syms)) = - MULTIPLE_SYMBOLS.iter().find(|(name, _syms)| *name == sym_name) + if let Some((_names, syms)) = MULTIPLE_SYMBOLS + .iter() + .find(|(name, _syms)| *name == sym_name) { // Handle the occasional file that defines multiple symbols for sym in *syms { @@ -291,21 +309,34 @@ fn validate_archive_symbols(out_path: &Path) { ]; // List global undefined symbols - let out = - Command::new("nm").arg("-guj").arg(out_path).stderr(Stdio::inherit()).output().unwrap(); + let out = Command::new("nm") + .arg("-guj") + .arg(out_path) + .stderr(Stdio::inherit()) + .output() + .unwrap(); let undef = str::from_utf8(&out.stdout).unwrap(); let mut undef = undef.lines().collect::>(); undef.retain(|sym| { // Account for file formats that add a leading `_` - !ALLOWED_UNDEF_PFX.iter().any(|pfx| sym.starts_with(pfx) || sym[1..].starts_with(pfx)) + !ALLOWED_UNDEF_PFX + .iter() + .any(|pfx| sym.starts_with(pfx) || sym[1..].starts_with(pfx)) }); - assert!(undef.is_empty(), "found disallowed undefined symbols: {undef:#?}"); + assert!( + undef.is_empty(), + "found disallowed undefined symbols: {undef:#?}" + ); // Find any symbols that are missing the `_musl_` prefix` - let out = - Command::new("nm").arg("-gUj").arg(out_path).stderr(Stdio::inherit()).output().unwrap(); + let out = Command::new("nm") + .arg("-gUj") + .arg(out_path) + .stderr(Stdio::inherit()) + .output() + .unwrap(); let defined = str::from_utf8(&out.stdout).unwrap(); let mut defined = defined.lines().collect::>(); diff --git a/crates/util/src/main.rs b/crates/util/src/main.rs index ef70ec903..e70578699 100644 --- a/crates/util/src/main.rs +++ b/crates/util/src/main.rs @@ -221,7 +221,11 @@ macro_rules! impl_parse_tuple_via_rug { impl ParseTuple for ($ty, $ty, $ty) { fn parse(input: &[&str]) -> Self { assert_eq!(input.len(), 3, "expected three arguments, got {input:?}"); - (parse_rug(input, 0), parse_rug(input, 1), parse_rug(input, 2)) + ( + parse_rug(input, 0), + parse_rug(input, 1), + parse_rug(input, 2), + ) } } }; diff --git a/libm-test/benches/random.rs b/libm-test/benches/random.rs index 63d7e5c6d..81f58e3a6 100644 --- a/libm-test/benches/random.rs +++ b/libm-test/benches/random.rs @@ -7,7 +7,11 @@ use libm_test::generate::random::RandomInput; use libm_test::{CheckBasis, CheckCtx, GeneratorKind, MathOp, TupleCall}; /// Benchmark with this many items to get a variety -const BENCH_ITER_ITEMS: usize = if cfg!(feature = "short-benchmarks") { 50 } else { 500 }; +const BENCH_ITER_ITEMS: usize = if cfg!(feature = "short-benchmarks") { + 50 +} else { + 500 +}; /// Extra parameters we only care about if we are benchmarking against musl. #[allow(dead_code)] @@ -53,8 +57,10 @@ where let name = Op::NAME; let ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Musl, GeneratorKind::Random); - let benchvec: Vec<_> = - random::get_test_cases::(&ctx).0.take(BENCH_ITER_ITEMS).collect(); + let benchvec: Vec<_> = random::get_test_cases::(&ctx) + .0 + .take(BENCH_ITER_ITEMS) + .collect(); // Perform a sanity check that we are benchmarking the same thing // Don't test against musl if it is not available @@ -73,7 +79,10 @@ where let musl_res = input.call(musl_fn); let crate_res = input.call(Op::ROUTINE); - crate_res.validate(musl_res, input, &ctx).context(name).unwrap(); + crate_res + .validate(musl_res, input, &ctx) + .context(name) + .unwrap(); } #[cfg(not(feature = "build-musl"))] diff --git a/libm-test/examples/plot_domains.rs b/libm-test/examples/plot_domains.rs index 78524761e..3563103b8 100644 --- a/libm-test/examples/plot_domains.rs +++ b/libm-test/examples/plot_domains.rs @@ -56,7 +56,13 @@ where Op::RustArgs: SpacedInput, { let mut ctx = CheckCtx::new(Op::IDENTIFIER, CheckBasis::Mpfr, GeneratorKind::QuickSpaced); - plot_one_generator(out_dir, &ctx, "logspace", config, spaced::get_test_cases::(&ctx).0); + plot_one_generator( + out_dir, + &ctx, + "logspace", + config, + spaced::get_test_cases::(&ctx).0, + ); ctx.gen_kind = GeneratorKind::EdgeCases; plot_one_generator( out_dir, diff --git a/libm-test/src/domain.rs b/libm-test/src/domain.rs index 41e948461..94641be9b 100644 --- a/libm-test/src/domain.rs +++ b/libm-test/src/domain.rs @@ -67,16 +67,25 @@ impl EitherPrim { /// Convenience 1-dimensional float domains. impl Domain { /// x ∈ ℝ - const UNBOUNDED: Self = - Self { start: Bound::Unbounded, end: Bound::Unbounded, check_points: None }; + const UNBOUNDED: Self = Self { + start: Bound::Unbounded, + end: Bound::Unbounded, + check_points: None, + }; /// x ∈ ℝ >= 0 - const POSITIVE: Self = - Self { start: Bound::Included(F::ZERO), end: Bound::Unbounded, check_points: None }; + const POSITIVE: Self = Self { + start: Bound::Included(F::ZERO), + end: Bound::Unbounded, + check_points: None, + }; /// x ∈ ℝ > 0 - const STRICTLY_POSITIVE: Self = - Self { start: Bound::Excluded(F::ZERO), end: Bound::Unbounded, check_points: None }; + const STRICTLY_POSITIVE: Self = Self { + start: Bound::Excluded(F::ZERO), + end: Bound::Unbounded, + check_points: None, + }; /// Wrap in the float variant of [`EitherPrim`]. const fn into_prim_float(self) -> EitherPrim> { @@ -87,8 +96,11 @@ impl Domain { /// Convenience 1-dimensional integer domains. impl Domain { /// x ∈ ℝ - const UNBOUNDED_INT: Self = - Self { start: Bound::Unbounded, end: Bound::Unbounded, check_points: None }; + const UNBOUNDED_INT: Self = Self { + start: Bound::Unbounded, + end: Bound::Unbounded, + check_points: None, + }; /// Wrap in the int variant of [`EitherPrim`]. const fn into_prim_int(self) -> EitherPrim, Self> { @@ -99,13 +111,18 @@ impl Domain { /// Multidimensional domains, represented as an array of 1-D domains. impl EitherPrim, Domain> { /// x ∈ ℝ - const UNBOUNDED1: [Self; 1] = - [Domain { start: Bound::Unbounded, end: Bound::Unbounded, check_points: None } - .into_prim_float()]; + const UNBOUNDED1: [Self; 1] = [Domain { + start: Bound::Unbounded, + end: Bound::Unbounded, + check_points: None, + } + .into_prim_float()]; /// {x1, x2} ∈ ℝ - const UNBOUNDED2: [Self; 2] = - [Domain::UNBOUNDED.into_prim_float(), Domain::UNBOUNDED.into_prim_float()]; + const UNBOUNDED2: [Self; 2] = [ + Domain::UNBOUNDED.into_prim_float(), + Domain::UNBOUNDED.into_prim_float(), + ]; /// {x1, x2, x3} ∈ ℝ const UNBOUNDED3: [Self; 3] = [ @@ -115,8 +132,10 @@ impl EitherPrim, Domain> { ]; /// {x1, x2} ∈ ℝ, one float and one int - const UNBOUNDED_F_I: [Self; 2] = - [Domain::UNBOUNDED.into_prim_float(), Domain::UNBOUNDED_INT.into_prim_int()]; + const UNBOUNDED_F_I: [Self; 2] = [ + Domain::UNBOUNDED.into_prim_float(), + Domain::UNBOUNDED_INT.into_prim_int(), + ]; /// x ∈ ℝ >= 0 const POSITIVE: [Self; 1] = [Domain::POSITIVE.into_prim_float()]; @@ -133,9 +152,12 @@ impl EitherPrim, Domain> { .into_prim_float()]; /// Domain for `acosh` - const ACOSH: [Self; 1] = - [Domain { start: Bound::Included(F::ONE), end: Bound::Unbounded, check_points: None } - .into_prim_float()]; + const ACOSH: [Self; 1] = [Domain { + start: Bound::Included(F::ONE), + end: Bound::Unbounded, + check_points: None, + } + .into_prim_float()]; /// Domain for `atanh` const ATANH: [Self; 1] = [Domain { @@ -157,9 +179,12 @@ impl EitherPrim, Domain> { const LOG: [Self; 1] = Self::STRICTLY_POSITIVE; /// Domain for `log1p` i.e. `log(1 + x)` - const LOG1P: [Self; 1] = - [Domain { start: Bound::Excluded(F::NEG_ONE), end: Bound::Unbounded, check_points: None } - .into_prim_float()]; + const LOG1P: [Self; 1] = [Domain { + start: Bound::Excluded(F::NEG_ONE), + end: Bound::Unbounded, + check_points: None, + } + .into_prim_float()]; /// Domain for `sqrt` const SQRT: [Self; 1] = Self::POSITIVE; @@ -187,8 +212,10 @@ impl EitherPrim, Domain> { /// Domain for `jn` and `yn`. // FIXME: the domain should provide some sort of "reasonable range" so we don't actually test // the entire system unbounded. - const BESSEL_N: [Self; 2] = - [Domain::UNBOUNDED_INT.into_prim_int(), Domain::UNBOUNDED.into_prim_float()]; + const BESSEL_N: [Self; 2] = [ + Domain::UNBOUNDED_INT.into_prim_int(), + Domain::UNBOUNDED.into_prim_float(), + ]; } /// Get the domain for a given function. diff --git a/libm-test/src/f8_impl.rs b/libm-test/src/f8_impl.rs index ddb7bf90e..905c7d7fd 100644 --- a/libm-test/src/f8_impl.rs +++ b/libm-test/src/f8_impl.rs @@ -498,6 +498,8 @@ impl fmt::LowerHex for f8 { } pub const fn hf8(s: &str) -> f8 { - let Ok(bits) = libm::support::hex_float::parse_hex_exact(s, 8, 3) else { panic!() }; + let Ok(bits) = libm::support::hex_float::parse_hex_exact(s, 8, 3) else { + panic!() + }; f8(bits as u8) } diff --git a/libm-test/src/generate.rs b/libm-test/src/generate.rs index 89ca09a7a..da080d23f 100644 --- a/libm-test/src/generate.rs +++ b/libm-test/src/generate.rs @@ -16,7 +16,11 @@ pub struct KnownSize { impl KnownSize { pub fn new(iter: I, total: u64) -> Self { - Self { total, current: 0, iter } + Self { + total, + current: 0, + iter, + } } } @@ -30,7 +34,10 @@ impl Iterator for KnownSize { return next; } - assert_eq!(self.current, self.total, "total items did not match expected"); + assert_eq!( + self.current, self.total, + "total items did not match expected" + ); None } diff --git a/libm-test/src/generate/case_list.rs b/libm-test/src/generate/case_list.rs index e3628d51c..f1e6fcec3 100644 --- a/libm-test/src/generate/case_list.rs +++ b/libm-test/src/generate/case_list.rs @@ -20,14 +20,21 @@ pub struct TestCase { impl TestCase { #[expect(dead_code)] fn append_inputs(v: &mut Vec, l: &[Op::RustArgs]) { - v.extend(l.iter().copied().map(|input| Self { input, output: None })); + v.extend(l.iter().copied().map(|input| Self { + input, + output: None, + })); } fn append_pairs(v: &mut Vec, l: &[(Op::RustArgs, Option)]) where Op::RustRet: Copy, { - v.extend(l.iter().copied().map(|(input, output)| Self { input, output })); + v.extend( + l.iter() + .copied() + .map(|(input, output)| Self { input, output }), + ); } } @@ -603,9 +610,15 @@ fn rint_cases() -> Vec> { &[ // Known failure on i586 #[cfg(not(x86_no_sse))] - ((hf64!("-0x1.e3f13ff995ffcp+38"),), Some(hf64!("-0x1.e3f13ff994000p+38"))), + ( + (hf64!("-0x1.e3f13ff995ffcp+38"),), + Some(hf64!("-0x1.e3f13ff994000p+38")), + ), #[cfg(x86_no_sse)] - ((hf64!("-0x1.e3f13ff995ffcp+38"),), Some(hf64!("-0x1.e3f13ff998000p+38"))), + ( + (hf64!("-0x1.e3f13ff995ffcp+38"),), + Some(hf64!("-0x1.e3f13ff998000p+38")), + ), ], ); v @@ -655,9 +668,15 @@ fn roundeven_cases() -> Vec> { &[ // Known failure on i586 #[cfg(not(x86_no_sse))] - ((hf64!("-0x1.e3f13ff995ffcp+38"),), Some(hf64!("-0x1.e3f13ff994000p+38"))), + ( + (hf64!("-0x1.e3f13ff995ffcp+38"),), + Some(hf64!("-0x1.e3f13ff994000p+38")), + ), #[cfg(x86_no_sse)] - ((hf64!("-0x1.e3f13ff995ffcp+38"),), Some(hf64!("-0x1.e3f13ff998000p+38"))), + ( + (hf64!("-0x1.e3f13ff995ffcp+38"),), + Some(hf64!("-0x1.e3f13ff998000p+38")), + ), ], ); v @@ -832,7 +851,9 @@ where { assert_eq!(ctx.basis, CheckBasis::None); assert_eq!(ctx.gen_kind, GeneratorKind::List); - Op::get_cases().into_iter().filter_map(|x| x.output.map(|o| (x.input, o))) + Op::get_cases() + .into_iter() + .filter_map(|x| x.output.map(|o| (x.input, o))) } /// Opposite of the above; extract only test cases that don't have a known output, to be run @@ -847,7 +868,18 @@ where assert_eq!(ctx.gen_kind, GeneratorKind::List); let cases = Op::get_cases(); - let count: u64 = cases.iter().filter(|case| case.output.is_none()).count().try_into().unwrap(); + let count: u64 = cases + .iter() + .filter(|case| case.output.is_none()) + .count() + .try_into() + .unwrap(); - (cases.into_iter().filter(|x| x.output.is_none()).map(|x| x.input), count) + ( + cases + .into_iter() + .filter(|x| x.output.is_none()) + .map(|x| x.input), + count, + ) } diff --git a/libm-test/src/generate/edge_cases.rs b/libm-test/src/generate/edge_cases.rs index 56cc9fa9a..2fb074638 100644 --- a/libm-test/src/generate/edge_cases.rs +++ b/libm-test/src/generate/edge_cases.rs @@ -249,7 +249,11 @@ macro_rules! impl_edge_case_input { .flat_map(move |(first, second)| { iter2.clone().map(move |third| (first, second, third)) }); - let count = steps0.checked_mul(steps1).unwrap().checked_mul(steps2).unwrap(); + let count = steps0 + .checked_mul(steps1) + .unwrap() + .checked_mul(steps2) + .unwrap(); (iter, count) } diff --git a/libm-test/src/generate/random.rs b/libm-test/src/generate/random.rs index e8a7ee905..4ee88946d 100644 --- a/libm-test/src/generate/random.rs +++ b/libm-test/src/generate/random.rs @@ -117,7 +117,10 @@ impl_random_input!(f128); /// Create a test case iterator. pub fn get_test_cases( ctx: &CheckCtx, -) -> (impl Iterator + Send + use<'_, RustArgs>, u64) { +) -> ( + impl Iterator + Send + use<'_, RustArgs>, + u64, +) { let (iter, count) = RustArgs::get_cases(ctx); // Wrap in `KnownSize` so we get an assertion if the cuunt is wrong. diff --git a/libm-test/src/generate/spaced.rs b/libm-test/src/generate/spaced.rs index bea3f4c7e..8e6b376eb 100644 --- a/libm-test/src/generate/spaced.rs +++ b/libm-test/src/generate/spaced.rs @@ -70,7 +70,9 @@ fn value_count() -> Option where u64: TryFrom, { - u64::try_from(F::Int::MAX).ok().and_then(|max| max.checked_add(1)) + u64::try_from(F::Int::MAX) + .ok() + .and_then(|max| max.checked_add(1)) } /// Returns an iterator of every possible value of type `F`. @@ -162,8 +164,11 @@ macro_rules! impl_spaced_input { .flat_map(move |(first, second)| { iter2.clone().map(move |third| (first, second, third)) }); - let count = - steps0.checked_mul(steps1).unwrap().checked_mul(steps2).unwrap(); + let count = steps0 + .checked_mul(steps1) + .unwrap() + .checked_mul(steps2) + .unwrap(); (EitherIter::B(iter), count) } diff --git a/libm-test/src/lib.rs b/libm-test/src/lib.rs index 485c01a47..730318abc 100644 --- a/libm-test/src/lib.rs +++ b/libm-test/src/lib.rs @@ -71,7 +71,12 @@ pub fn test_log(s: &str) { return None; }; - PathBuf::from(x).parent().unwrap().parent().unwrap().join("target") + PathBuf::from(x) + .parent() + .unwrap() + .parent() + .unwrap() + .join("target") } }; let outfile = target_dir.join("test-log.txt"); @@ -81,7 +86,9 @@ pub fn test_log(s: &str) { .append(true) .open(outfile) .expect("failed to open logfile"); - let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap(); + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); writeln!(f, "\n\nTest run at {}", now.as_secs()).unwrap(); writeln!(f, "arch: {}", env::consts::ARCH).unwrap(); diff --git a/libm-test/src/num.rs b/libm-test/src/num.rs index eed941423..3237c8503 100644 --- a/libm-test/src/num.rs +++ b/libm-test/src/num.rs @@ -180,8 +180,17 @@ impl Consts { neg_max_snan, } = self; - [pos_nan, neg_nan, max_qnan, min_snan, max_snan, neg_max_qnan, neg_min_snan, neg_max_snan] - .into_iter() + [ + pos_nan, + neg_nan, + max_qnan, + min_snan, + max_snan, + neg_max_qnan, + neg_min_snan, + neg_max_snan, + ] + .into_iter() } } @@ -229,7 +238,9 @@ where assert!(!end.is_nan()); assert!(end >= start); - let steps = steps.checked_sub(F::Int::ONE).expect("`steps` must be at least 2"); + let steps = steps + .checked_sub(F::Int::ONE) + .expect("`steps` must be at least 2"); let between = ulp_between(start, end).expect("`start` or `end` is NaN"); let spacing = (between / steps).max(F::Int::ONE); let steps = steps.min(between); // At maximum, one step per ULP @@ -283,15 +294,22 @@ mod tests { if i == 0 { assert_eq!(down, f8::NEG_INFINITY.to_bits(), "{i} next_down({v:#010b})"); } else { - let expected = - if v == f8::ZERO { 1 | f8::SIGN_MASK } else { f8::ALL[i - 1].to_bits() }; + let expected = if v == f8::ZERO { + 1 | f8::SIGN_MASK + } else { + f8::ALL[i - 1].to_bits() + }; assert_eq!(down, expected, "{i} next_down({v:#010b})"); } if i == f8::ALL_LEN - 1 { assert_eq!(up, f8::INFINITY.to_bits(), "{i} next_up({v:#010b})"); } else { - let expected = if v == f8::NEG_ZERO { 1 } else { f8::ALL[i + 1].to_bits() }; + let expected = if v == f8::NEG_ZERO { + 1 + } else { + f8::ALL[i + 1].to_bits() + }; assert_eq!(up, expected, "{i} next_up({v:#010b})"); } } @@ -300,8 +318,14 @@ mod tests { #[test] fn test_next_up_down_inf_nan() { assert_eq!(f8::NEG_INFINITY.next_up().to_bits(), f8::ALL[0].to_bits(),); - assert_eq!(f8::NEG_INFINITY.next_down().to_bits(), f8::NEG_INFINITY.to_bits(),); - assert_eq!(f8::INFINITY.next_down().to_bits(), f8::ALL[f8::ALL_LEN - 1].to_bits(),); + assert_eq!( + f8::NEG_INFINITY.next_down().to_bits(), + f8::NEG_INFINITY.to_bits(), + ); + assert_eq!( + f8::INFINITY.next_down().to_bits(), + f8::ALL[f8::ALL_LEN - 1].to_bits(), + ); assert_eq!(f8::INFINITY.next_up().to_bits(), f8::INFINITY.to_bits(),); assert_eq!(f8::NAN.next_up().to_bits(), f8::NAN.to_bits(),); assert_eq!(f8::NAN.next_down().to_bits(), f8::NAN.to_bits(),); @@ -321,7 +345,10 @@ mod tests { // Check across zero assert_eq!(f8::from_bits(0b1_0000_111).n_up(8).to_bits(), 0b0_0000_001); - assert_eq!(f8::from_bits(0b0_0000_111).n_down(8).to_bits(), 0b1_0000_001); + assert_eq!( + f8::from_bits(0b0_0000_111).n_down(8).to_bits(), + 0b1_0000_001 + ); } #[test] @@ -337,13 +364,25 @@ mod tests { #[test] fn test_n_up_down_inf_nan_zero() { assert_eq!(f8::NEG_INFINITY.n_up(1).to_bits(), f8::ALL[0].to_bits()); - assert_eq!(f8::NEG_INFINITY.n_up(239).to_bits(), f8::ALL[f8::ALL_LEN - 1].to_bits()); + assert_eq!( + f8::NEG_INFINITY.n_up(239).to_bits(), + f8::ALL[f8::ALL_LEN - 1].to_bits() + ); assert_eq!(f8::NEG_INFINITY.n_up(240).to_bits(), f8::INFINITY.to_bits()); - assert_eq!(f8::NEG_INFINITY.n_down(u8::MAX).to_bits(), f8::NEG_INFINITY.to_bits()); + assert_eq!( + f8::NEG_INFINITY.n_down(u8::MAX).to_bits(), + f8::NEG_INFINITY.to_bits() + ); - assert_eq!(f8::INFINITY.n_down(1).to_bits(), f8::ALL[f8::ALL_LEN - 1].to_bits()); + assert_eq!( + f8::INFINITY.n_down(1).to_bits(), + f8::ALL[f8::ALL_LEN - 1].to_bits() + ); assert_eq!(f8::INFINITY.n_down(239).to_bits(), f8::ALL[0].to_bits()); - assert_eq!(f8::INFINITY.n_down(240).to_bits(), f8::NEG_INFINITY.to_bits()); + assert_eq!( + f8::INFINITY.n_down(240).to_bits(), + f8::NEG_INFINITY.to_bits() + ); assert_eq!(f8::INFINITY.n_up(u8::MAX).to_bits(), f8::INFINITY.to_bits()); assert_eq!(f8::NAN.n_up(u8::MAX).to_bits(), f8::NAN.to_bits()); @@ -381,7 +420,11 @@ mod tests { assert_eq!(down, expected, "{i} {n} n_down({v:#010b})"); } else { // Overflow to -inf - assert_eq!(down, f8::NEG_INFINITY.to_bits(), "{i} {n} n_down({v:#010b})"); + assert_eq!( + down, + f8::NEG_INFINITY.to_bits(), + "{i} {n} n_down({v:#010b})" + ); } let mut up_exp_idx = i + n; @@ -438,13 +481,22 @@ mod tests { #[test] fn test_ulp_between_inf_nan_zero() { - assert_eq!(ulp_between(f8::NEG_INFINITY, f8::INFINITY).unwrap(), f8::ALL_LEN as u8); - assert_eq!(ulp_between(f8::INFINITY, f8::NEG_INFINITY).unwrap(), f8::ALL_LEN as u8); + assert_eq!( + ulp_between(f8::NEG_INFINITY, f8::INFINITY).unwrap(), + f8::ALL_LEN as u8 + ); + assert_eq!( + ulp_between(f8::INFINITY, f8::NEG_INFINITY).unwrap(), + f8::ALL_LEN as u8 + ); assert_eq!( ulp_between(f8::NEG_INFINITY, f8::ALL[f8::ALL_LEN - 1]).unwrap(), f8::ALL_LEN as u8 - 1 ); - assert_eq!(ulp_between(f8::INFINITY, f8::ALL[0]).unwrap(), f8::ALL_LEN as u8 - 1); + assert_eq!( + ulp_between(f8::INFINITY, f8::ALL[0]).unwrap(), + f8::ALL_LEN as u8 - 1 + ); assert_eq!(ulp_between(f8::ZERO, f8::NEG_ZERO).unwrap(), 0); assert_eq!(ulp_between(f8::NAN, f8::ZERO), None); @@ -469,7 +521,12 @@ mod tests { // of steps. let (ls, count) = logspace(f8::from_bits(0x0), f8::from_bits(0x3), 10); let ls: Vec<_> = ls.collect(); - let exp = [f8::from_bits(0x0), f8::from_bits(0x1), f8::from_bits(0x2), f8::from_bits(0x3)]; + let exp = [ + f8::from_bits(0x0), + f8::from_bits(0x1), + f8::from_bits(0x2), + f8::from_bits(0x3), + ]; assert_eq!(ls, exp); assert_eq!(ls.len(), usize::from(count)); } diff --git a/libm-test/src/op.rs b/libm-test/src/op.rs index 4f251f80d..bd17aad7d 100644 --- a/libm-test/src/op.rs +++ b/libm-test/src/op.rs @@ -16,7 +16,7 @@ use std::fmt; use std::panic::{RefUnwindSafe, UnwindSafe}; -pub use shared::{FloatTy, MathOpInfo, Ty, ALL_OPERATIONS}; +pub use shared::{ALL_OPERATIONS, FloatTy, MathOpInfo, Ty}; use crate::{CheckOutput, Float, TupleCall}; diff --git a/libm-test/src/run_cfg.rs b/libm-test/src/run_cfg.rs index b36164b00..3345a01d2 100644 --- a/libm-test/src/run_cfg.rs +++ b/libm-test/src/run_cfg.rs @@ -15,7 +15,9 @@ pub const EXTENSIVE_ITER_ENV: &str = "LIBM_EXTENSIVE_ITERATIONS"; /// The override value, if set by the above environment. static EXTENSIVE_ITER_OVERRIDE: LazyLock> = LazyLock::new(|| { - env::var(EXTENSIVE_ITER_ENV).map(|v| v.parse().expect("failed to parse iteration count")).ok() + env::var(EXTENSIVE_ITER_ENV) + .map(|v| v.parse().expect("failed to parse iteration count")) + .ok() }); /// Specific tests that need to have a reduced amount of iterations to complete in a reasonable @@ -115,7 +117,10 @@ static EXTENSIVE: LazyLock> = LazyLock::new(|| { let mut ret = Vec::new(); let append_ty_ops = |ret: &mut Vec<_>, fty: FloatTy| { - let iter = Identifier::ALL.iter().filter(move |id| id.math_op().float_ty == fty).copied(); + let iter = Identifier::ALL + .iter() + .filter(move |id| id.math_op().float_ty == fty) + .copied(); ret.extend(iter); }; @@ -276,7 +281,10 @@ pub fn iteration_count(ctx: &CheckCtx, argnum: usize) -> u64 { let seed_msg = match ctx.gen_kind { GeneratorKind::QuickSpaced | GeneratorKind::Extensive => String::new(), GeneratorKind::Random => { - format!(" using `{SEED_ENV}={}`", str::from_utf8(SEED.as_slice()).unwrap()) + format!( + " using `{SEED_ENV}={}`", + str::from_utf8(SEED.as_slice()).unwrap() + ) } GeneratorKind::EdgeCases | GeneratorKind::List => unimplemented!(), }; @@ -303,7 +311,10 @@ pub fn int_range(ctx: &CheckCtx, argnum: usize) -> RangeInclusive { return i32::MIN..=i32::MAX; } - assert_eq!(argnum, 0, "For `jn`/`yn`, only the first argument takes an integer"); + assert_eq!( + argnum, 0, + "For `jn`/`yn`, only the first argument takes an integer" + ); // The integer argument to `jn` is an iteration count. Limit this to ensure tests can be // completed in a reasonable amount of time. @@ -331,7 +342,11 @@ pub fn check_point_count(ctx: &CheckCtx) -> usize { "check_point_count is intended for edge case tests" ); let t_env = TestEnv::from_env(ctx); - if t_env.slow_platform || !cfg!(optimizations_enabled) { 4 } else { 10 } + if t_env.slow_platform || !cfg!(optimizations_enabled) { + 4 + } else { + 10 + } } /// When validating points of interest (e.g. asymptotes, inflection points, extremes), also check diff --git a/libm-test/src/test_traits.rs b/libm-test/src/test_traits.rs index c560dade8..dbb970161 100644 --- a/libm-test/src/test_traits.rs +++ b/libm-test/src/test_traits.rs @@ -328,7 +328,10 @@ where // Check when both are NaNs if actual.is_nan() && expected.is_nan() { if require_biteq && ctx.basis == CheckBasis::None { - ensure!(actual.to_bits() == expected.to_bits(), "mismatched NaN bitpatterns"); + ensure!( + actual.to_bits() == expected.to_bits(), + "mismatched NaN bitpatterns" + ); } // By default, NaNs have nothing special to check. return Ok(()); @@ -340,7 +343,10 @@ where // Make sure that the signs are the same before checing ULP to avoid wraparound let act_sig = actual.signum(); let exp_sig = expected.signum(); - ensure!(act_sig == exp_sig, "mismatched signs {act_sig:?} {exp_sig:?}"); + ensure!( + act_sig == exp_sig, + "mismatched signs {act_sig:?} {exp_sig:?}" + ); if actual.is_infinite() ^ expected.is_infinite() { bail!("mismatched infinities"); diff --git a/libm-test/tests/u256.rs b/libm-test/tests/u256.rs index 4444036d0..8cbb3ad22 100644 --- a/libm-test/tests/u256.rs +++ b/libm-test/tests/u256.rs @@ -40,7 +40,10 @@ fn from_bigint(bx: &mut BigInt) -> u256 { let mut bres = [0u128, 0]; bx.write_digits(&mut bres, Order::Lsf); bx.assign(0); - u256 { lo: bres[0], hi: bres[1] } + u256 { + lo: bres[0], + hi: bres[1], + } } fn check_one( @@ -142,6 +145,11 @@ fn mp_u256_widen_mul() { by.assign(y); let actual = x.widen_mul(y); bx *= &by; - check_one(|| format!("{x:#034x}"), || Some(format!("{y:#034x}")), actual, &mut bx); + check_one( + || format!("{x:#034x}"), + || Some(format!("{y:#034x}")), + actual, + &mut bx, + ); } } diff --git a/libm-test/tests/z_extensive/run.rs b/libm-test/tests/z_extensive/run.rs index b10c231d1..59c806ce7 100644 --- a/libm-test/tests/z_extensive/run.rs +++ b/libm-test/tests/z_extensive/run.rs @@ -28,8 +28,15 @@ pub fn run() { // With default parallelism, the CPU doesn't saturate. We don't need to be nice to // other processes, so do 1.5x to make sure we use all available resources. - let threads = std::thread::available_parallelism().map(Into::into).unwrap_or(0) * 3 / 2; - rayon::ThreadPoolBuilder::new().num_threads(threads).build_global().unwrap(); + let threads = std::thread::available_parallelism() + .map(Into::into) + .unwrap_or(0) + * 3 + / 2; + rayon::ThreadPoolBuilder::new() + .num_threads(threads) + .build_global() + .unwrap(); libtest_mimic::run(&args, tests).exit(); } @@ -134,7 +141,9 @@ where }); // Run the actual tests - let res = chunks.par_bridge().try_for_each_init(Op::new_mp, test_single_chunk); + let res = chunks + .par_bridge() + .try_for_each_init(Op::new_mp, test_single_chunk); let real_total = completed.load(Ordering::Relaxed); pb.complete(real_total); @@ -179,7 +188,12 @@ impl Progress { let pb = ProgressBar::new(total); pb.set_style(initial_style); - Self { pb, final_style, name_padded, is_tty } + Self { + pb, + final_style, + name_padded, + is_tty, + } } fn update(&self, completed: u64, input: impl fmt::Debug) { diff --git a/libm/configure.rs b/libm/configure.rs index 8b8ba9815..2a497c7b1 100644 --- a/libm/configure.rs +++ b/libm/configure.rs @@ -107,9 +107,15 @@ fn emit_cfg_shorthands(cfg: &Config) { /// Reemit config that we make use of for test logging. fn emit_cfg_env(cfg: &Config) { - println!("cargo:rustc-env=CFG_CARGO_FEATURES={:?}", cfg.cargo_features); + println!( + "cargo:rustc-env=CFG_CARGO_FEATURES={:?}", + cfg.cargo_features + ); println!("cargo:rustc-env=CFG_OPT_LEVEL={}", cfg.opt_level); - println!("cargo:rustc-env=CFG_TARGET_FEATURES={:?}", cfg.target_features); + println!( + "cargo:rustc-env=CFG_TARGET_FEATURES={:?}", + cfg.target_features + ); } /// Configure whether or not `f16` and `f128` support should be enabled. diff --git a/libm/src/lib.rs b/libm/src/lib.rs index 7e56bd079..7df84fe18 100644 --- a/libm/src/lib.rs +++ b/libm/src/lib.rs @@ -2,7 +2,10 @@ #![no_std] #![cfg_attr(intrinsics_enabled, allow(internal_features))] #![cfg_attr(intrinsics_enabled, feature(core_intrinsics))] -#![cfg_attr(all(intrinsics_enabled, target_family = "wasm"), feature(wasm_numeric_instr))] +#![cfg_attr( + all(intrinsics_enabled, target_family = "wasm"), + feature(wasm_numeric_instr) +)] #![cfg_attr(f128_enabled, feature(f128))] #![cfg_attr(f16_enabled, feature(f16))] #![allow(clippy::assign_op_pattern)] diff --git a/libm/src/math/atanf.rs b/libm/src/math/atanf.rs index eb3d401cd..da8daa41a 100644 --- a/libm/src/math/atanf.rs +++ b/libm/src/math/atanf.rs @@ -29,8 +29,13 @@ const ATAN_LO: [f32; 4] = [ 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */ ]; -const A_T: [f32; 5] = - [3.3333328366e-01, -1.9999158382e-01, 1.4253635705e-01, -1.0648017377e-01, 6.1687607318e-02]; +const A_T: [f32; 5] = [ + 3.3333328366e-01, + -1.9999158382e-01, + 1.4253635705e-01, + -1.0648017377e-01, + 6.1687607318e-02, +]; /// Arctangent (f32) /// diff --git a/libm/src/math/cbrt.rs b/libm/src/math/cbrt.rs index 9d3311cd6..cf56f7a97 100644 --- a/libm/src/math/cbrt.rs +++ b/libm/src/math/cbrt.rs @@ -171,7 +171,11 @@ pub fn cbrt_round(x: f64, round: Round) -> FpResult { for (a, b) in wlist { if azz == a { - let tmp = if round as u64 + sign == 2 { hf64!("0x1p-52") } else { 0.0 }; + let tmp = if round as u64 + sign == 2 { + hf64!("0x1p-52") + } else { + 0.0 + }; y1 = (b + tmp).copysign(zz); } } diff --git a/libm/src/math/erf.rs b/libm/src/math/erf.rs index 1b634abec..5d82228a0 100644 --- a/libm/src/math/erf.rs +++ b/libm/src/math/erf.rs @@ -306,5 +306,9 @@ pub fn erfc(x: f64) -> f64 { } let x1p_1022 = f64::from_bits(0x0010000000000000); - if sign != 0 { 2.0 - x1p_1022 } else { x1p_1022 * x1p_1022 } + if sign != 0 { + 2.0 - x1p_1022 + } else { + x1p_1022 * x1p_1022 + } } diff --git a/libm/src/math/erff.rs b/libm/src/math/erff.rs index 2e41183bf..fe15f0108 100644 --- a/libm/src/math/erff.rs +++ b/libm/src/math/erff.rs @@ -218,5 +218,9 @@ pub fn erfcf(x: f32) -> f32 { } let x1p_120 = f32::from_bits(0x03800000); - if sign != 0 { 2.0 - x1p_120 } else { x1p_120 * x1p_120 } + if sign != 0 { + 2.0 - x1p_120 + } else { + x1p_120 * x1p_120 + } } diff --git a/libm/src/math/exp10f.rs b/libm/src/math/exp10f.rs index 0520a41f2..303045b33 100644 --- a/libm/src/math/exp10f.rs +++ b/libm/src/math/exp10f.rs @@ -2,8 +2,9 @@ use super::{exp2, exp2f, modff}; const LN10_F32: f32 = 3.32192809488736234787031942948939; const LN10_F64: f64 = 3.32192809488736234787031942948939; -const P10: &[f32] = - &[1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7]; +const P10: &[f32] = &[ + 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, +]; /// Calculates 10 raised to the power of `x` (f32). #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] diff --git a/libm/src/math/expm1f.rs b/libm/src/math/expm1f.rs index 12c6f532b..63dc86e37 100644 --- a/libm/src/math/expm1f.rs +++ b/libm/src/math/expm1f.rs @@ -126,5 +126,9 @@ pub fn expm1f(mut x: f32) -> f32 { return y - 1.; } let uf = f32::from_bits(((0x7f - k) << 23) as u32); /* 2^-k */ - if k < 23 { (x - e + (1. - uf)) * twopk } else { (x - (e + uf) + 1.) * twopk } + if k < 23 { + (x - e + (1. - uf)) * twopk + } else { + (x - (e + uf) + 1.) * twopk + } } diff --git a/libm/src/math/fma.rs b/libm/src/math/fma.rs index e0b3347ac..8856e63f5 100644 --- a/libm/src/math/fma.rs +++ b/libm/src/math/fma.rs @@ -387,11 +387,17 @@ mod tests { #[test] fn fma_sbb() { - assert_eq!(fma(-(1.0 - f64::EPSILON), f64::MIN, f64::MIN), -3991680619069439e277); + assert_eq!( + fma(-(1.0 - f64::EPSILON), f64::MIN, f64::MIN), + -3991680619069439e277 + ); } #[test] fn fma_underflow() { - assert_eq!(fma(1.1102230246251565e-16, -9.812526705433188e-305, 1.0894e-320), 0.0,); + assert_eq!( + fma(1.1102230246251565e-16, -9.812526705433188e-305, 1.0894e-320), + 0.0, + ); } } diff --git a/libm/src/math/fma_wide.rs b/libm/src/math/fma_wide.rs index 08b78b022..f268c2f14 100644 --- a/libm/src/math/fma_wide.rs +++ b/libm/src/math/fma_wide.rs @@ -75,11 +75,18 @@ where } } - return FpResult { val: result.narrow(), status }; + return FpResult { + val: result.narrow(), + status, + }; } let neg = ui >> (B::BITS - 1) != IntTy::::ZERO; - let err = if neg == (zb > xy) { xy - result + zb } else { zb - result + xy }; + let err = if neg == (zb > xy) { + xy - result + zb + } else { + zb - result + xy + }; if neg == (err < B::ZERO) { ui += one; } else { diff --git a/libm/src/math/generic/ceil.rs b/libm/src/math/generic/ceil.rs index 5c5bb4763..499770c0d 100644 --- a/libm/src/math/generic/ceil.rs +++ b/libm/src/math/generic/ceil.rs @@ -75,7 +75,14 @@ mod tests { /// Test against https://en.cppreference.com/w/cpp/numeric/math/ceil fn spec_test(cases: &[(F, F, Status)]) { - let roundtrip = [F::ZERO, F::ONE, F::NEG_ONE, F::NEG_ZERO, F::INFINITY, F::NEG_INFINITY]; + let roundtrip = [ + F::ZERO, + F::ONE, + F::NEG_ONE, + F::NEG_ZERO, + F::INFINITY, + F::NEG_INFINITY, + ]; for x in roundtrip { let FpResult { val, status } = ceil_status(x); diff --git a/libm/src/math/generic/floor.rs b/libm/src/math/generic/floor.rs index 243804625..58d1ee4c2 100644 --- a/libm/src/math/generic/floor.rs +++ b/libm/src/math/generic/floor.rs @@ -75,7 +75,14 @@ mod tests { /// Test against https://en.cppreference.com/w/cpp/numeric/math/floor fn spec_test(cases: &[(F, F, Status)]) { - let roundtrip = [F::ZERO, F::ONE, F::NEG_ONE, F::NEG_ZERO, F::INFINITY, F::NEG_INFINITY]; + let roundtrip = [ + F::ZERO, + F::ONE, + F::NEG_ONE, + F::NEG_ZERO, + F::INFINITY, + F::NEG_INFINITY, + ]; for x in roundtrip { let FpResult { val, status } = floor_status(x); diff --git a/libm/src/math/generic/rint.rs b/libm/src/math/generic/rint.rs index 9cdeb1185..7bf38e323 100644 --- a/libm/src/math/generic/rint.rs +++ b/libm/src/math/generic/rint.rs @@ -15,7 +15,11 @@ pub fn rint_round(x: F, _round: Round) -> FpResult { // On i386 `force_eval!` must be used to force rounding via storage to memory. Otherwise, // the excess precission from x87 would cause an incorrect final result. let force = |x| { - if cfg!(x86_no_sse) && (F::BITS == 32 || F::BITS == 64) { force_eval!(x) } else { x } + if cfg!(x86_no_sse) && (F::BITS == 32 || F::BITS == 64) { + force_eval!(x) + } else { + x + } }; let res = if e >= F::EXP_BIAS + F::SIG_BITS { @@ -47,7 +51,14 @@ mod tests { use crate::support::{Hexf, Status}; fn spec_test(cases: &[(F, F, Status)]) { - let roundtrip = [F::ZERO, F::ONE, F::NEG_ONE, F::NEG_ZERO, F::INFINITY, F::NEG_INFINITY]; + let roundtrip = [ + F::ZERO, + F::ONE, + F::NEG_ONE, + F::NEG_ZERO, + F::INFINITY, + F::NEG_INFINITY, + ]; for x in roundtrip { let FpResult { val, status } = rint_round(x, Round::Nearest); diff --git a/libm/src/math/generic/sqrt.rs b/libm/src/math/generic/sqrt.rs index ec9ff22df..c52560bdb 100644 --- a/libm/src/math/generic/sqrt.rs +++ b/libm/src/math/generic/sqrt.rs @@ -521,7 +521,10 @@ mod tests { f128::from_bits(0x400c3880000000000000000000000000), 0x40059000000000000000000000000000_u128, ), - (f128::from_bits(0x0000000f), 0x1fc9efbdeb14f4ed9b17ae807907e1e9_u128), + ( + f128::from_bits(0x0000000f), + 0x1fc9efbdeb14f4ed9b17ae807907e1e9_u128, + ), (f128::INFINITY, f128::INFINITY.to_bits()), ]; diff --git a/libm/src/math/generic/trunc.rs b/libm/src/math/generic/trunc.rs index 25414ecf4..29a28f47b 100644 --- a/libm/src/math/generic/trunc.rs +++ b/libm/src/math/generic/trunc.rs @@ -36,7 +36,11 @@ pub fn trunc_status(x: F) -> FpResult { // C5: Otherwise the result is inexact and we will truncate. Raise `FE_INEXACT`, mask the // result, and return. - let status = if xi & F::SIG_MASK == F::Int::ZERO { Status::OK } else { Status::INEXACT }; + let status = if xi & F::SIG_MASK == F::Int::ZERO { + Status::OK + } else { + Status::INEXACT + }; xi &= mask; FpResult::new(F::from_bits(xi), status) } @@ -47,7 +51,14 @@ mod tests { use crate::support::Hexf; fn spec_test(cases: &[(F, F, Status)]) { - let roundtrip = [F::ZERO, F::ONE, F::NEG_ONE, F::NEG_ZERO, F::INFINITY, F::NEG_INFINITY]; + let roundtrip = [ + F::ZERO, + F::ONE, + F::NEG_ONE, + F::NEG_ZERO, + F::INFINITY, + F::NEG_INFINITY, + ]; for x in roundtrip { let FpResult { val, status } = trunc_status(x); diff --git a/libm/src/math/ilogb.rs b/libm/src/math/ilogb.rs index ccc4914be..5b41f7b1d 100644 --- a/libm/src/math/ilogb.rs +++ b/libm/src/math/ilogb.rs @@ -21,7 +21,11 @@ pub fn ilogb(x: f64) -> i32 { e } else if e == 0x7ff { force_eval!(0.0 / 0.0); - if (i << 12) != 0 { FP_ILOGBNAN } else { i32::MAX } + if (i << 12) != 0 { + FP_ILOGBNAN + } else { + i32::MAX + } } else { e - 0x3ff } diff --git a/libm/src/math/k_sin.rs b/libm/src/math/k_sin.rs index 42441455f..9dd96c944 100644 --- a/libm/src/math/k_sin.rs +++ b/libm/src/math/k_sin.rs @@ -49,5 +49,9 @@ pub(crate) fn k_sin(x: f64, y: f64, iy: i32) -> f64 { let w = z * z; let r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6); let v = z * x; - if iy == 0 { x + v * (S1 + z * r) } else { x - ((z * (0.5 * y - v * r) - y) - v * S1) } + if iy == 0 { + x + v * (S1 + z * r) + } else { + x - ((z * (0.5 * y - v * r) - y) - v * S1) + } } diff --git a/libm/src/math/log1p.rs b/libm/src/math/log1p.rs index b7f3fb09e..65142c0d6 100644 --- a/libm/src/math/log1p.rs +++ b/libm/src/math/log1p.rs @@ -118,7 +118,11 @@ pub fn log1p(x: f64) -> f64 { k = (hu >> 20) as i32 - 0x3ff; /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ if k < 54 { - c = if k >= 2 { 1. - (f64::from_bits(ui) - x) } else { x - (f64::from_bits(ui) - 1.) }; + c = if k >= 2 { + 1. - (f64::from_bits(ui) - x) + } else { + x - (f64::from_bits(ui) - 1.) + }; c /= f64::from_bits(ui); } else { c = 0.; diff --git a/libm/src/math/log1pf.rs b/libm/src/math/log1pf.rs index bba5b8a2f..23978e61c 100644 --- a/libm/src/math/log1pf.rs +++ b/libm/src/math/log1pf.rs @@ -73,7 +73,11 @@ pub fn log1pf(x: f32) -> f32 { k = (iu >> 23) as i32 - 0x7f; /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */ if k < 25 { - c = if k >= 2 { 1. - (f32::from_bits(ui) - x) } else { x - (f32::from_bits(ui) - 1.) }; + c = if k >= 2 { + 1. - (f32::from_bits(ui) - x) + } else { + x - (f32::from_bits(ui) - 1.) + }; c /= f32::from_bits(ui); } else { c = 0.; diff --git a/libm/src/math/pow.rs b/libm/src/math/pow.rs index 80b2a2499..7e7d049b9 100644 --- a/libm/src/math/pow.rs +++ b/libm/src/math/pow.rs @@ -239,10 +239,18 @@ pub fn pow(x: f64, y: f64) -> f64 { /* over/underflow if x is not close to one */ if ix < 0x3fefffff { - return if hy < 0 { s * HUGE * HUGE } else { s * TINY * TINY }; + return if hy < 0 { + s * HUGE * HUGE + } else { + s * TINY * TINY + }; } if ix > 0x3ff00000 { - return if hy > 0 { s * HUGE * HUGE } else { s * TINY * TINY }; + return if hy > 0 { + s * HUGE * HUGE + } else { + s * TINY * TINY + }; } /* now |1-x| is TINY <= 2**-20, suffice to compute @@ -439,7 +447,11 @@ mod tests { fn pow_test(base: f64, exponent: f64, expected: f64) { let res = pow(base, exponent); assert!( - if expected.is_nan() { res.is_nan() } else { pow(base, exponent) == expected }, + if expected.is_nan() { + res.is_nan() + } else { + pow(base, exponent) == expected + }, "{} ** {} was {} instead of {}", base, exponent, @@ -449,11 +461,13 @@ mod tests { } fn test_sets_as_base(sets: &[&[f64]], exponent: f64, expected: f64) { - sets.iter().for_each(|s| s.iter().for_each(|val| pow_test(*val, exponent, expected))); + sets.iter() + .for_each(|s| s.iter().for_each(|val| pow_test(*val, exponent, expected))); } fn test_sets_as_exponent(base: f64, sets: &[&[f64]], expected: f64) { - sets.iter().for_each(|s| s.iter().for_each(|val| pow_test(base, *val, expected))); + sets.iter() + .for_each(|s| s.iter().for_each(|val| pow_test(base, *val, expected))); } fn test_sets(sets: &[&[f64]], computed: &dyn Fn(f64) -> f64, expected: &dyn Fn(f64) -> f64) { @@ -467,7 +481,11 @@ mod tests { #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))] let res = force_eval!(res); assert!( - if exp.is_nan() { res.is_nan() } else { exp == res }, + if exp.is_nan() { + res.is_nan() + } else { + exp == res + }, "test for {} was {} instead of {}", val, res, @@ -515,7 +533,9 @@ mod tests { // (-Infinity ^ anything but odd ints should be == -0 ^ (-anything)) // We can lump in pos/neg odd ints here because they don't seem to // cause panics (div by zero) in release mode (I think). - test_sets(ALL, &|v: f64| pow(f64::NEG_INFINITY, v), &|v: f64| pow(-0.0, -v)); + test_sets(ALL, &|v: f64| pow(f64::NEG_INFINITY, v), &|v: f64| { + pow(-0.0, -v) + }); } #[test] @@ -582,11 +602,15 @@ mod tests { // Factoring -1 out: // (negative anything ^ integer should be (-1 ^ integer) * (positive anything ^ integer)) - [POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS].iter().for_each(|int_set| { - int_set.iter().for_each(|int| { - test_sets(ALL, &|v: f64| pow(-v, *int), &|v: f64| pow(-1.0, *int) * pow(v, *int)); - }) - }); + [POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS] + .iter() + .for_each(|int_set| { + int_set.iter().for_each(|int| { + test_sets(ALL, &|v: f64| pow(-v, *int), &|v: f64| { + pow(-1.0, *int) * pow(v, *int) + }); + }) + }); // Negative base (imaginary results): // (-anything except 0 and Infinity ^ non-integer should be NAN) diff --git a/libm/src/math/powf.rs b/libm/src/math/powf.rs index 839c6c23d..11c7a7cbd 100644 --- a/libm/src/math/powf.rs +++ b/libm/src/math/powf.rs @@ -182,11 +182,19 @@ pub fn powf(x: f32, y: f32) -> f32 { /* if |y| > 2**27 */ /* over/underflow if x is not close to one */ if ix < 0x3f7ffff8 { - return if hy < 0 { sn * HUGE * HUGE } else { sn * TINY * TINY }; + return if hy < 0 { + sn * HUGE * HUGE + } else { + sn * TINY * TINY + }; } if ix > 0x3f800007 { - return if hy > 0 { sn * HUGE * HUGE } else { sn * TINY * TINY }; + return if hy > 0 { + sn * HUGE * HUGE + } else { + sn * TINY * TINY + }; } /* now |1-x| is TINY <= 2**-20, suffice to compute diff --git a/libm/src/math/rem_pio2.rs b/libm/src/math/rem_pio2.rs index 917e90819..d677fd9dc 100644 --- a/libm/src/math/rem_pio2.rs +++ b/libm/src/math/rem_pio2.rs @@ -199,16 +199,28 @@ mod tests { fn test_near_pi() { let arg = 3.141592025756836; let arg = force_eval!(arg); - assert_eq!(rem_pio2(arg), (2, -6.278329573009626e-7, -2.1125998133974653e-23)); + assert_eq!( + rem_pio2(arg), + (2, -6.278329573009626e-7, -2.1125998133974653e-23) + ); let arg = 3.141592033207416; let arg = force_eval!(arg); - assert_eq!(rem_pio2(arg), (2, -6.20382377148128e-7, -2.1125998133974653e-23)); + assert_eq!( + rem_pio2(arg), + (2, -6.20382377148128e-7, -2.1125998133974653e-23) + ); let arg = 3.141592144966125; let arg = force_eval!(arg); - assert_eq!(rem_pio2(arg), (2, -5.086236681942706e-7, -2.1125998133974653e-23)); + assert_eq!( + rem_pio2(arg), + (2, -5.086236681942706e-7, -2.1125998133974653e-23) + ); let arg = 3.141592979431152; let arg = force_eval!(arg); - assert_eq!(rem_pio2(arg), (2, 3.2584135866119817e-7, -2.1125998133974653e-23)); + assert_eq!( + rem_pio2(arg), + (2, 3.2584135866119817e-7, -2.1125998133974653e-23) + ); } #[test] diff --git a/libm/src/math/sinf.rs b/libm/src/math/sinf.rs index b8fae2c98..709b63fcf 100644 --- a/libm/src/math/sinf.rs +++ b/libm/src/math/sinf.rs @@ -42,7 +42,11 @@ pub fn sinf(x: f32) -> f32 { if ix < 0x39800000 { /* |x| < 2**-12 */ /* raise inexact if x!=0 and underflow if subnormal */ - force_eval!(if ix < 0x00800000 { x / x1p120 } else { x + x1p120 }); + force_eval!(if ix < 0x00800000 { + x / x1p120 + } else { + x + x1p120 + }); return x; } return k_sinf(x64); @@ -57,7 +61,11 @@ pub fn sinf(x: f32) -> f32 { return k_cosf(x64 - S1_PIO2); } } - return k_sinf(if sign { -(x64 + S2_PIO2) } else { -(x64 - S2_PIO2) }); + return k_sinf(if sign { + -(x64 + S2_PIO2) + } else { + -(x64 - S2_PIO2) + }); } if ix <= 0x40e231d5 { /* |x| ~<= 9*pi/4 */ diff --git a/libm/src/math/support/big.rs b/libm/src/math/support/big.rs index eae08238e..f24c063cd 100644 --- a/libm/src/math/support/big.rs +++ b/libm/src/math/support/big.rs @@ -19,11 +19,17 @@ pub struct u256 { impl u256 { #[cfg(any(test, feature = "unstable-public-internals"))] - pub const MAX: Self = Self { lo: u128::MAX, hi: u128::MAX }; + pub const MAX: Self = Self { + lo: u128::MAX, + hi: u128::MAX, + }; /// Reinterpret as a signed integer pub fn signed(self) -> i256 { - i256 { lo: self.lo, hi: self.hi } + i256 { + lo: self.lo, + hi: self.hi, + } } } @@ -39,7 +45,10 @@ impl i256 { /// Reinterpret as an unsigned integer #[cfg(any(test, feature = "unstable-public-internals"))] pub fn unsigned(self) -> u256 { - u256 { lo: self.lo, hi: self.hi } + u256 { + lo: self.lo, + hi: self.hi, + } } } @@ -53,7 +62,10 @@ impl MinInt for u256 { const ZERO: Self = Self { lo: 0, hi: 0 }; const ONE: Self = Self { lo: 1, hi: 0 }; const MIN: Self = Self { lo: 0, hi: 0 }; - const MAX: Self = Self { lo: u128::MAX, hi: u128::MAX }; + const MAX: Self = Self { + lo: u128::MAX, + hi: u128::MAX, + }; } impl MinInt for i256 { @@ -65,8 +77,14 @@ impl MinInt for i256 { const BITS: u32 = 256; const ZERO: Self = Self { lo: 0, hi: 0 }; const ONE: Self = Self { lo: 1, hi: 0 }; - const MIN: Self = Self { lo: 0, hi: 1 << 127 }; - const MAX: Self = Self { lo: u128::MAX, hi: u128::MAX << 1 }; + const MIN: Self = Self { + lo: 0, + hi: 1 << 127, + }; + const MAX: Self = Self { + lo: u128::MAX, + hi: u128::MAX << 1, + }; } macro_rules! impl_common { diff --git a/libm/src/math/support/big/tests.rs b/libm/src/math/support/big/tests.rs index 2c71191ba..d2010f021 100644 --- a/libm/src/math/support/big/tests.rs +++ b/libm/src/math/support/big/tests.rs @@ -13,23 +13,62 @@ fn hexu(v: u256) -> String { #[test] fn widen_u128() { - assert_eq!(u128::MAX.widen(), u256 { lo: u128::MAX, hi: 0 }); - assert_eq!(LOHI_SPLIT.widen(), u256 { lo: LOHI_SPLIT, hi: 0 }); + assert_eq!( + u128::MAX.widen(), + u256 { + lo: u128::MAX, + hi: 0 + } + ); + assert_eq!( + LOHI_SPLIT.widen(), + u256 { + lo: LOHI_SPLIT, + hi: 0 + } + ); } #[test] fn widen_i128() { assert_eq!((-1i128).widen(), u256::MAX.signed()); - assert_eq!((LOHI_SPLIT as i128).widen(), i256 { lo: LOHI_SPLIT, hi: u128::MAX }); + assert_eq!( + (LOHI_SPLIT as i128).widen(), + i256 { + lo: LOHI_SPLIT, + hi: u128::MAX + } + ); assert_eq!((-1i128).zero_widen().unsigned(), (u128::MAX).widen()); } #[test] fn widen_mul_u128() { let tests = [ - (u128::MAX / 2, 2_u128, u256 { lo: u128::MAX - 1, hi: 0 }), - (u128::MAX, 2_u128, u256 { lo: u128::MAX - 1, hi: 1 }), - (u128::MAX, u128::MAX, u256 { lo: 1, hi: u128::MAX - 1 }), + ( + u128::MAX / 2, + 2_u128, + u256 { + lo: u128::MAX - 1, + hi: 0, + }, + ), + ( + u128::MAX, + 2_u128, + u256 { + lo: u128::MAX - 1, + hi: 1, + }, + ), + ( + u128::MAX, + u128::MAX, + u256 { + lo: 1, + hi: u128::MAX - 1, + }, + ), (0, 0, u256::ZERO), (1234u128, 0, u256::ZERO), (0, 1234, u256::ZERO), @@ -68,7 +107,13 @@ fn not_u256() { #[test] fn shr_u256() { - let only_low = [1, u16::MAX.into(), u32::MAX.into(), u64::MAX.into(), u128::MAX]; + let only_low = [ + 1, + u16::MAX.into(), + u32::MAX.into(), + u64::MAX.into(), + u128::MAX, + ]; let mut has_errors = false; let mut add_error = |a, b, expected, actual| { @@ -99,23 +144,106 @@ fn shr_u256() { } let check = [ - (u256::MAX, 1, u256 { lo: u128::MAX, hi: u128::MAX >> 1 }), - (u256::MAX, 5, u256 { lo: u128::MAX, hi: u128::MAX >> 5 }), - (u256::MAX, 63, u256 { lo: u128::MAX, hi: u64::MAX as u128 | (1 << 64) }), - (u256::MAX, 64, u256 { lo: u128::MAX, hi: u64::MAX as u128 }), - (u256::MAX, 65, u256 { lo: u128::MAX, hi: (u64::MAX >> 1) as u128 }), - (u256::MAX, 127, u256 { lo: u128::MAX, hi: 1 }), - (u256::MAX, 128, u256 { lo: u128::MAX, hi: 0 }), - (u256::MAX, 129, u256 { lo: u128::MAX >> 1, hi: 0 }), - (u256::MAX, 191, u256 { lo: u64::MAX as u128 | 1 << 64, hi: 0 }), - (u256::MAX, 192, u256 { lo: u64::MAX as u128, hi: 0 }), - (u256::MAX, 193, u256 { lo: u64::MAX as u128 >> 1, hi: 0 }), + ( + u256::MAX, + 1, + u256 { + lo: u128::MAX, + hi: u128::MAX >> 1, + }, + ), + ( + u256::MAX, + 5, + u256 { + lo: u128::MAX, + hi: u128::MAX >> 5, + }, + ), + ( + u256::MAX, + 63, + u256 { + lo: u128::MAX, + hi: u64::MAX as u128 | (1 << 64), + }, + ), + ( + u256::MAX, + 64, + u256 { + lo: u128::MAX, + hi: u64::MAX as u128, + }, + ), + ( + u256::MAX, + 65, + u256 { + lo: u128::MAX, + hi: (u64::MAX >> 1) as u128, + }, + ), + ( + u256::MAX, + 127, + u256 { + lo: u128::MAX, + hi: 1, + }, + ), + ( + u256::MAX, + 128, + u256 { + lo: u128::MAX, + hi: 0, + }, + ), + ( + u256::MAX, + 129, + u256 { + lo: u128::MAX >> 1, + hi: 0, + }, + ), + ( + u256::MAX, + 191, + u256 { + lo: u64::MAX as u128 | 1 << 64, + hi: 0, + }, + ), + ( + u256::MAX, + 192, + u256 { + lo: u64::MAX as u128, + hi: 0, + }, + ), + ( + u256::MAX, + 193, + u256 { + lo: u64::MAX as u128 >> 1, + hi: 0, + }, + ), (u256::MAX, 254, u256 { lo: 0b11, hi: 0 }), (u256::MAX, 255, u256 { lo: 1, hi: 0 }), ( - u256 { hi: LOHI_SPLIT, lo: 0 }, + u256 { + hi: LOHI_SPLIT, + lo: 0, + }, 64, - u256 { lo: 0xffffffffffffffff0000000000000000, hi: 0xaaaaaaaaaaaaaaaa }, + u256 { + lo: 0xffffffffffffffff0000000000000000, + hi: 0xaaaaaaaaaaaaaaaa, + }, ), ]; diff --git a/libm/src/math/support/env.rs b/libm/src/math/support/env.rs index 796309372..53ae32f65 100644 --- a/libm/src/math/support/env.rs +++ b/libm/src/math/support/env.rs @@ -25,7 +25,10 @@ impl FpResult { /// Return `val` with `Status::OK`. pub fn ok(val: T) -> Self { - Self { val, status: Status::OK } + Self { + val, + status: Status::OK, + } } } diff --git a/libm/src/math/support/float_traits.rs b/libm/src/math/support/float_traits.rs index fac104832..8094a7b84 100644 --- a/libm/src/math/support/float_traits.rs +++ b/libm/src/math/support/float_traits.rs @@ -105,7 +105,11 @@ pub trait Float: /// if `NaN` should not be treated separately. #[allow(dead_code)] fn eq_repr(self, rhs: Self) -> bool { - if self.is_nan() && rhs.is_nan() { true } else { self.biteq(rhs) } + if self.is_nan() && rhs.is_nan() { + true + } else { + self.biteq(rhs) + } } /// Returns true if the value is NaN. @@ -149,7 +153,11 @@ pub trait Float: /// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position. fn from_parts(negative: bool, exponent: u32, significand: Self::Int) -> Self { - let sign = if negative { Self::Int::ONE } else { Self::Int::ZERO }; + let sign = if negative { + Self::Int::ONE + } else { + Self::Int::ZERO + }; Self::from_bits( (sign << (Self::BITS - 1)) | (Self::Int::cast_from(exponent & Self::EXP_SAT) << Self::SIG_BITS) @@ -173,7 +181,11 @@ pub trait Float: /// Returns a number that represents the sign of self. #[allow(dead_code)] fn signum(self) -> Self { - if self.is_nan() { self } else { Self::ONE.copysign(self) } + if self.is_nan() { + self + } else { + Self::ONE.copysign(self) + } } } @@ -273,18 +285,61 @@ macro_rules! float_impl { } fn normalize(significand: Self::Int) -> (i32, Self::Int) { let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS); - (1i32.wrapping_sub(shift as i32), significand << shift as Self::Int) + ( + 1i32.wrapping_sub(shift as i32), + significand << shift as Self::Int, + ) } } }; } #[cfg(f16_enabled)] -float_impl!(f16, u16, i16, 16, 10, f16::from_bits, f16::to_bits, fmaf16, fmaf16); -float_impl!(f32, u32, i32, 32, 23, f32_from_bits, f32_to_bits, fmaf, fmaf32); -float_impl!(f64, u64, i64, 64, 52, f64_from_bits, f64_to_bits, fma, fmaf64); +float_impl!( + f16, + u16, + i16, + 16, + 10, + f16::from_bits, + f16::to_bits, + fmaf16, + fmaf16 +); +float_impl!( + f32, + u32, + i32, + 32, + 23, + f32_from_bits, + f32_to_bits, + fmaf, + fmaf32 +); +float_impl!( + f64, + u64, + i64, + 64, + 52, + f64_from_bits, + f64_to_bits, + fma, + fmaf64 +); #[cfg(f128_enabled)] -float_impl!(f128, u128, i128, 128, 112, f128::from_bits, f128::to_bits, fmaf128, fmaf128); +float_impl!( + f128, + u128, + i128, + 128, + 112, + f128::from_bits, + f128::to_bits, + fmaf128, + fmaf128 +); /* FIXME(msrv): vendor some things that are not const stable at our MSRV */ @@ -424,7 +479,10 @@ mod tests { // `from_parts` assert_biteq!(f32::from_parts(true, f32::EXP_BIAS, 0), -1.0f32); - assert_biteq!(f32::from_parts(false, 10 + f32::EXP_BIAS, 0), hf32!("0x1p10")); + assert_biteq!( + f32::from_parts(false, 10 + f32::EXP_BIAS, 0), + hf32!("0x1p10") + ); assert_biteq!(f32::from_parts(false, 0, 1), f32::from_bits(0x1)); } @@ -451,7 +509,10 @@ mod tests { // `from_parts` assert_biteq!(f64::from_parts(true, f64::EXP_BIAS, 0), -1.0f64); - assert_biteq!(f64::from_parts(false, 10 + f64::EXP_BIAS, 0), hf64!("0x1p10")); + assert_biteq!( + f64::from_parts(false, 10 + f64::EXP_BIAS, 0), + hf64!("0x1p10") + ); assert_biteq!(f64::from_parts(false, 0, 1), f64::from_bits(0x1)); } diff --git a/libm/src/math/support/hex_float.rs b/libm/src/math/support/hex_float.rs index 819e2f56e..85569d98a 100644 --- a/libm/src/math/support/hex_float.rs +++ b/libm/src/math/support/hex_float.rs @@ -234,7 +234,9 @@ const fn parse_hex(mut b: &[u8]) -> Result { match c { b'.' => { if seen_point { - return Err(HexFloatParseError("unexpected '.' parsing fractional digits")); + return Err(HexFloatParseError( + "unexpected '.' parsing fractional digits", + )); } seen_point = true; continue; @@ -294,7 +296,9 @@ const fn parse_hex(mut b: &[u8]) -> Result { } if !some_digits { - return Err(HexFloatParseError("at least one exponent digit is required")); + return Err(HexFloatParseError( + "at least one exponent digit is required", + )); }; { @@ -542,7 +546,11 @@ mod parse_tests { for k in -149..=127 { let s = format!("0x1p{k}"); let x = hf32(&s); - let y = if k < 0 { 0.5f32.powi(-k) } else { 2.0f32.powi(k) }; + let y = if k < 0 { + 0.5f32.powi(-k) + } else { + 2.0f32.powi(k) + }; assert_eq!(x, y); } @@ -613,9 +621,14 @@ mod parse_tests { fn rounding_extreme_underflow() { for k in 1..1000 { let s = format!("0x1p{}", -149 - k); - let Ok((bits, status)) = parse_any(&s, 32, 23, Round::Nearest) else { unreachable!() }; + let Ok((bits, status)) = parse_any(&s, 32, 23, Round::Nearest) else { + unreachable!() + }; assert_eq!(bits, 0, "{s} should round to zero, got bits={bits}"); - assert!(status.underflow(), "should indicate underflow when parsing {s}"); + assert!( + status.underflow(), + "should indicate underflow when parsing {s}" + ); assert!(status.inexact(), "should indicate inexact when parsing {s}"); } } @@ -623,11 +636,15 @@ mod parse_tests { fn long_tail() { for k in 1..1000 { let s = format!("0x1.{}p0", "0".repeat(k)); - let Ok(bits) = parse_hex_exact(&s, 32, 23) else { panic!("parsing {s} failed") }; + let Ok(bits) = parse_hex_exact(&s, 32, 23) else { + panic!("parsing {s} failed") + }; assert_eq!(f32::from_bits(bits as u32), 1.0); let s = format!("0x1.{}1p0", "0".repeat(k)); - let Ok((bits, status)) = parse_any(&s, 32, 23, Round::Nearest) else { unreachable!() }; + let Ok((bits, status)) = parse_any(&s, 32, 23, Round::Nearest) else { + unreachable!() + }; if status.inexact() { assert!(1.0 == f32::from_bits(bits as u32)); } else { @@ -839,7 +856,10 @@ mod parse_tests { assert_eq!(hf32!("0x1.ffep+8").to_bits(), 0x43fff000_u32); assert_eq!(hf64!("0x1.ffep+8").to_bits(), 0x407ffe0000000000_u64); #[cfg(f128_enabled)] - assert_eq!(hf128!("0x1.ffep+8").to_bits(), 0x4007ffe0000000000000000000000000_u128); + assert_eq!( + hf128!("0x1.ffep+8").to_bits(), + 0x4007ffe0000000000000000000000000_u128 + ); } } @@ -1143,8 +1163,14 @@ mod print_tests { #[cfg(f128_enabled)] { - assert_eq!(Hexf(f128::MAX).to_string(), "0x1.ffffffffffffffffffffffffffffp+16383"); - assert_eq!(Hexf(f128::MIN).to_string(), "-0x1.ffffffffffffffffffffffffffffp+16383"); + assert_eq!( + Hexf(f128::MAX).to_string(), + "0x1.ffffffffffffffffffffffffffffp+16383" + ); + assert_eq!( + Hexf(f128::MIN).to_string(), + "-0x1.ffffffffffffffffffffffffffffp+16383" + ); assert_eq!(Hexf(f128::ZERO).to_string(), "0x0p+0"); assert_eq!(Hexf(f128::NEG_ZERO).to_string(), "-0x0p+0"); assert_eq!(Hexf(f128::NAN).to_string(), "NaN"); diff --git a/libm/src/math/tan.rs b/libm/src/math/tan.rs index a074ca554..a072bdec5 100644 --- a/libm/src/math/tan.rs +++ b/libm/src/math/tan.rs @@ -53,7 +53,11 @@ pub fn tan(x: f64) -> f64 { if ix < 0x3e400000 { /* |x| < 2**-27 */ /* raise inexact if x!=0 and underflow if subnormal */ - force_eval!(if ix < 0x00100000 { x / x1p120 as f64 } else { x + x1p120 as f64 }); + force_eval!(if ix < 0x00100000 { + x / x1p120 as f64 + } else { + x + x1p120 as f64 + }); return x; } return k_tan(x, 0.0, 0); diff --git a/libm/src/math/tanf.rs b/libm/src/math/tanf.rs index 7586aae4c..8bcf9581f 100644 --- a/libm/src/math/tanf.rs +++ b/libm/src/math/tanf.rs @@ -42,7 +42,11 @@ pub fn tanf(x: f32) -> f32 { if ix < 0x39800000 { /* |x| < 2**-12 */ /* raise inexact if x!=0 and underflow if subnormal */ - force_eval!(if ix < 0x00800000 { x / x1p120 } else { x + x1p120 }); + force_eval!(if ix < 0x00800000 { + x / x1p120 + } else { + x + x1p120 + }); return x; } return k_tanf(x64, false);