Attempt to avoid LLVM error
This commit is contained in:
parent
2f062b8f5e
commit
278eb287b3
3 changed files with 78 additions and 50 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -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]]
|
||||||
|
|
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue