fold_const_pow (real_value *result, const real_value *arg0,
const real_value *arg1, const real_format *format)
{
+ if (flag_signaling_nans
+ && (REAL_VALUE_ISSIGNALING_NAN (*arg0)
+ || REAL_VALUE_ISSIGNALING_NAN (*arg1)))
+ return false;
+
if (do_mpfr_arg2 (result, mpfr_pow, arg0, arg1, format))
- return true;
-
- /* Check for an integer exponent. */
- REAL_VALUE_TYPE cint1;
- HOST_WIDE_INT n1 = real_to_integer (arg1);
- real_from_integer (&cint1, VOIDmode, n1, SIGNED);
- /* Attempt to evaluate pow at compile-time, unless this should
- raise an exception. */
- if (real_identical (arg1, &cint1)
- && (n1 > 0
- || (!flag_trapping_math && !flag_errno_math)
- || !real_equal (arg0, &dconst0)))
{
- bool inexact = real_powi (result, format, arg0, n1);
- /* Avoid the folding if flag_signaling_nans is on. */
- if (flag_unsafe_math_optimizations
- || (!inexact
- && !(flag_signaling_nans
- && REAL_VALUE_ISSIGNALING_NAN (*arg0))))
- return true;
+ if (flag_errno_math)
+ switch (result->cl)
+ {
+ case rvc_inf:
+ case rvc_nan:
+ return false;
+ case rvc_zero:
+ return arg0->cl == rvc_zero;
+ default:
+ break;
+ }
+ return true;
}
return false;
--- /dev/null
+/* PR middle-end/123826 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#ifdef __NO_MATH_ERRNO__
+int main() { return 0; }
+#else
+#include <errno.h>
+#include <float.h>
+#include <math.h>
+
+double foo(double x)
+{
+ return pow(x, 2.0);
+}
+
+int main()
+{
+#ifdef math_errhandling
+#ifdef MATH_ERRNO
+ if ((math_errhandling & MATH_ERRNO) == 0)
+ return 0;
+#else
+ if ((math_errhandling & 1) == 0)
+ return 0;
+#endif
+#endif
+
+ errno = 0;
+ double x = foo(DBL_MAX);
+ if (errno != ERANGE)
+ __builtin_abort ();
+ return 0;
+}
+#endif
--- /dev/null
+/* PR middle-end/123826 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#ifdef __NO_MATH_ERRNO__
+int main() { return 0; }
+#else
+#include <errno.h>
+#include <float.h>
+#include <math.h>
+
+float foo(float x)
+{
+ return powf(x, 2.0f);
+}
+
+int main()
+{
+#ifdef math_errhandling
+#ifdef MATH_ERRNO
+ if ((math_errhandling & MATH_ERRNO) == 0)
+ return 0;
+#else
+ if ((math_errhandling & 1) == 0)
+ return 0;
+#endif
+#endif
+
+ errno = 0;
+ float x = foo(FLT_MAX);
+ if (errno != ERANGE)
+ __builtin_abort ();
+ return 0;
+}
+#endif
|| REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1))))
return NULL_TREE;
+ if (flag_errno_math)
+ return NULL_TREE;
+
/* If the exponent is equivalent to an integer, expand to an optimal
multiplication sequence when profitable. */
c = TREE_REAL_CST (arg1);