diff options
author | Andrew Waterman <andrew@sifive.com> | 2018-02-22 14:31:54 -0500 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2021-08-27 16:22:07 -0700 |
commit | 012483cf93fd62162233a9d1be1879c664dd149a (patch) | |
tree | 41351f0919529028d0967f3e72f804d074c2f0b1 | |
parent | ab9c19649286b0826d4f067de8aec76ad7e58114 (diff) | |
download | glibc-012483cf93fd62162233a9d1be1879c664dd149a.zip glibc-012483cf93fd62162233a9d1be1879c664dd149a.tar.gz glibc-012483cf93fd62162233a9d1be1879c664dd149a.tar.bz2 |
RISC-V: fmax/fmin: Handle signalling NaNs correctly.
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.
(cherry picked from commit fdcc625376505eacb1125a6aeba57501407a30ec)
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | sysdeps/riscv/rvd/s_fmax.c | 11 | ||||
-rw-r--r-- | sysdeps/riscv/rvd/s_fmin.c | 11 | ||||
-rw-r--r-- | sysdeps/riscv/rvf/s_fmaxf.c | 11 | ||||
-rw-r--r-- | sysdeps/riscv/rvf/s_fminf.c | 11 |
5 files changed, 43 insertions, 8 deletions
@@ -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. diff --git a/sysdeps/riscv/rvd/s_fmax.c b/sysdeps/riscv/rvd/s_fmax.c index ef8f134..22e91bf 100644 --- a/sysdeps/riscv/rvd/s_fmax.c +++ b/sysdeps/riscv/rvd/s_fmax.c @@ -17,12 +17,19 @@ <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) diff --git a/sysdeps/riscv/rvd/s_fmin.c b/sysdeps/riscv/rvd/s_fmin.c index c6ff24c..7b35230 100644 --- a/sysdeps/riscv/rvd/s_fmin.c +++ b/sysdeps/riscv/rvd/s_fmin.c @@ -17,12 +17,19 @@ <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) diff --git a/sysdeps/riscv/rvf/s_fmaxf.c b/sysdeps/riscv/rvf/s_fmaxf.c index 3293f2f..63f7e3d 100644 --- a/sysdeps/riscv/rvf/s_fmaxf.c +++ b/sysdeps/riscv/rvf/s_fmaxf.c @@ -17,12 +17,19 @@ <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) diff --git a/sysdeps/riscv/rvf/s_fminf.c b/sysdeps/riscv/rvf/s_fminf.c index e4411f0..82cca4e 100644 --- a/sysdeps/riscv/rvf/s_fminf.c +++ b/sysdeps/riscv/rvf/s_fminf.c @@ -17,12 +17,19 @@ <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) |