Merge branch release-2021
[alexxy/gromacs.git] / src / gromacs / simd / impl_arm_sve / impl_arm_sve_simd_double.h
index 542d642f498759a6a1e5f9961913b45609c4a3b6..2e5e15850d7aa8c2c8f2ca1eccefa4ddbfc4246e 100644 (file)
@@ -385,16 +385,24 @@ static inline SimdDouble gmx_simdcall frexp(SimdDouble value, SimdDInt32* expone
     svint64_t         iExponent;
 
     iExponent = svand_s64_x(pg, svreinterpret_s64_f64(value.simdInternal_), exponentMask);
-    // iExponent               = svsub_s64_x(pg, svlsr_n_s64_x(pg, iExponent, 52), exponentBias);
     iExponent = svsub_s64_x(
             pg, svreinterpret_s64_u64(svlsr_n_u64_x(pg, svreinterpret_u64_s64(iExponent), 52)), exponentBias);
 
-    exponent->simdInternal_ = iExponent;
 
-    return { svreinterpret_f64_s64(
+    svfloat64_t result = svreinterpret_f64_s64(
             svorr_s64_x(pg,
                         svand_s64_x(pg, svreinterpret_s64_f64(value.simdInternal_), mantissaMask),
-                        svreinterpret_s64_f64(half))) };
+                        svreinterpret_s64_f64(half)));
+
+    if (opt == MathOptimization::Safe)
+    {
+        svbool_t valueIsZero = svcmpeq_n_f64(pg, value.simdInternal_, 0.0);
+        iExponent            = svsel_s64(valueIsZero, svdup_s64(0), iExponent);
+        result               = svsel_f64(valueIsZero, value.simdInternal_, result);
+    }
+
+    exponent->simdInternal_ = iExponent;
+    return { result };
 }
 
 template<MathOptimization opt = MathOptimization::Safe>