diff options
Diffstat (limited to 'third_party/rust/packed_simd/src/api/reductions/min_max.rs')
-rw-r--r-- | third_party/rust/packed_simd/src/api/reductions/min_max.rs | 360 |
1 files changed, 0 insertions, 360 deletions
diff --git a/third_party/rust/packed_simd/src/api/reductions/min_max.rs b/third_party/rust/packed_simd/src/api/reductions/min_max.rs deleted file mode 100644 index a3ce13a451..0000000000 --- a/third_party/rust/packed_simd/src/api/reductions/min_max.rs +++ /dev/null @@ -1,360 +0,0 @@ -//! Implements portable horizontal vector min/max reductions. - -macro_rules! impl_reduction_min_max { - ([$elem_ty:ident; $elem_count:expr]: $id:ident - | $ielem_ty:ident | $test_tt:tt) => { - impl $id { - /// Largest vector element value. - #[inline] - pub fn max_element(self) -> $elem_ty { - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc64", - target_arch = "wasm32", - )))] - { - use crate::llvm::simd_reduce_max; - let v: $ielem_ty = unsafe { simd_reduce_max(self.0) }; - v as $elem_ty - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc64", - target_arch = "wasm32", - ))] - { - // FIXME: broken on AArch64 - // https://github.com/rust-lang-nursery/packed_simd/issues/15 - // FIXME: broken on WASM32 - // https://github.com/rust-lang-nursery/packed_simd/issues/91 - let mut x = self.extract(0); - for i in 1..$id::lanes() { - x = x.max(self.extract(i)); - } - x - } - } - - /// Smallest vector element value. - #[inline] - pub fn min_element(self) -> $elem_ty { - #[cfg(not(any( - target_arch = "aarch64", - target_arch = "arm", - all(target_arch = "x86", not(target_feature = "sse2")), - target_arch = "powerpc64", - target_arch = "wasm32", - ),))] - { - use crate::llvm::simd_reduce_min; - let v: $ielem_ty = unsafe { simd_reduce_min(self.0) }; - v as $elem_ty - } - #[cfg(any( - target_arch = "aarch64", - target_arch = "arm", - all(target_arch = "x86", not(target_feature = "sse2")), - target_arch = "powerpc64", - target_arch = "wasm32", - ))] - { - // FIXME: broken on AArch64 - // https://github.com/rust-lang-nursery/packed_simd/issues/15 - // FIXME: broken on i586-unknown-linux-gnu - // https://github.com/rust-lang-nursery/packed_simd/issues/22 - // FIXME: broken on WASM32 - // https://github.com/rust-lang-nursery/packed_simd/issues/91 - let mut x = self.extract(0); - for i in 1..$id::lanes() { - x = x.min(self.extract(i)); - } - x - } - } - } - test_if! {$test_tt: - paste::item! { - // Comparisons use integer casts within mantissa^1 range. - #[allow(clippy::float_cmp)] - pub mod [<$id _reduction_min_max>] { - use super::*; - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - pub fn max_element() { - let v = $id::splat(0 as $elem_ty); - assert_eq!(v.max_element(), 0 as $elem_ty); - if $id::lanes() > 1 { - let v = v.replace(1, 1 as $elem_ty); - assert_eq!(v.max_element(), 1 as $elem_ty); - } - let v = v.replace(0, 2 as $elem_ty); - assert_eq!(v.max_element(), 2 as $elem_ty); - } - - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - pub fn min_element() { - let v = $id::splat(0 as $elem_ty); - assert_eq!(v.min_element(), 0 as $elem_ty); - if $id::lanes() > 1 { - let v = v.replace(1, 1 as $elem_ty); - assert_eq!(v.min_element(), 0 as $elem_ty); - } - let v = $id::splat(1 as $elem_ty); - let v = v.replace(0, 2 as $elem_ty); - if $id::lanes() > 1 { - assert_eq!(v.min_element(), 1 as $elem_ty); - } else { - assert_eq!(v.min_element(), 2 as $elem_ty); - } - if $id::lanes() > 1 { - let v = $id::splat(2 as $elem_ty); - let v = v.replace(1, 1 as $elem_ty); - assert_eq!(v.min_element(), 1 as $elem_ty); - } - } - } - } - } - }; -} - -macro_rules! test_reduction_float_min_max { - ([$elem_ty:ident; $elem_count:expr]: $id:ident | $test_tt:tt) => { - test_if! { - $test_tt: - paste::item! { - // Comparisons use integer casts within mantissa^1 range. - #[allow(clippy::float_cmp)] - pub mod [<$id _reduction_min_max_nan>] { - use super::*; - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn min_element_test() { - let n = crate::$elem_ty::NAN; - - assert_eq!(n.min(-3.), -3.); - assert_eq!((-3. as $elem_ty).min(n), -3.); - - let v0 = $id::splat(-3.); - - let target_with_broken_last_lane_nan = !cfg!(any( - target_arch = "arm", target_arch = "aarch64", - all(target_arch = "x86", - not(target_feature = "sse2") - ), - target_arch = "powerpc64", - target_arch = "wasm32", - )); - - // The vector is initialized to `-3.`s: [-3, -3, -3, -3] - for i in 0..$id::lanes() { - // We replace the i-th element of the vector with - // `NaN`: [-3, -3, -3, NaN] - let mut v = v0.replace(i, n); - - // If the NaN is in the last place, the LLVM - // implementation of these methods is broken on some - // targets: - if i == $id::lanes() - 1 && - target_with_broken_last_lane_nan { - assert_eq!(v.min_element(), -3., - "[A]: nan at {} => {} | {:?}", - i, v.min_element(), v); - - // If we replace all the elements in the vector - // up-to the `i-th` lane with `NaN`s, the result - // is still always `-3.` unless all elements of - // the vector are `NaN`s: - for j in 0..i { - v = v.replace(j, n); - if j == i-1 { - assert!(v.min_element().is_nan(), - "[B]: nan at {} => {} | {:?}", - i, v.min_element(), v); - } else { - assert_eq!(v.min_element(), -3., - "[B]: nan at {} => {} | {:?}", - i, v.min_element(), v); - } - } - - // We are done here, since we were in the last - // lane which is the last iteration of the loop. - break - } - - // We are not in the last lane, and there is only - // one `NaN` in the vector. - - // If the vector has one lane, the result is `NaN`: - if $id::lanes() == 1 { - assert!(v.min_element().is_nan(), - "[C]: all nans | v={:?} | min={} | \ -is_nan: {}", - v, v.min_element(), - v.min_element().is_nan() - ); - - // And we are done, since the vector only has - // one lane anyways. - break; - } - - // The vector has more than one lane, since there is - // only one `NaN` in the vector, the result is - // always `-3`. - assert_eq!(v.min_element(), -3., - "[D]: nan at {} => {} | {:?}", - i, v.min_element(), v); - - // If we replace all the elements in the vector - // up-to the `i-th` lane with `NaN`s, the result is - // still always `-3.` unless all elements of the - // vector are `NaN`s: - for j in 0..i { - v = v.replace(j, n); - - if i == $id::lanes() - 1 && j == i - 1 { - // All elements of the vector are `NaN`s, - // therefore the result is NaN as well. - // - // Note: the #lanes of the vector is > 1, so - // "i - 1" does not overflow. - assert!(v.min_element().is_nan(), - "[E]: all nans | v={:?} | min={} | \ -is_nan: {}", - v, v.min_element(), - v.min_element().is_nan()); - } else { - // There are non-`NaN` elements in the - // vector, therefore the result is `-3.`: - assert_eq!(v.min_element(), -3., - "[F]: nan at {} => {} | {:?}", - i, v.min_element(), v); - } - } - } - - // If the vector contains all NaNs the result is NaN: - assert!($id::splat(n).min_element().is_nan(), - "all nans | v={:?} | min={} | is_nan: {}", - $id::splat(n), $id::splat(n).min_element(), - $id::splat(n).min_element().is_nan()); - } - #[cfg_attr(not(target_arch = "wasm32"), test)] - #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn max_element_test() { - let n = crate::$elem_ty::NAN; - - assert_eq!(n.max(-3.), -3.); - assert_eq!((-3. as $elem_ty).max(n), -3.); - - let v0 = $id::splat(-3.); - - let target_with_broken_last_lane_nan = !cfg!(any( - target_arch = "arm", target_arch = "aarch64", - target_arch = "powerpc64", target_arch = "wasm32", - )); - - // The vector is initialized to `-3.`s: [-3, -3, -3, -3] - for i in 0..$id::lanes() { - // We replace the i-th element of the vector with - // `NaN`: [-3, -3, -3, NaN] - let mut v = v0.replace(i, n); - - // If the NaN is in the last place, the LLVM - // implementation of these methods is broken on some - // targets: - if i == $id::lanes() - 1 && - target_with_broken_last_lane_nan { - assert_eq!(v.max_element(), -3., - "[A]: nan at {} => {} | {:?}", - i, v.max_element(), v); - - // If we replace all the elements in the vector - // up-to the `i-th` lane with `NaN`s, the result - // is still always `-3.` unless all elements of - // the vector are `NaN`s: - for j in 0..i { - v = v.replace(j, n); - if j == i-1 { - assert!(v.min_element().is_nan(), - "[B]: nan at {} => {} | {:?}", - i, v.min_element(), v); - } else { - assert_eq!(v.max_element(), -3., - "[B]: nan at {} => {} | {:?}", - i, v.max_element(), v); - } - } - - // We are done here, since we were in the last - // lane which is the last iteration of the loop. - break - } - - // We are not in the last lane, and there is only - // one `NaN` in the vector. - - // If the vector has one lane, the result is `NaN`: - if $id::lanes() == 1 { - assert!(v.max_element().is_nan(), - "[C]: all nans | v={:?} | min={} | \ -is_nan: {}", - v, v.max_element(), - v.max_element().is_nan()); - - // And we are done, since the vector only has - // one lane anyways. - break; - } - - // The vector has more than one lane, since there is - // only one `NaN` in the vector, the result is - // always `-3`. - assert_eq!(v.max_element(), -3., - "[D]: nan at {} => {} | {:?}", - i, v.max_element(), v); - - // If we replace all the elements in the vector - // up-to the `i-th` lane with `NaN`s, the result is - // still always `-3.` unless all elements of the - // vector are `NaN`s: - for j in 0..i { - v = v.replace(j, n); - - if i == $id::lanes() - 1 && j == i - 1 { - // All elements of the vector are `NaN`s, - // therefore the result is NaN as well. - // - // Note: the #lanes of the vector is > 1, so - // "i - 1" does not overflow. - assert!(v.max_element().is_nan(), - "[E]: all nans | v={:?} | max={} | \ -is_nan: {}", - v, v.max_element(), - v.max_element().is_nan()); - } else { - // There are non-`NaN` elements in the - // vector, therefore the result is `-3.`: - assert_eq!(v.max_element(), -3., - "[F]: nan at {} => {} | {:?}", - i, v.max_element(), v); - } - } - } - - // If the vector contains all NaNs the result is NaN: - assert!($id::splat(n).max_element().is_nan(), - "all nans | v={:?} | max={} | is_nan: {}", - $id::splat(n), $id::splat(n).max_element(), - $id::splat(n).max_element().is_nan()); - } - } - } - } - }; -} |