+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
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); })
(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))
(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
+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
--- /dev/null
+lappend additional_flags "-fno-trapping-math"
+return 0
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+/* { 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 ();
+}