From: Andrew Waterman Date: Thu, 22 Feb 2018 19:31:54 +0000 (-0500) Subject: RISC-V: fmax/fmin: Handle signalling NaNs correctly. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aab08776cc8f6dbafaa6efcb7e1bb374a21ab823;p=thirdparty%2Fglibc.git 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) --- diff --git a/ChangeLog b/ChangeLog index 8b859f637d6..394f6703638 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2018-02-22 Andrew Waterman + + * 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 * 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 ef8f1344ce5..22e91bfc4b8 100644 --- a/sysdeps/riscv/rvd/s_fmax.c +++ b/sysdeps/riscv/rvd/s_fmax.c @@ -17,12 +17,19 @@ . */ #include +#include #include 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 c6ff24cefb8..7b35230cacd 100644 --- a/sysdeps/riscv/rvd/s_fmin.c +++ b/sysdeps/riscv/rvd/s_fmin.c @@ -17,12 +17,19 @@ . */ #include +#include #include 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 3293f2f41ca..63f7e3d6648 100644 --- a/sysdeps/riscv/rvf/s_fmaxf.c +++ b/sysdeps/riscv/rvf/s_fmaxf.c @@ -17,12 +17,19 @@ . */ #include +#include #include 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 e4411f04b25..82cca4e37d8 100644 --- a/sysdeps/riscv/rvf/s_fminf.c +++ b/sysdeps/riscv/rvf/s_fminf.c @@ -17,12 +17,19 @@ . */ #include +#include #include 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)