From 3fae09bd08b4ffacd3f81cc6ec13772e99d29796 Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Fri, 12 Mar 2021 20:09:31 -0500 Subject: [PATCH] Revert "Revert i586 fix, fix test instead" This reverts commit 1ea2f128821339d8050ca936f24b71677352437e. --- crates/core_simd/src/reduction.rs | 14 ++++++++++++-- crates/core_simd/tests/ops_macros.rs | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/core_simd/src/reduction.rs b/crates/core_simd/src/reduction.rs index 177669ff444e..e59bf93baa31 100644 --- a/crates/core_simd/src/reduction.rs +++ b/crates/core_simd/src/reduction.rs @@ -59,13 +59,23 @@ macro_rules! impl_float_reductions { /// Produces the sum of the lanes of the vector. #[inline] pub fn sum(self) -> $scalar { - unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) } + // f32 SIMD sum is inaccurate on i586 + if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) && core::mem::size_of::<$scalar>() == 4 { + self.as_slice().iter().sum() + } else { + unsafe { crate::intrinsics::simd_reduce_add_ordered(self, 0.) } + } } /// Produces the sum of the lanes of the vector. #[inline] pub fn product(self) -> $scalar { - unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) } + // f32 SIMD product is inaccurate on i586 + if cfg!(all(target_arch = "x86", not(target_feature = "sse2"))) && core::mem::size_of::<$scalar>() == 4 { + self.as_slice().iter().product() + } else { + unsafe { crate::intrinsics::simd_reduce_mul_ordered(self, 1.) } + } } /// Returns the maximum lane in the vector. diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs index 59e923ac5c14..2b65d5146238 100644 --- a/crates/core_simd/tests/ops_macros.rs +++ b/crates/core_simd/tests/ops_macros.rs @@ -483,7 +483,7 @@ macro_rules! impl_float_tests { test_helpers::test_1(&|x| { test_helpers::prop_assert_biteq! ( Vector::::from_array(x).sum(), - x.iter().sum(), + x.iter().copied().fold(0 as Scalar, ::add), ); Ok(()) }); @@ -493,7 +493,7 @@ macro_rules! impl_float_tests { test_helpers::test_1(&|x| { test_helpers::prop_assert_biteq! ( Vector::::from_array(x).product(), - x.iter().product(), + x.iter().copied().fold(1. as Scalar, ::mul), ); Ok(()) });