aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2013-02-14 23:34:05 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2013-02-14 23:34:05 +0100
commit8745da14d8609425764c399c6ac1f44235277ef3 (patch)
treeaa26f6fb5b7890e973f8f810d9847d98ed3c1be6 /Eigen
parent912ba10efe420ed17dabb6085f258c2ec4bd6789 (diff)
Fix SSE plog<float> to return -INF on 0
Diffstat (limited to 'Eigen')
-rw-r--r--Eigen/src/Core/arch/SSE/MathFunctions.h10
1 files changed, 7 insertions, 3 deletions
diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h
index 557af8455..5ede55fba 100644
--- a/Eigen/src/Core/arch/SSE/MathFunctions.h
+++ b/Eigen/src/Core/arch/SSE/MathFunctions.h
@@ -31,7 +31,8 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
/* the smallest non denormalized float number */
_EIGEN_DECLARE_CONST_Packet4f_FROM_INT(min_norm_pos, 0x00800000);
-
+ _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(minus_inf, 0xff800000);//-1.f/0.f);
+
/* natural logarithm computed for 4 simultaneous float
return NaN for x <= 0
*/
@@ -51,7 +52,8 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
Packet4i emm0;
- Packet4f invalid_mask = _mm_cmple_ps(x, _mm_setzero_ps());
+ Packet4f invalid_mask = _mm_cmplt_ps(x, _mm_setzero_ps());
+ Packet4f iszero_mask = _mm_cmpeq_ps(x, _mm_setzero_ps());
x = pmax(x, p4f_min_norm_pos); /* cut off denormalized stuff */
emm0 = _mm_srli_epi32(_mm_castps_si128(x), 23);
@@ -96,7 +98,9 @@ Packet4f plog<Packet4f>(const Packet4f& _x)
y2 = pmul(e, p4f_cephes_log_q2);
x = padd(x, y);
x = padd(x, y2);
- return _mm_or_ps(x, invalid_mask); // negative arg will be NAN
+ // negative arg will be NAN, 0 will be -INF
+ return _mm_or_ps(_mm_andnot_ps(iszero_mask, _mm_or_ps(x, invalid_mask)),
+ _mm_and_ps(iszero_mask, p4f_minus_inf));
}
template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED