diff --git a/gcc/match.pd b/gcc/match.pd index 10ff867e854..7bbb80172fc 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -256,10 +256,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Maybe fold x * 0 to 0. The expressions aren't the same when x is NaN, since x * 0 is also NaN. Nor are they the same in modes with signed zeros, since multiplying a - negative value by 0 gives -0, not +0. */ + negative value by 0 gives -0, not +0. Nor when x is +-Inf, + since x * 0 is NaN. */ (simplify (mult @0 real_zerop@1) (if (!tree_expr_maybe_nan_p (@0) + && (!HONOR_NANS (type) || !tree_expr_maybe_infinite_p (@0)) && !tree_expr_maybe_real_minus_zero_p (@0) && !tree_expr_maybe_real_minus_zero_p (@1)) @1)) diff --git a/gcc/testsuite/gcc.dg/pr104389.c b/gcc/testsuite/gcc.dg/pr104389.c new file mode 100644 index 00000000000..0c6c85a4f48 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104389.c @@ -0,0 +1,26 @@ +/* PR tree-optimization/104389 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target inf } */ + +__attribute__((noipa)) double +foo (void) +{ + double a = __builtin_huge_val (); + return a * 0.0; +} + +__attribute__((noipa)) long double +bar (void) +{ + return __builtin_huge_vall () * 0.0L; +} + +int +main () +{ + if (!__builtin_isnan (foo ()) || !__builtin_isnanl (bar ())) + __builtin_abort (); + return 0; +}