From 278eb287b34d6335a3ac4720f1517a12671fd0b8 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sun, 3 Mar 2024 11:28:58 -0500 Subject: [PATCH] Attempt to avoid LLVM error --- Cargo.lock | 2 + crates/std_float/src/lib.rs | 114 ++++++++++++++++++-------------- crates/std_float/tests/float.rs | 12 +++- 3 files changed, 78 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ede15ff002..1584c704fb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,6 +178,8 @@ version = "0.1.0" dependencies = [ "core_simd", "test_helpers", + "wasm-bindgen", + "wasm-bindgen-test", ] [[package]] diff --git a/crates/std_float/src/lib.rs b/crates/std_float/src/lib.rs index 44bbcba412f..148aa5f9f17 100644 --- a/crates/std_float/src/lib.rs +++ b/crates/std_float/src/lib.rs @@ -1,4 +1,3 @@ -#![cfg_attr(feature = "as_crate", no_std)] // We are std! #![cfg_attr( feature = "as_crate", feature(core_intrinsics), @@ -67,43 +66,28 @@ pub trait StdFloat: Sealed + Sized { /// Produces a vector where every element has the sine of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn sin(self) -> Self { - unsafe { intrinsics::simd_fsin(self) } - } + fn sin(self) -> Self; /// Produces a vector where every element has the cosine of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn cos(self) -> Self { - unsafe { intrinsics::simd_fcos(self) } - } + fn cos(self) -> Self; /// Produces a vector where every element has the exponential (base e) of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn exp(self) -> Self { - unsafe { intrinsics::simd_fexp(self) } - } + fn exp(self) -> Self; /// Produces a vector where every element has the exponential (base 2) of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn exp2(self) -> Self { - unsafe { intrinsics::simd_fexp2(self) } - } + fn exp2(self) -> Self; /// Produces a vector where every element has the natural logarithm of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn ln(self) -> Self { - unsafe { intrinsics::simd_flog(self) } - } + fn ln(self) -> Self; /// Produces a vector where every element has the logarithm with respect to an arbitrary /// in the equivalently-indexed elements in `self` and `base`. @@ -115,19 +99,13 @@ pub trait StdFloat: Sealed + Sized { /// Produces a vector where every element has the base-2 logarithm of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn log2(self) -> Self { - unsafe { intrinsics::simd_flog2(self) } - } + fn log2(self) -> Self; /// Produces a vector where every element has the base-10 logarithm of the value /// in the equivalently-indexed element in `self`. - #[inline] #[must_use = "method returns a new vector and does not mutate the original value"] - fn log10(self) -> Self { - unsafe { intrinsics::simd_flog10(self) } - } + fn log10(self) -> Self; /// Returns the smallest integer greater than or equal to each element. #[must_use = "method returns a new vector and does not mutate the original value"] @@ -165,27 +143,65 @@ pub trait StdFloat: Sealed + Sized { impl Sealed for Simd where LaneCount: SupportedLaneCount {} impl Sealed for Simd where LaneCount: SupportedLaneCount {} -// We can safely just use all the defaults. -impl StdFloat for Simd -where - LaneCount: SupportedLaneCount, -{ - /// Returns the floating point's fractional value, with its integer part removed. - #[must_use = "method returns a new vector and does not mutate the original value"] - #[inline] - fn fract(self) -> Self { - self - self.trunc() +macro_rules! impl_float { + { + $($fn:ident: $intrinsic:ident,)* + } => { + impl StdFloat for Simd + where + LaneCount: SupportedLaneCount, + { + #[inline] + fn fract(self) -> Self { + self - self.trunc() + } + + $( + #[inline] + fn $fn(self) -> Self { + unsafe { intrinsics::$intrinsic(self) } + } + )* + } + + impl StdFloat for Simd + where + LaneCount: SupportedLaneCount, + { + #[inline] + fn fract(self) -> Self { + self - self.trunc() + } + + $( + #[inline] + fn $fn(self) -> Self { + // https://github.com/llvm/llvm-project/issues/83729 + #[cfg(target_arch = "aarch64")] + { + let mut ln = Self::splat(0f64); + for i in 0..N { + ln[i] = self[i].$fn() + } + ln + } + + #[cfg(not(target_arch = "aarch64"))] + { + unsafe { intrinsics::$intrinsic(self) } + } + } + )* + } } } -impl StdFloat for Simd -where - LaneCount: SupportedLaneCount, -{ - /// Returns the floating point's fractional value, with its integer part removed. - #[must_use = "method returns a new vector and does not mutate the original value"] - #[inline] - fn fract(self) -> Self { - self - self.trunc() - } +impl_float! { + sin: simd_fsin, + cos: simd_fcos, + exp: simd_fexp, + exp2: simd_fexp2, + ln: simd_flog, + log2: simd_flog2, + log10: simd_flog10, } diff --git a/crates/std_float/tests/float.rs b/crates/std_float/tests/float.rs index 60bdf00fba8..c66c968f8c6 100644 --- a/crates/std_float/tests/float.rs +++ b/crates/std_float/tests/float.rs @@ -53,9 +53,19 @@ macro_rules! impl_tests { mod $scalar { use std_float::StdFloat; - unary_test! { $scalar, sqrt, sin, cos, exp, exp2, ln, log2, log10, ceil, floor, round, trunc, fract } + unary_test! { $scalar, sqrt, sin, cos, exp, exp2, ln, log2, log10, ceil, floor, round, trunc } binary_test! { $scalar, log } ternary_test! { $scalar, mul_add } + + test_helpers::test_lanes! { + fn fract() { + test_helpers::test_unary_elementwise_flush_subnormals( + &core_simd::simd::Simd::<$scalar, LANES>::fract, + &$scalar::fract, + &|_| true, + ) + } + } } } }