From 873639d6fd11c734cee6ae566e6e1e377f208fe7 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 7 Oct 2020 11:51:54 -0700 Subject: [PATCH 1/2] Use bitxor to implement Neg for floats --- crates/core_simd/src/ops.rs | 15 +++++++++++++-- crates/core_simd/tests/ops_impl/float_macros.rs | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 5af10a4e1886..9e0bc3f42a66 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -212,7 +212,18 @@ macro_rules! impl_op { impl core::ops::Neg for $type { type Output = Self; fn neg(self) -> Self::Output { - <$type>::splat(-<$scalar>::default()) - self + <$type>::splat(0) - self + } + } + } + }; + + { impl Neg for $type:ty, $scalar:ty, @float } => { + impl_ref_ops! { + impl core::ops::Neg for $type { + type Output = Self; + fn neg(self) -> Self::Output { + Self::from_bits(<$type>::splat(-0.0).to_bits() ^ self.to_bits()) } } } @@ -310,7 +321,7 @@ macro_rules! impl_float_ops { impl_op! { impl Mul for $vector, $scalar } impl_op! { impl Div for $vector, $scalar } impl_op! { impl Rem for $vector, $scalar } - impl_op! { impl Neg for $vector, $scalar } + impl_op! { impl Neg for $vector, $scalar, @float } impl_op! { impl Index for $vector, $scalar } )* )* diff --git a/crates/core_simd/tests/ops_impl/float_macros.rs b/crates/core_simd/tests/ops_impl/float_macros.rs index 1c969a2e8af3..7df30ec39f6c 100644 --- a/crates/core_simd/tests/ops_impl/float_macros.rs +++ b/crates/core_simd/tests/ops_impl/float_macros.rs @@ -289,6 +289,15 @@ macro_rules! float_tests { assert_biteq!(-v, expected); } + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn neg_odd_floats() { + for v in slice_chunks(&C) { + let expected = apply_unary_lanewise(v, core::ops::Neg::neg); + assert_biteq!(-v, expected); + } + } + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn abs_negative() { From ffd562f2181f5969d56c4a6c9399be27058c8a74 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Wed, 7 Oct 2020 13:24:21 -0700 Subject: [PATCH 2/2] Add comment about fneg to the bitxor in float neg --- crates/core_simd/src/ops.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/core_simd/src/ops.rs b/crates/core_simd/src/ops.rs index 9e0bc3f42a66..5a186649821b 100644 --- a/crates/core_simd/src/ops.rs +++ b/crates/core_simd/src/ops.rs @@ -223,6 +223,8 @@ macro_rules! impl_op { impl core::ops::Neg for $type { type Output = Self; fn neg(self) -> Self::Output { + // FIXME: Replace this with fneg intrinsic once available. + // https://github.com/rust-lang/stdsimd/issues/32 Self::from_bits(<$type>::splat(-0.0).to_bits() ^ self.to_bits()) } }