COMPMID-3457: vexp failure in QASYMM8_SIGNED overflowing
authormorgolock <pablo.tello@arm.com>
Mon, 11 May 2020 15:00:04 +0000 (16:00 +0100)
committerGeorgios Pinitas <georgios.pinitas@arm.com>
Fri, 15 May 2020 11:24:27 +0000 (11:24 +0000)
Change-Id: Ied11a4a3e9d04615a1a1f0bfa552f3dd8293a170
Signed-off-by: morgolock <pablo.tello@arm.com>
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/3178
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>

arm_compute/core/NEON/NEMath.h
arm_compute/core/NEON/NEMath.inl

index 3905f67e2977b5a94e7230abd2a55a7a57bf9b53..8827bbf459f006fb8503a8145cf0cd461d96132d 100644 (file)
@@ -25,6 +25,7 @@
 #define ARM_COMPUTE_NEMATH_H
 
 #include <arm_neon.h>
+#include <array>
 
 namespace arm_compute
 {
index 49870d06a839cc8eca12f2db4ba4cd44ae6e0c8b..032bfde238c94866f9ef2643b61844a9587c28df 100644 (file)
@@ -22,6 +22,7 @@
  * SOFTWARE.
  */
 #include <cmath>
+#include <limits>
 
 #ifndef M_PI
 #define M_PI (3.14159265358979323846)
@@ -147,6 +148,8 @@ inline float32x4_t vexpq_f32(float32x4_t x)
 {
     static const float32x4_t CONST_LN2          = vdupq_n_f32(0.6931471805f); // ln(2)
     static const float32x4_t CONST_INV_LN2      = vdupq_n_f32(1.4426950408f); // 1/ln(2)
+    static const float32x4_t CONST_INF          = vdupq_n_f32(std::numeric_limits<float>::infinity());
+    static const float32x4_t CONST_MAX_INPUT    = vdupq_n_f32(88.7f);
     static const float32x4_t CONST_0            = vdupq_n_f32(0.f);
     static const int32x4_t   CONST_NEGATIVE_126 = vdupq_n_s32(-126);
 
@@ -159,7 +162,8 @@ inline float32x4_t vexpq_f32(float32x4_t x)
 
     // Reconstruct
     poly = vreinterpretq_f32_s32(vqaddq_s32(vreinterpretq_s32_f32(poly), vqshlq_n_s32(m, 23)));
-    poly = vbslq_f32(vcltq_s32(m, CONST_NEGATIVE_126), CONST_0, poly);
+    poly = vbslq_f32(vcltq_s32(m, CONST_NEGATIVE_126), CONST_0, poly); // Handle underflow
+    poly = vbslq_f32(vcgtq_f32(x, CONST_MAX_INPUT), CONST_INF, poly);  // Handle overflow
 
     return poly;
 }