summaryrefslogtreecommitdiffstats
path: root/third_party/rust/packed_simd/src/api/reductions/min_max.rs
diff options
context:
space:
mode:
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.rs360
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());
- }
- }
- }
- }
- };
-}