diff --git a/gcc/match.pd b/gcc/match.pd index 097ed2e5dff..a063a1577b5 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4482,9 +4482,20 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* a CMP (-0) -> a CMP 0 */ (if (REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@1))) (cmp @0 { build_real (TREE_TYPE (@1), dconst0); })) + /* (-0) CMP b -> 0 CMP b. */ + (if (TREE_CODE (@0) == REAL_CST + && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (@0))) + (cmp { build_real (TREE_TYPE (@0), dconst0); } @1)) /* x != NaN is always true, other ops are always false. */ (if (REAL_VALUE_ISNAN (TREE_REAL_CST (@1)) - && ! HONOR_SNANS (@1)) + && !tree_expr_signaling_nan_p (@1) + && !tree_expr_maybe_signaling_nan_p (@0)) + { constant_boolean_node (cmp == NE_EXPR, type); }) + /* NaN != y is always true, other ops are always false. */ + (if (TREE_CODE (@0) == REAL_CST + && REAL_VALUE_ISNAN (TREE_REAL_CST (@0)) + && !tree_expr_signaling_nan_p (@0) + && !tree_expr_signaling_nan_p (@1)) { constant_boolean_node (cmp == NE_EXPR, type); }) /* Fold comparisons against infinity. */ (if (REAL_VALUE_ISINF (TREE_REAL_CST (@1)) diff --git a/gcc/testsuite/c-c++-common/pr57371-4.c b/gcc/testsuite/c-c++-common/pr57371-4.c index f43f7c22419..d938ecdd675 100644 --- a/gcc/testsuite/c-c++-common/pr57371-4.c +++ b/gcc/testsuite/c-c++-common/pr57371-4.c @@ -13,25 +13,25 @@ void nonfinite(unsigned short x) { { volatile int nonfinite_1; nonfinite_1 = (float) x > QNAN; - /* { dg-final { scan-tree-dump "nonfinite_1 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_1 = 0" "original" } } */ } { volatile int nonfinite_2; nonfinite_2 = (float) x >= QNAN; - /* { dg-final { scan-tree-dump "nonfinite_2 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_2 = 0" "original" } } */ } { volatile int nonfinite_3; nonfinite_3 = (float) x < QNAN; - /* { dg-final { scan-tree-dump "nonfinite_3 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_3 = 0" "original" } } */ } { volatile int nonfinite_4; nonfinite_4 = (float) x <= QNAN; - /* { dg-final { scan-tree-dump "nonfinite_4 = \\(float\\)" "original" } } */ + /* { dg-final { scan-tree-dump "nonfinite_4 = 0" "original" } } */ } { diff --git a/gcc/testsuite/g++.dg/pr88173-1.C b/gcc/testsuite/g++.dg/pr88173-1.C new file mode 100644 index 00000000000..08fcf97ff16 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr88173-1.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -std=c++11" } */ + +#define big __builtin_huge_val() +#define nan __builtin_nan("") + +constexpr bool b1 = big > nan; +constexpr bool b2 = nan < big; + diff --git a/gcc/testsuite/g++.dg/pr88173-2.C b/gcc/testsuite/g++.dg/pr88173-2.C new file mode 100644 index 00000000000..aa7d7849913 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr88173-2.C @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsignaling-nans -std=c++11" } */ + +#define big __builtin_huge_val() +#define nan __builtin_nan("") + +constexpr bool b1 = big > nan; +constexpr bool b2 = nan < big; +