diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/match.pd | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.x | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-1.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-2.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-3.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-4.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-5.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-6.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-7.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/inf-compare-8.c | 19 |
12 files changed, 185 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d9089b..24fd1b4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-01-09 Joseph Myers <joseph@codesourcery.com> + + PR tree-optimization/64811 + * match.pd: When optimizing comparisons with Inf, avoid + introducing or losing exceptions from comparisons with NaN. + 2018-01-09 Martin Liska <mliska@suse.cz> PR sanitizer/82517 diff --git a/gcc/match.pd b/gcc/match.pd index 915c20f..435125a 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3050,18 +3050,22 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) code = swap_tree_comparison (code); } (switch - /* x > +Inf is always false, if with ignore sNANs. */ + /* x > +Inf is always false, if we ignore NaNs or exceptions. */ (if (code == GT_EXPR - && ! HONOR_SNANS (@0)) + && !(HONOR_NANS (@0) && flag_trapping_math)) { constant_boolean_node (false, type); }) (if (code == LE_EXPR) - /* x <= +Inf is always true, if we don't case about NaNs. */ + /* x <= +Inf is always true, if we don't care about NaNs. */ (if (! HONOR_NANS (@0)) { constant_boolean_node (true, type); } - /* x <= +Inf is the same as x == x, i.e. !isnan(x). */ - (eq @0 @0))) - /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX. */ - (if (code == EQ_EXPR || code == GE_EXPR) + /* x <= +Inf is the same as x == x, i.e. !isnan(x), but this loses + an "invalid" exception. */ + (if (!flag_trapping_math) + (eq @0 @0)))) + /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX, but + for == this introduces an exception for x a NaN. */ + (if ((code == EQ_EXPR && !(HONOR_NANS (@0) && flag_trapping_math)) + || code == GE_EXPR) (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); } (if (neg) (lt @0 { build_real (TREE_TYPE (@0), max); }) @@ -3072,7 +3076,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (neg) (ge @0 { build_real (TREE_TYPE (@0), max); }) (le @0 { build_real (TREE_TYPE (@0), max); })))) - /* x != +Inf is always equal to !(x > DBL_MAX). */ + /* x != +Inf is always equal to !(x > DBL_MAX), but this introduces + an exception for x a NaN so use an unordered comparison. */ (if (code == NE_EXPR) (with { real_maxval (&max, neg, TYPE_MODE (TREE_TYPE (@0))); } (if (! HONOR_NANS (@0)) @@ -3080,10 +3085,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (ge @0 { build_real (TREE_TYPE (@0), max); }) (le @0 { build_real (TREE_TYPE (@0), max); })) (if (neg) - (bit_xor (lt @0 { build_real (TREE_TYPE (@0), max); }) - { build_one_cst (type); }) - (bit_xor (gt @0 { build_real (TREE_TYPE (@0), max); }) - { build_one_cst (type); })))))))))) + (unge @0 { build_real (TREE_TYPE (@0), max); }) + (unle @0 { build_real (TREE_TYPE (@0), max); })))))))))) /* If this is a comparison of a real constant with a PLUS_EXPR or a MINUS_EXPR of a real constant, we can convert it into a diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7f90a43..679b22a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2018-01-09 Joseph Myers <joseph@codesourcery.com> + + PR tree-optimization/64811 + * gcc.dg/torture/inf-compare-1.c, gcc.dg/torture/inf-compare-2.c, + gcc.dg/torture/inf-compare-3.c, gcc.dg/torture/inf-compare-4.c, + gcc.dg/torture/inf-compare-5.c, gcc.dg/torture/inf-compare-6.c, + gcc.dg/torture/inf-compare-7.c, gcc.dg/torture/inf-compare-8.c: + New tests. + * gcc.c-torture/execute/ieee/fp-cmp-7.x: New file. + 2018-01-09 Georg-Johann Lay <avr@gjlay.de> PR target/79883 diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.x b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.x new file mode 100644 index 0000000..35f7a0a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/fp-cmp-7.x @@ -0,0 +1,2 @@ +lappend additional_flags "-fno-trapping-math" +return 0 diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-1.c b/gcc/testsuite/gcc.dg/torture/inf-compare-1.c new file mode 100644 index 0000000..0f45108 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-1.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x > __builtin_inf (); + if (i != 0 || !fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-2.c b/gcc/testsuite/gcc.dg/torture/inf-compare-2.c new file mode 100644 index 0000000..ba73395 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-2.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x < -__builtin_inf (); + if (i != 0 || !fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-3.c b/gcc/testsuite/gcc.dg/torture/inf-compare-3.c new file mode 100644 index 0000000..e545d3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-3.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x <= __builtin_inf (); + if (i != 0 || !fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-4.c b/gcc/testsuite/gcc.dg/torture/inf-compare-4.c new file mode 100644 index 0000000..fca6cbf --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-4.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x >= -__builtin_inf (); + if (i != 0 || !fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-5.c b/gcc/testsuite/gcc.dg/torture/inf-compare-5.c new file mode 100644 index 0000000..d7f17e7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-5.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x == __builtin_inf (); + if (i != 0 || fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-6.c b/gcc/testsuite/gcc.dg/torture/inf-compare-6.c new file mode 100644 index 0000000..2dd862b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-6.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x == -__builtin_inf (); + if (i != 0 || fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-7.c b/gcc/testsuite/gcc.dg/torture/inf-compare-7.c new file mode 100644 index 0000000..36676b4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-7.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x != __builtin_inf (); + if (i != 1 || fetestexcept (FE_INVALID)) + abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/inf-compare-8.c b/gcc/testsuite/gcc.dg/torture/inf-compare-8.c new file mode 100644 index 0000000..cfda813 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/inf-compare-8.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target fenv_exceptions } */ + +#include <fenv.h> + +extern void abort (void); +extern void exit (int); + +volatile double x = __builtin_nan (""); +volatile int i; + +int +main (void) +{ + i = x != -__builtin_inf (); + if (i != 1 || fetestexcept (FE_INVALID)) + abort (); +} |