@@ -58,22 +58,38 @@ macro_rules! impl_float_reductions {
58
58
/// Produces the sum of the lanes of the vector.
59
59
#[ inline]
60
60
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
+ }
62
67
}
63
68
64
69
/// Produces the sum of the lanes of the vector.
65
70
#[ inline]
66
71
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
+ }
68
78
}
69
79
70
80
/// 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`.
71
84
#[ inline]
72
85
pub fn max_lane( self ) -> $scalar {
73
86
unsafe { crate :: intrinsics:: simd_reduce_max( self ) }
74
87
}
75
88
76
89
/// 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`.
77
93
#[ inline]
78
94
pub fn min_lane( self ) -> $scalar {
79
95
unsafe { crate :: intrinsics:: simd_reduce_min( self ) }
0 commit comments