]> git.lizzy.rs Git - rust.git/commitdiff
Give rounding intrinsics their own modules
authorJubilee Young <workingjubilee@gmail.com>
Sun, 25 Apr 2021 22:01:05 +0000 (15:01 -0700)
committerJubilee Young <workingjubilee@gmail.com>
Mon, 26 Apr 2021 01:27:03 +0000 (18:27 -0700)
crates/core_simd/src/intrinsics.rs
crates/core_simd/src/round.rs
crates/core_simd/tests/ops_macros.rs
crates/core_simd/tests/round.rs [new file with mode: 0644]

index 57e666873c1bb55998262e4d9d128dcab245df12..e8bcca22f6842b57c9a72d1dca0d1e883774160a 100644 (file)
     /// neg/fneg
     pub(crate) fn simd_neg<T>(x: T) -> T;
 
-    // floor
-    #[cfg(feature = "std")]
-    pub(crate) fn simd_floor<T>(x: T) -> T;
-
-    // ceil
-    #[cfg(feature = "std")]
-    pub(crate) fn simd_ceil<T>(x: T) -> T;
-
     /// fabs
     pub(crate) fn simd_fabs<T>(x: T) -> T;
 
     pub(crate) fn simd_reduce_or<T, U>(x: T) -> U;
     pub(crate) fn simd_reduce_xor<T, U>(x: T) -> U;
 }
+
+#[cfg(feature = "std")]
+mod std {
+    extern "platform-intrinsic" {
+        // ceil
+        pub(crate) fn simd_ceil<T>(x: T) -> T;
+
+        // floor
+        pub(crate) fn simd_floor<T>(x: T) -> T;
+    }
+}
+
+#[cfg(feature = "std")]
+pub(crate) use crate::intrinsics::std::*;
index ccad1aad9c44493a891194c73b3a2cc5577302c3..1855c1480d267b72bdd416d8ec917d17135cd9ea 100644 (file)
@@ -2,12 +2,12 @@ macro_rules! implement {
     {
         $type:ident, $int_type:ident
     } => {
+        #[cfg(feature = "std")]
         impl<const LANES: usize> crate::$type<LANES>
         where
             Self: crate::LanesAtMost32,
         {
             /// Returns the largest integer less than or equal to each lane.
-            #[cfg(feature = "std")]
             #[must_use = "method returns a new vector and does not mutate the original value"]
             #[inline]
             pub fn floor(self) -> Self {
@@ -15,7 +15,6 @@ pub fn floor(self) -> Self {
             }
 
             /// Returns the smallest integer greater than or equal to each lane.
-            #[cfg(feature = "std")]
             #[must_use = "method returns a new vector and does not mutate the original value"]
             #[inline]
             pub fn ceil(self) -> Self {
index 37f3b49a33061e8bb0d992cfc6ec6e47fb7b28b2..9f9992258770166038e83aa73d611f7275fb2298 100644 (file)
@@ -353,7 +353,6 @@ macro_rules! impl_float_tests {
         mod $scalar {
             type Vector<const LANES: usize> = core_simd::$vector<LANES>;
             type Scalar = $scalar;
-            type IntScalar = $int_scalar;
 
             impl_unary_op_test!(Vector<LANES>, Scalar, Neg::neg);
             impl_binary_op_test!(Vector<LANES>, Scalar, Add::add, AddAssign::add_assign);
@@ -362,25 +361,6 @@ mod $scalar {
             impl_binary_op_test!(Vector<LANES>, Scalar, Div::div, DivAssign::div_assign);
             impl_binary_op_test!(Vector<LANES>, Scalar, Rem::rem, RemAssign::rem_assign);
 
-            #[cfg(feature = "std")]
-            test_helpers::test_lanes! {
-                fn ceil<const LANES: usize>() {
-                    test_helpers::test_unary_elementwise(
-                        &Vector::<LANES>::ceil,
-                        &Scalar::ceil,
-                        &|_| true,
-                    )
-                }
-
-                fn floor<const LANES: usize>() {
-                    test_helpers::test_unary_elementwise(
-                        &Vector::<LANES>::floor,
-                        &Scalar::floor,
-                        &|_| true,
-                    )
-                }
-            }
-
             test_helpers::test_lanes! {
                 fn is_sign_positive<const LANES: usize>() {
                     test_helpers::test_unary_mask_elementwise(
@@ -446,39 +426,6 @@ fn abs<const LANES: usize>() {
                     )
                 }
 
-                fn round_from_int<const LANES: usize>() {
-                    test_helpers::test_unary_elementwise(
-                        &Vector::<LANES>::round_from_int,
-                        &|x| x as Scalar,
-                        &|_| true,
-                    )
-                }
-
-                fn to_int_unchecked<const LANES: usize>() {
-                    // The maximum integer that can be represented by the equivalently sized float has
-                    // all of the mantissa digits set to 1, pushed up to the MSB.
-                    const ALL_MANTISSA_BITS: IntScalar = ((1 << <Scalar>::MANTISSA_DIGITS) - 1);
-                    const MAX_REPRESENTABLE_VALUE: Scalar =
-                        (ALL_MANTISSA_BITS << (core::mem::size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar;
-
-                    let mut runner = proptest::test_runner::TestRunner::default();
-                    runner.run(
-                        &test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE),
-                        |x| {
-                            let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() };
-                            let result_2 = {
-                                let mut result = [0; LANES];
-                                for (i, o) in x.iter().zip(result.iter_mut()) {
-                                    *o = unsafe { i.to_int_unchecked() };
-                                }
-                                result
-                            };
-                            test_helpers::prop_assert_biteq!(result_1, result_2);
-                            Ok(())
-                        },
-                    ).unwrap();
-                }
-
                 fn horizontal_sum<const LANES: usize>() {
                     test_helpers::test_1(&|x| {
                         test_helpers::prop_assert_biteq! (
diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
new file mode 100644 (file)
index 0000000..dc9c8ad
--- /dev/null
@@ -0,0 +1,66 @@
+macro_rules! float_rounding_test {
+    { $vector:ident, $scalar:tt, $int_scalar:tt } => {
+        mod $scalar {
+            type Vector<const LANES: usize> = core_simd::$vector<LANES>;
+            type Scalar = $scalar;
+            type IntScalar = $int_scalar;
+
+            #[cfg(feature = "std")]
+            test_helpers::test_lanes! {
+                fn ceil<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::ceil,
+                        &Scalar::ceil,
+                        &|_| true,
+                    )
+                }
+
+                fn floor<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::floor,
+                        &Scalar::floor,
+                        &|_| true,
+                    )
+                }
+            }
+
+            test_helpers::test_lanes! {
+                fn from_int<const LANES: usize>() {
+                    test_helpers::test_unary_elementwise(
+                        &Vector::<LANES>::round_from_int,
+                        &|x| x as Scalar,
+                        &|_| true,
+                    )
+                }
+
+                fn to_int_unchecked<const LANES: usize>() {
+                    // The maximum integer that can be represented by the equivalently sized float has
+                    // all of the mantissa digits set to 1, pushed up to the MSB.
+                    const ALL_MANTISSA_BITS: IntScalar = ((1 << <Scalar>::MANTISSA_DIGITS) - 1);
+                    const MAX_REPRESENTABLE_VALUE: Scalar =
+                        (ALL_MANTISSA_BITS << (core::mem::size_of::<Scalar>() * 8 - <Scalar>::MANTISSA_DIGITS as usize - 1)) as Scalar;
+
+                    let mut runner = proptest::test_runner::TestRunner::default();
+                    runner.run(
+                        &test_helpers::array::UniformArrayStrategy::new(-MAX_REPRESENTABLE_VALUE..MAX_REPRESENTABLE_VALUE),
+                        |x| {
+                            let result_1 = unsafe { Vector::from_array(x).to_int_unchecked().to_array() };
+                            let result_2 = {
+                                let mut result = [0; LANES];
+                                for (i, o) in x.iter().zip(result.iter_mut()) {
+                                    *o = unsafe { i.to_int_unchecked() };
+                                }
+                                result
+                            };
+                            test_helpers::prop_assert_biteq!(result_1, result_2);
+                            Ok(())
+                        },
+                    ).unwrap();
+                }
+            }
+        }
+    }
+}
+
+float_rounding_test! { SimdF32, f32, i32 }
+float_rounding_test! { SimdF64, f64, i64 }