]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
RISC-V: fmax/fmin: Handle signalling NaNs correctly.
authorAndrew Waterman <andrew@sifive.com>
Thu, 22 Feb 2018 19:31:54 +0000 (14:31 -0500)
committerDJ Delorie <dj@redhat.com>
Thu, 22 Feb 2018 19:31:54 +0000 (14:31 -0500)
RISC-V's fmax(sNAN,4) returns 4 but glibc expects it to return qNAN.

* sysdeps/riscv/rvd/s_fmax.c (__fmax): Handle sNaNs correctly.
* sysdeps/riscv/rvd/s_fmin.c (__fmin): Likewise.
* sysdeps/riscv/rvf/s_fmaxf.c (__fmaxf): Likewise.
* sysdeps/riscv/rvf/s_fminf.c (__fminf): Likewise.

ChangeLog
sysdeps/riscv/rvd/s_fmax.c
sysdeps/riscv/rvd/s_fmin.c
sysdeps/riscv/rvf/s_fmaxf.c
sysdeps/riscv/rvf/s_fminf.c

index bb787d65bb1ec53167e01c1871a65db096bd74f7..a9a8a4f5e46b721d5bd7dd883ce5aeb85e82c111 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2018-02-22  Andrew Waterman <andrew@sifive.com>
+
+       * sysdeps/riscv/rvd/s_fmax.c (__fmax): Handle sNaNs correctly.
+       * sysdeps/riscv/rvd/s_fmin.c (__fmin): Likewise.
+       * sysdeps/riscv/rvf/s_fmaxf.c (__fmaxf): Likewise.
+       * sysdeps/riscv/rvf/s_fminf.c (__fminf): Likewise.
+
 2018-02-22  DJ Delorie  <dj@delorie.com>
 
        * sysdeps/riscv/tls-macros.h: Do not initialize $gp.
index ef8f1344ce5a6827cbd3703eefac7878db64291a..22e91bfc4b8e17d3b23acccb492495fac8a4fc1b 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <math.h>
+#include <math_private.h>
 #include <libm-alias-double.h>
 
 double
 __fmax (double x, double y)
 {
-  asm ("fmax.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
-  return x;
+  double res;
+
+  if (__glibc_unlikely ((_FCLASS (x) | _FCLASS (y)) & _FCLASS_SNAN))
+    return x + y;
+  else
+    asm ("fmax.d %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+
+  return res;
 }
 libm_alias_double (__fmax, fmax)
index c6ff24cefb8ad0df4aa0caf8ff42b57e4dd9f00c..7b35230cacd77a5c2bd061d215ecd60cc8ce6088 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <math.h>
+#include <math_private.h>
 #include <libm-alias-double.h>
 
 double
 __fmin (double x, double y)
 {
-  asm ("fmin.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
-  return x;
+  double res;
+
+  if (__glibc_unlikely ((_FCLASS (x) | _FCLASS (y)) & _FCLASS_SNAN))
+    return x + y;
+  else
+    asm ("fmin.d %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+
+  return res;
 }
 libm_alias_double (__fmin, fmin)
index 3293f2f41ca13d87a5e224159e70ecdfc038871f..63f7e3d6648ee9bfc1832ec0b6cc95c28c57ad21 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <math.h>
+#include <math_private.h>
 #include <libm-alias-float.h>
 
 float
 __fmaxf (float x, float y)
 {
-  asm ("fmax.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
-  return x;
+  float res;
+
+  if (__glibc_unlikely ((_FCLASS (x) | _FCLASS (y)) & _FCLASS_SNAN))
+    return x + y;
+  else
+    asm ("fmax.s %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+
+  return res;
 }
 libm_alias_float (__fmax, fmax)
index e4411f04b25c3d542f332d75b88cfff16e6aebe6..82cca4e37d827f44635472757b4de520140e3761 100644 (file)
    <http://www.gnu.org/licenses/>.  */
 
 #include <math.h>
+#include <math_private.h>
 #include <libm-alias-float.h>
 
 float
 __fminf (float x, float y)
 {
-  asm ("fmin.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y));
-  return x;
+  float res;
+
+  if (__glibc_unlikely ((_FCLASS (x) | _FCLASS (y)) & _FCLASS_SNAN))
+    return x + y;
+  else
+    asm ("fmin.s %0, %1, %2" : "=f" (res) : "f" (x), "f" (y));
+
+  return res;
 }
 libm_alias_float (__fmin, fmin)