From 00ec1629ca7325d8fdf8dd3c1654c921b60ced59 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 20 Oct 2014 11:38:51 +0200 Subject: [PATCH] Fix bug #859: pexp(NaN) returned Inf instead of NaN --- Eigen/src/Core/arch/SSE/MathFunctions.h | 2 +- test/main.h | 20 ++++++++++++++++++++ test/packetmath.cpp | 6 ++++++ test/stable_norm.cpp | 5 ----- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h index 99cbd0d95..9776afca3 100644 --- a/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -166,7 +166,7 @@ Packet4f pexp(const Packet4f& _x) emm0 = _mm_cvttps_epi32(fx); emm0 = _mm_add_epi32(emm0, p4i_0x7f); emm0 = _mm_slli_epi32(emm0, 23); - return pmul(y, _mm_castsi128_ps(emm0)); + return pmax(pmul(y, Packet4f(_mm_castsi128_ps(emm0))), _x); } template<> EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS EIGEN_UNUSED Packet2d pexp(const Packet2d& _x) diff --git a/test/main.h b/test/main.h index c3b2990c6..664204866 100644 --- a/test/main.h +++ b/test/main.h @@ -406,6 +406,26 @@ void randomPermutationVector(PermutationVectorType& v, typename PermutationVecto } } +template bool isNotNaN(const T& x) +{ + return x==x; +} + +template bool isNaN(const T& x) +{ + return x!=x; +} + +template bool isInf(const T& x) +{ + return x > NumTraits::highest(); +} + +template bool isMinusInf(const T& x) +{ + return x < NumTraits::lowest(); +} + } // end namespace Eigen template struct GetDifferentType; diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 2c0519c41..935f7ceba 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -239,6 +239,12 @@ template void packetmath_real() data2[i] = internal::random(-87,88); } CHECK_CWISE1_IF(internal::packet_traits::HasExp, std::exp, internal::pexp); + { + data1[0] = std::numeric_limits::quiet_NaN(); + packet_helper::HasExp,Packet> h; + h.store(data2, internal::pexp(h.load(data1))); + VERIFY(isNaN(data2[0])); + } for (int i=0; i bool isNotNaN(const T& x) -{ - return x==x; -} - // workaround aggressive optimization in ICC template EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }