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.
This commit is contained in:
Andrew Waterman 2018-02-22 14:31:54 -05:00 committed by DJ Delorie
parent 8090720a87
commit fdcc625376
5 changed files with 43 additions and 8 deletions

View File

@ -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> 2018-02-22 DJ Delorie <dj@delorie.com>
* sysdeps/riscv/tls-macros.h: Do not initialize $gp. * sysdeps/riscv/tls-macros.h: Do not initialize $gp.

View File

@ -17,12 +17,19 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <math.h> #include <math.h>
#include <math_private.h>
#include <libm-alias-double.h> #include <libm-alias-double.h>
double double
__fmax (double x, double y) __fmax (double x, double y)
{ {
asm ("fmax.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y)); double res;
return x;
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) libm_alias_double (__fmax, fmax)

View File

@ -17,12 +17,19 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <math.h> #include <math.h>
#include <math_private.h>
#include <libm-alias-double.h> #include <libm-alias-double.h>
double double
__fmin (double x, double y) __fmin (double x, double y)
{ {
asm ("fmin.d %0, %1, %2" : "=f" (x) : "f" (x), "f" (y)); double res;
return x;
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) libm_alias_double (__fmin, fmin)

View File

@ -17,12 +17,19 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <math.h> #include <math.h>
#include <math_private.h>
#include <libm-alias-float.h> #include <libm-alias-float.h>
float float
__fmaxf (float x, float y) __fmaxf (float x, float y)
{ {
asm ("fmax.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y)); float res;
return x;
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) libm_alias_float (__fmax, fmax)

View File

@ -17,12 +17,19 @@
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <math.h> #include <math.h>
#include <math_private.h>
#include <libm-alias-float.h> #include <libm-alias-float.h>
float float
__fminf (float x, float y) __fminf (float x, float y)
{ {
asm ("fmin.s %0, %1, %2" : "=f" (x) : "f" (x), "f" (y)); float res;
return x;
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) libm_alias_float (__fmin, fmin)