fold-const: do not fold NaN result from non-NaN operands [PR95115]

These operations should raise an invalid operation exception at runtime.
So they should not be folded during compilation unless -fno-trapping-math
is used.

gcc/
	PR middle-end/95115
	* fold-const.cc (const_binop): Do not fold NaN result from
	  non-NaN operands.

gcc/testsuite
	* gcc.dg/pr95115.c: New test.
This commit is contained in:
Xi Ruoyao 2022-01-31 01:15:20 +08:00
parent d43fbc7d3f
commit 34afa19d29
No known key found for this signature in database
GPG Key ID: D95E4716CCBB34DC
2 changed files with 36 additions and 0 deletions

View File

@ -1305,6 +1305,17 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
inexact = real_arithmetic (&value, code, &d1, &d2);
real_convert (&result, mode, &value);
/* Don't constant fold this floating point operation if
both operands are not NaN but the result is NaN, and
flag_trapping_math. Such operations should raise an
invalid operation exception. */
if (flag_trapping_math
&& MODE_HAS_NANS (mode)
&& REAL_VALUE_ISNAN (result)
&& !REAL_VALUE_ISNAN (d1)
&& !REAL_VALUE_ISNAN (d2))
return NULL_TREE;
/* Don't constant fold this floating point operation if
the result has overflowed and flag_trapping_math. */
if (flag_trapping_math

View File

@ -0,0 +1,25 @@
/* { dg-do run } */
/* { dg-options "-O2 -ftrapping-math" } */
/* { dg-add-options ieee } */
/* { dg-require-effective-target fenv_exceptions } */
#include <fenv.h>
#include <stdlib.h>
double
x (void)
{
double d = __builtin_inf ();
return d / d;
}
int
main (void)
{
double r = x ();
if (!__builtin_isnan (r))
abort ();
if (!fetestexcept (FE_INVALID))
abort ();
exit (0);
}