diff --git a/ci/run.sh b/ci/run.sh index 68d13c130..82617b001 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -184,6 +184,8 @@ fi mflags=() +nowiden_tests=$(grep -vE '^#' etc/has-nowiden-impl.txt | tr '\n' ' ') + # We enumerate features manually. mflags+=(--no-default-features) @@ -283,6 +285,7 @@ else # Test the same in release mode, which also increases coverage. Also ensure # the soft float routines are checked. "${cmd[@]}" "$profile_flag" release-checked + [ -n "${nowiden_tests:-}" ] && LIBM_F32_NO_WIDEN=1 "${cmd[@]}" "$profile_flag" release-checked -- $nowiden_tests "${cmd[@]}" "$profile_flag" release-checked --features force-soft-floats "${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics "${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics --benches diff --git a/etc/has-nowiden-impl.txt b/etc/has-nowiden-impl.txt new file mode 100644 index 000000000..4b61bec79 --- /dev/null +++ b/etc/has-nowiden-impl.txt @@ -0,0 +1,2 @@ +# Functions that have a different version based on f32_no_widen +fmaf diff --git a/libm/configure.rs b/libm/configure.rs index 2a497c7b1..f0dba502e 100644 --- a/libm/configure.rs +++ b/libm/configure.rs @@ -50,6 +50,7 @@ pub fn emit_libm_config(cfg: &Config) { emit_intrinsics_cfg(); emit_arch_cfg(); emit_optimization_cfg(cfg); + emit_widen_cfg(cfg); emit_cfg_shorthands(cfg); emit_cfg_env(cfg); emit_f16_f128_cfg(cfg); @@ -96,6 +97,15 @@ fn emit_optimization_cfg(cfg: &Config) { } } +fn emit_widen_cfg(_cfg: &Config) { + println!("cargo:rustc-check-cfg=cfg(f32_no_widen)"); + println!("cargo:rerun-if-env-changed=LIBM_F32_NO_WIDEN"); + + if env::var_os("LIBM_F32_NO_WIDEN").is_some() { + println!("cargo:rustc-cfg=f32_no_widen"); + } +} + /// Provide an alias for common longer config combinations. fn emit_cfg_shorthands(cfg: &Config) { println!("cargo:rustc-check-cfg=cfg(x86_no_sse)"); diff --git a/libm/src/math/fma_wide.rs b/libm/src/math/fma_wide.rs index f268c2f14..5b26f0072 100644 --- a/libm/src/math/fma_wide.rs +++ b/libm/src/math/fma_wide.rs @@ -23,7 +23,11 @@ pub fn fmaf(x: f32, y: f32, z: f32) -> f32 { args: x, y, z, } - fma_wide_round(x, y, z, Round::Nearest).val + if cfg!(f32_no_widen) { + super::fma::fma_round(x, y, z, Round::Nearest).val + } else { + fma_wide_round(x, y, z, Round::Nearest).val + } } /// Fma implementation when a hardware-backed larger float type is available. For `f32` and `f64`,