1
Fork 0

Attempt to avoid LLVM error

This commit is contained in:
Caleb Zulawski 2024-03-03 11:28:58 -05:00
parent 2f062b8f5e
commit 278eb287b3
3 changed files with 78 additions and 50 deletions

2
Cargo.lock generated
View file

@ -178,6 +178,8 @@ version = "0.1.0"
dependencies = [ dependencies = [
"core_simd", "core_simd",
"test_helpers", "test_helpers",
"wasm-bindgen",
"wasm-bindgen-test",
] ]
[[package]] [[package]]

View file

@ -1,4 +1,3 @@
#![cfg_attr(feature = "as_crate", no_std)] // We are std!
#![cfg_attr( #![cfg_attr(
feature = "as_crate", feature = "as_crate",
feature(core_intrinsics), feature(core_intrinsics),
@ -67,43 +66,28 @@ pub trait StdFloat: Sealed + Sized {
/// Produces a vector where every element has the sine of the value /// Produces a vector where every element has the sine of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn sin(self) -> Self { fn sin(self) -> Self;
unsafe { intrinsics::simd_fsin(self) }
}
/// Produces a vector where every element has the cosine of the value /// Produces a vector where every element has the cosine of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn cos(self) -> Self { fn cos(self) -> Self;
unsafe { intrinsics::simd_fcos(self) }
}
/// Produces a vector where every element has the exponential (base e) of the value /// Produces a vector where every element has the exponential (base e) of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn exp(self) -> Self { fn exp(self) -> Self;
unsafe { intrinsics::simd_fexp(self) }
}
/// Produces a vector where every element has the exponential (base 2) of the value /// Produces a vector where every element has the exponential (base 2) of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn exp2(self) -> Self { fn exp2(self) -> Self;
unsafe { intrinsics::simd_fexp2(self) }
}
/// Produces a vector where every element has the natural logarithm of the value /// Produces a vector where every element has the natural logarithm of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn ln(self) -> Self { fn ln(self) -> Self;
unsafe { intrinsics::simd_flog(self) }
}
/// Produces a vector where every element has the logarithm with respect to an arbitrary /// Produces a vector where every element has the logarithm with respect to an arbitrary
/// in the equivalently-indexed elements in `self` and `base`. /// 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 /// Produces a vector where every element has the base-2 logarithm of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn log2(self) -> Self { fn log2(self) -> Self;
unsafe { intrinsics::simd_flog2(self) }
}
/// Produces a vector where every element has the base-10 logarithm of the value /// Produces a vector where every element has the base-10 logarithm of the value
/// in the equivalently-indexed element in `self`. /// in the equivalently-indexed element in `self`.
#[inline]
#[must_use = "method returns a new vector and does not mutate the original value"] #[must_use = "method returns a new vector and does not mutate the original value"]
fn log10(self) -> Self { fn log10(self) -> Self;
unsafe { intrinsics::simd_flog10(self) }
}
/// Returns the smallest integer greater than or equal to each element. /// 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"] #[must_use = "method returns a new vector and does not mutate the original value"]
@ -165,27 +143,65 @@ pub trait StdFloat: Sealed + Sized {
impl<const N: usize> Sealed for Simd<f32, N> where LaneCount<N>: SupportedLaneCount {} impl<const N: usize> Sealed for Simd<f32, N> where LaneCount<N>: SupportedLaneCount {}
impl<const N: usize> Sealed for Simd<f64, N> where LaneCount<N>: SupportedLaneCount {} impl<const N: usize> Sealed for Simd<f64, N> where LaneCount<N>: SupportedLaneCount {}
// We can safely just use all the defaults. macro_rules! impl_float {
impl<const N: usize> StdFloat for Simd<f32, N> {
where $($fn:ident: $intrinsic:ident,)*
LaneCount<N>: SupportedLaneCount, } => {
{ impl<const N: usize> StdFloat for Simd<f32, N>
/// Returns the floating point's fractional value, with its integer part removed. where
#[must_use = "method returns a new vector and does not mutate the original value"] LaneCount<N>: SupportedLaneCount,
#[inline] {
fn fract(self) -> Self { #[inline]
self - self.trunc() fn fract(self) -> Self {
self - self.trunc()
}
$(
#[inline]
fn $fn(self) -> Self {
unsafe { intrinsics::$intrinsic(self) }
}
)*
}
impl<const N: usize> StdFloat for Simd<f64, N>
where
LaneCount<N>: 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<const N: usize> StdFloat for Simd<f64, N> impl_float! {
where sin: simd_fsin,
LaneCount<N>: SupportedLaneCount, cos: simd_fcos,
{ exp: simd_fexp,
/// Returns the floating point's fractional value, with its integer part removed. exp2: simd_fexp2,
#[must_use = "method returns a new vector and does not mutate the original value"] ln: simd_flog,
#[inline] log2: simd_flog2,
fn fract(self) -> Self { log10: simd_flog10,
self - self.trunc()
}
} }

View file

@ -53,9 +53,19 @@ macro_rules! impl_tests {
mod $scalar { mod $scalar {
use std_float::StdFloat; 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 } binary_test! { $scalar, log }
ternary_test! { $scalar, mul_add } ternary_test! { $scalar, mul_add }
test_helpers::test_lanes! {
fn fract<const LANES: usize>() {
test_helpers::test_unary_elementwise_flush_subnormals(
&core_simd::simd::Simd::<$scalar, LANES>::fract,
&$scalar::fract,
&|_| true,
)
}
}
} }
} }
} }