@@ -58,22 +58,38 @@ macro_rules! impl_float_reductions {
5858 /// Produces the sum of the lanes of the vector.
5959 #[ inline]
6060 pub fn sum( self ) -> $scalar {
61- unsafe { crate :: intrinsics:: simd_reduce_add_ordered( self , 0. ) }
61+ // f32 SIMD sum is inaccurate on i586
62+ if cfg!( target_arch = "i586" ) && core:: mem:: size_of:: <$scalar>( ) == 4 {
63+ self . as_slice( ) . iter( ) . sum( )
64+ } else {
65+ unsafe { crate :: intrinsics:: simd_reduce_add_ordered( self , 0. ) }
66+ }
6267 }
6368
6469 /// Produces the sum of the lanes of the vector.
6570 #[ inline]
6671 pub fn product( self ) -> $scalar {
67- unsafe { crate :: intrinsics:: simd_reduce_mul_ordered( self , 1. ) }
72+ // f32 SIMD product is inaccurate on i586
73+ if cfg!( target_arch = "i586" ) && core:: mem:: size_of:: <$scalar>( ) == 4 {
74+ self . as_slice( ) . iter( ) . product( )
75+ } else {
76+ unsafe { crate :: intrinsics:: simd_reduce_mul_ordered( self , 1. ) }
77+ }
6878 }
6979
7080 /// Returns the maximum lane in the vector.
81+ ///
82+ /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
83+ /// return either. This function will not return `NaN` unless all lanes are `NaN`.
7184 #[ inline]
7285 pub fn max_lane( self ) -> $scalar {
7386 unsafe { crate :: intrinsics:: simd_reduce_max( self ) }
7487 }
7588
7689 /// Returns the minimum lane in the vector.
90+ ///
91+ /// Returns values based on equality, so a vector containing both `0.` and `-0.` may
92+ /// return either. This function will not return `NaN` unless all lanes are `NaN`.
7793 #[ inline]
7894 pub fn min_lane( self ) -> $scalar {
7995 unsafe { crate :: intrinsics:: simd_reduce_min( self ) }
0 commit comments