From 70b81845bf34a1bea7f82e9245fa7482edeb34b6 Mon Sep 17 00:00:00 2001 From: Janis Johnson Date: Tue, 16 Jan 2007 18:53:16 +0000 Subject: [PATCH] dfp-bit.c (dfp_compare_op): Return separate value for NaN. gcc/ * config/dfp-bit.c (dfp_compare_op): Return separate value for NaN. (DFP_NE, DFP_LE, DFP_GE): Return false for NaN. gcc/testsuite/ * gcc.dg/dfp/compare-special.h: New file. * gcc.dg/dfp/compare-special-32.c: New test. * gcc.dg/dfp/compare-special-64.c: New test. * gcc.dg/dfp/compare-special-128.c: New test. From-SVN: r120830 --- gcc/ChangeLog | 5 + gcc/config/dfp-bit.c | 10 +- gcc/testsuite/ChangeLog | 7 + .../gcc.dg/dfp/compare-special-d128.c | 15 + .../gcc.dg/dfp/compare-special-d32.c | 15 + .../gcc.dg/dfp/compare-special-d64.c | 15 + gcc/testsuite/gcc.dg/dfp/compare-special.h | 287 ++++++++++++++++++ 7 files changed, 353 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special-d128.c create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special-d32.c create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special-d64.c create mode 100644 gcc/testsuite/gcc.dg/dfp/compare-special.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cf4cd24f51d..80e90935bbd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2007-01-16 Janis Johnson + + * config/dfp-bit.c (dfp_compare_op): Return separate value for NaN. + (DFP_NE, DFP_LE, DFP_GE): Return false for NaN. + 2007-01-16 David Edelsohn * config/rs6000/darwin-ldouble.c: Build file for SOFT_FLOAT. diff --git a/gcc/config/dfp-bit.c b/gcc/config/dfp-bit.c index 0ee2083e835..47575ccc8b7 100644 --- a/gcc/config/dfp-bit.c +++ b/gcc/config/dfp-bit.c @@ -146,6 +146,8 @@ dfp_compare_op (dfp_binary_func op, DFP_C_TYPE arg_a, DFP_C_TYPE arg_b) result = -1; else if (decNumberIsZero (&res)) result = 0; + else if (decNumberIsNaN (&res)) + result = -2; else result = 1; @@ -302,7 +304,9 @@ DFP_NE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b) { int stat; stat = dfp_compare_op (decNumberCompare, arg_a, arg_b); - /* For NE return nonzero for true, zero for false. */ + /* For NE return zero for true, nonzero for false. */ + if (__builtin_expect (stat == -2, 0)) /* An operand is NaN. */ + return 1; return stat != 0; } #endif /* L_ne */ @@ -336,6 +340,8 @@ DFP_LE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b) int stat; stat = dfp_compare_op (decNumberCompare, arg_a, arg_b); /* For LE return 0 (<= 0) for true, 1 for false. */ + if (__builtin_expect (stat == -2, 0)) /* An operand is NaN. */ + return 1; return stat == 1; } #endif /* L_le */ @@ -347,6 +353,8 @@ DFP_GE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b) int stat; stat = dfp_compare_op (decNumberCompare, arg_a, arg_b); /* For GE return 1 (>=0) for true, -1 for false. */ + if (__builtin_expect (stat == -2, 0)) /* An operand is NaN. */ + return -1; return (stat != -1) ? 1 : -1; } #endif /* L_ge */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5d3374783bb..b098046ddbc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2007-01-16 Janis Johnson + + * gcc.dg/dfp/compare-special.h: New file. + * gcc.dg/dfp/compare-special-32.c: New test. + * gcc.dg/dfp/compare-special-64.c: New test. + * gcc.dg/dfp/compare-special-128.c: New test. + 2007-01-16 Roger Sayle Paul Thomas Steven G. Kargl diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c new file mode 100644 index 00000000000..cef4670b766 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d128.c @@ -0,0 +1,15 @@ +/* { dg-options "-std=gnu99 -O0" } */ + +/* C99 6.5.8 Relational operators. + C99 6.5.9 Equality operators. + Compare decimal float special values at runtime. */ + +#define WIDTH 128 +#include "compare-special.h" + +int +main () +{ + test_compares (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c new file mode 100644 index 00000000000..fa91d7edd33 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d32.c @@ -0,0 +1,15 @@ +/* { dg-options "-std=gnu99 -O0" } */ + +/* C99 6.5.8 Relational operators. + C99 6.5.9 Equality operators. + Compare decimal float special values at runtime. */ + +#define WIDTH 32 +#include "compare-special.h" + +int +main () +{ + test_compares (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c b/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c new file mode 100644 index 00000000000..2238e0190e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/compare-special-d64.c @@ -0,0 +1,15 @@ +/* { dg-options "-std=gnu99 -O0" } */ + +/* C99 6.5.8 Relational operators. + C99 6.5.9 Equality operators. + Compare decimal float special values at runtime. */ + +#define WIDTH 64 +#include "compare-special.h" + +int +main () +{ + test_compares (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/dfp/compare-special.h b/gcc/testsuite/gcc.dg/dfp/compare-special.h new file mode 100644 index 00000000000..1bd77e52156 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/compare-special.h @@ -0,0 +1,287 @@ +/* Basic test of runtime relational comparisons using NaNs and infinities. */ + +#include + +static int failcnt; + +#define PASTE2(A,B) A ## B +#define PASTE(A,B) PASTE2(A,B) + +#ifdef DBG +#include +#define FAILURE(OP,KIND) \ + { printf ("failed at line %d: %s for %s values\n", __LINE__, OP, KIND); \ + failcnt++; } +#else +#define FAILURE(OP,KIND) abort (); +#endif + +#ifndef WIDTH +#error define WIDTH as decimal float size in bytes +#endif + +#if WIDTH == 32 +#define DTYPE _Decimal32 +#define SUFFIX DF +#define SUFFIX2 d32 +#elif WIDTH == 64 +#define DTYPE _Decimal64 +#define SUFFIX DD +#define SUFFIX2 d64 +#elif WIDTH == 128 +#define DTYPE _Decimal128 +#define SUFFIX DL +#define SUFFIX2 d128 +#elif WIDTH == 0 +/* This is for testing the test using a type known to work. */ +#define DTYPE double +#define SUFFIX +#define SUFFIX2 +#else +#error invalid width for decimal float type +#endif + +DTYPE m_two = PASTE(-2.0, SUFFIX); +DTYPE m_one = PASTE(-1.0, SUFFIX); +DTYPE zero = PASTE(0.0, SUFFIX); +DTYPE one = PASTE(1.0, SUFFIX); +DTYPE two = PASTE(2.0, SUFFIX); + +volatile DTYPE x, y, z, nan, inf, m_inf; + +void +test_compares (void) +{ + nan = PASTE(__builtin_nan, SUFFIX2) (""); + inf = PASTE(__builtin_inf, SUFFIX2) (); + m_inf = - PASTE(__builtin_inf, SUFFIX2) (); + + x = PASTE(__builtin_nan, SUFFIX2) (""); + y = PASTE(__builtin_inf, SUFFIX2) (); + z = - PASTE(__builtin_inf, SUFFIX2) (); + + /* Less than or equal to with NaN. */ + + if (x <= two) FAILURE ("<=", "NaN") + if (x <= zero) FAILURE ("<=", "NaN") + if (x <= m_one) FAILURE ("<=", "NaN") + if (x <= nan) FAILURE ("<=", "NaN") + if (x <= inf) FAILURE ("<=", "NaN") + if (x <= m_inf) FAILURE ("<=", "NaN") + + if (two <= x) FAILURE ("<=", "NaN") + if (zero <= x) FAILURE ("<=", "NaN") + if (m_one <= x) FAILURE ("<=", "NaN") + if (nan <= x) FAILURE ("<=", "NaN") + if (inf <= x) FAILURE ("<=", "NaN") + if (m_inf <= x) FAILURE ("<=", "NaN") + + /* Less than or equal to with infinities, no NaNs. */ + + if (y <= two) FAILURE ("<=", "inf") + if (y <= zero) FAILURE ("<=", "inf") + if (y <= m_one) FAILURE ("<=", "inf") + if (!(two <= y)) FAILURE ("<=", "inf") + if (!(zero <= y)) FAILURE ("<=", "inf") + if (!(m_one <= y)) FAILURE ("<=", "inf") + + if (!(z <= two)) FAILURE ("<=", "-inf") + if (!(z <= zero)) FAILURE ("<=", "-inf") + if (!(z <= m_one)) FAILURE ("<=", "-inf") + if (two <= z) FAILURE ("<=", "-inf") + if (zero <= z) FAILURE ("<=", "-inf") + if (m_one <= z) FAILURE ("<=", "-inf") + + if (!(y <= inf)) FAILURE ("<=", "inf") + if (y <= m_inf) FAILURE ("<=", "inf") + if (!(z <= inf)) FAILURE ("<=", "inf") + if (!(z <= m_inf)) FAILURE ("<=", "inf") + + /* Less than with NaN. */ + + if (x < two) FAILURE ("<", "NaN") + if (x < zero) FAILURE ("<", "NaN") + if (x < m_one) FAILURE ("<", "NaN") + if (x < nan) FAILURE ("<", "NaN") + if (x < inf) FAILURE ("<", "NaN") + if (x < m_inf) FAILURE ("<", "NaN") + + if (two < x) FAILURE ("<", "NaN") + if (zero < x) FAILURE ("<", "NaN") + if (m_one < x) FAILURE ("<", "NaN") + if (nan < x) FAILURE ("<", "NaN") + if (inf < x) FAILURE ("<", "NaN") + if (m_inf < x) FAILURE ("<", "NaN") + + /* Less than with infinities, no NaNs. */ + + if (y < two) FAILURE ("<", "inf") + if (y < zero) FAILURE ("<", "inf") + if (y < m_one) FAILURE ("<", "inf") + if (!(two < y)) FAILURE ("<", "inf") + if (!(zero < y)) FAILURE ("<", "inf") + if (!(m_one < y)) FAILURE ("<", "inf") + + if (!(z < two)) FAILURE ("<", "-inf") + if (!(z < zero)) FAILURE ("<", "-inf") + if (!(z < m_one)) FAILURE ("<", "-inf") + if (two < z) FAILURE ("<", "-inf") + if (zero < z) FAILURE ("<", "-inf") + if (m_one < z) FAILURE ("<", "-inf") + + if (y < inf) FAILURE ("<=", "inf") + if (y < m_inf) FAILURE ("<=", "inf") + if (!(z < inf)) FAILURE ("<=", "inf") + if (z < m_inf) FAILURE ("<=", "inf") + + /* Greater than or equal to with NaN. */ + + if (x >= two) FAILURE (">=", "NaN") + if (x >= zero) FAILURE (">=", "NaN") + if (x >= m_one) FAILURE (">=", "NaN") + if (x >= nan) FAILURE (">=", "NaN") + if (x >= inf) FAILURE (">=", "NaN") + if (x >= m_inf) FAILURE (">=", "NaN") + + if (two >= x) FAILURE (">=", "NaN") + if (zero >= x) FAILURE (">=", "NaN") + if (m_one >= x) FAILURE (">=", "NaN") + if (nan >= x) FAILURE (">=", "NaN") + if (inf >= x) FAILURE (">=", "NaN") + if (m_inf >= x) FAILURE (">=", "NaN") + + /* Greater than or equal to with infinities, no NaNs. */ + + if (!(y >= two)) FAILURE (">=", "inf") + if (!(y >= zero)) FAILURE (">=", "inf") + if (!(y >= m_one)) FAILURE (">=", "inf") + if (two >= y) FAILURE (">=", "inf") + if (zero >= y) FAILURE (">=", "inf") + if (m_one >= y) FAILURE (">=", "inf") + + if (z >= two) FAILURE (">=", "-inf") + if (z >= zero) FAILURE (">=", "-inf") + if (z >= m_one) FAILURE (">=", "-inf") + if (!(two >= z)) FAILURE (">=", "-inf") + if (!(zero >= z)) FAILURE (">=", "-inf") + if (!(m_one >= z)) FAILURE (">=", "-inf") + + if (!(y >= inf)) FAILURE ("<=", "inf") + if (!(y >= m_inf)) FAILURE ("<=", "inf") + if (z >= inf) FAILURE ("<=", "inf") + if (!(z >= m_inf)) FAILURE ("<=", "inf") + + /* Greater than with NaN. */ + + if (x > two) FAILURE (">", "NaN") + if (x > zero) FAILURE (">", "NaN") + if (x > m_one) FAILURE (">", "NaN") + if (x > nan) FAILURE (">", "NaN") + if (x > inf) FAILURE (">", "NaN") + if (x > m_inf) FAILURE (">", "NaN") + + if (two > x) FAILURE (">", "NaN") + if (zero > x) FAILURE (">", "NaN") + if (m_one > x) FAILURE (">", "NaN") + if (nan > x) FAILURE (">", "NaN") + if (inf > x) FAILURE (">", "NaN") + if (m_inf > x) FAILURE (">", "NaN") + + /* Greater than with infinities, no NaNs. */ + + if (!(y > two)) FAILURE (">", "inf") + if (!(y > zero)) FAILURE (">", "inf") + if (!(y > m_one)) FAILURE (">", "inf") + if (two > y) FAILURE (">", "inf") + if (zero > y) FAILURE (">", "inf") + if (m_one > y) FAILURE (">", "inf") + + if (z > two) FAILURE (">", "-inf") + if (z > zero) FAILURE (">", "-inf") + if (z > m_one) FAILURE (">", "-inf") + if (!(two > z)) FAILURE (">", "-inf") + if (!(zero > z)) FAILURE (">", "-inf") + if (!(m_one > z)) FAILURE (">", "-inf") + + if (y > inf) FAILURE (">", "inf") + if (!(y > m_inf)) FAILURE (">", "inf") + if (z > inf) FAILURE (">", "inf") + if (z > m_inf) FAILURE (">", "inf") + + /* Equal with NaN. */ + + if (x == two) FAILURE ("==", "NaN") + if (x == zero) FAILURE ("==", "NaN") + if (x == m_one) FAILURE ("==", "NaN") + if (x == nan) FAILURE ("==", "NaN") + if (x == inf) FAILURE ("==", "NaN") + if (x == m_inf) FAILURE ("==", "NaN") + + if (two == x) FAILURE ("==", "NaN") + if (zero == x) FAILURE ("==", "NaN") + if (m_one == x) FAILURE ("==", "NaN") + if (nan == x) FAILURE ("==", "NaN") + if (inf == x) FAILURE ("==", "NaN") + if (m_inf == x) FAILURE ("==", "NaN") + + /* Equal with infinities, no NaNs. */ + + if (y == two) FAILURE ("==", "inf") + if (y == zero) FAILURE ("==", "inf") + if (y == m_one) FAILURE ("==", "inf") + if (two == y) FAILURE ("==", "inf") + if (zero == y) FAILURE ("==", "inf") + if (m_one == y) FAILURE ("==", "inf") + + if (z == two) FAILURE ("==", "-inf") + if (z == zero) FAILURE ("==", "-inf") + if (z == m_one) FAILURE ("==", "-inf") + if (two == z) FAILURE ("==", "-inf") + if (zero == z) FAILURE ("==", "-inf") + if (m_one == z) FAILURE ("==", "-inf") + + if (!(y == inf)) FAILURE ("==", "inf") + if (y == m_inf) FAILURE ("==", "inf") + if (z == inf) FAILURE ("==", "inf") + if (!(z == m_inf)) FAILURE ("==", "inf") + + /* Not equal with NaN. */ + + if (!(x != two)) FAILURE ("!=", "NaN") + if (!(x != zero)) FAILURE ("!=", "NaN") + if (!(x != m_one)) FAILURE ("!=", "NaN") + if (!(x != nan)) FAILURE ("!=", "NaN") + if (!(x != inf)) FAILURE ("!=", "NaN") + if (!(x != m_inf)) FAILURE ("!=", "NaN") + + if (!(two != x)) FAILURE ("!=", "NaN") + if (!(zero != x)) FAILURE ("!=", "NaN") + if (!(m_one != x)) FAILURE ("!=", "NaN") + if (!(nan != x)) FAILURE ("!=", "NaN") + if (!(inf != x)) FAILURE ("!=", "NaN") + if (!(m_inf != x)) FAILURE ("!=", "NaN") + + /* Not equal with infinities, no NaNs. */ + + if (!(y != two)) FAILURE ("!=", "inf") + if (!(y != zero)) FAILURE ("!=", "inf") + if (!(y != m_one)) FAILURE ("!=", "inf") + if (!(two != y)) FAILURE ("!=", "inf") + if (!(zero != y)) FAILURE ("!=", "inf") + if (!(m_one != y)) FAILURE ("!=", "inf") + + if (!(z != two)) FAILURE ("!=", "-inf") + if (!(z != zero)) FAILURE ("!=", "-inf") + if (!(z != m_one)) FAILURE ("!=", "-inf") + if (!(two != z)) FAILURE ("!=", "-inf") + if (!(zero != z)) FAILURE ("!=", "-inf") + if (!(m_one != z)) FAILURE ("!=", "-inf") + + if (y != inf) FAILURE ("!=", "inf") + if (!(y != m_inf)) FAILURE ("!=", "inf") + if (!(z != inf)) FAILURE ("!=", "inf") + if (z != m_inf) FAILURE ("!=", "inf") + + if (failcnt) + abort (); +}