Hi Richard,
> > This is my proposed solution to PR middle-end/123826. Initially I
> > thought this would be a "one line change", adding a test for
> > flag_errno_math to gimple_expand_builtin_pow. Unfortunately this
> > revealed a second later problem, where pow (with constant
> > arguments) was still getting evaluated at compile-time, even when the
> > result is known to overflow.
> >
> > It's ancient history, but shortly after I added support for pow as a
> > builtin, I contributed code to evaluate it at compile-time when the
> > exponent is an integer constant. Since then we now use MPFR to
> > evaluate libm math functions at compile-time. However the vestigial
> > call to evaluate pow via real_powi still exists, and gets invoked
> > after do_mpfr_arg2/mpfr_pow correctly determines that we shouldn't
> > evaluate pow at compile-time. This patch reorganizes fold_const_pow
> > paying attention to signaling NaNs (PR 61441) and flag_errno_math.
> > Most importantly normal cases like pow(2.0,3.0) and pow(3.0,0.5) still
> > get evaluated at compile-time.
> >
> > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
> > and make -k check, both with and without --target_board=unix{-m32},
> > with no new failures. Ok for mainline?
>
> I think the testcases need to check math_errhandling & MATH_ERRNO otherwise
> BSDs will likely runfail the testcases.
Many thanks for the review, and pointing me to C99's math_errhandling.
For the record, the idiom that I went with [which alas is still a test of the
system's libm implementation] looks like:
/* 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
The __NO_MATH_ERRNO__ test checks GCC's predefined macro, as set by
-fno-math-errno, and can be used by targets/backends that don’t have errno.h.
c99's math_errhandling is allowed to call a function, so it's a run-time test
on
platforms that support it. Platforms that define math_errhandling should also
define MATH_ERRNO (to 1), but a little paranoia can't hurt.
I've no doubt someone somewhere might need an xfail (which is why I split
the pow and powf test cases just in case these behave differently).
> Other than that, OK.
Thanks, pushed.
>
> I did think of making use of frange in gimple_expand_builtin_pow, but I
> suspect
> overflow and underflow are difficult to check for and it's probably not worth
> the
> trouble.
>
> Thanks,
> Richard.
>
> >
> > 2026-02-02 Roger Sayle <[email protected]>
> >
> > gcc/ChangeLog
> > PR middle-end/123826
> > * tree-ssa-math-opts.cc (gimple_expand_builtin_pow): Add test
> > for flag_errno_math.
> > * fold-const-call.cc (fold_const_pow): Reorganize, eliminating
> > call to real_powi, and letting do_mpfr_arg2 do all the heavy
> > lifting.
> >
> > gcc/testsuite/ChangeLog
> > PR middle-end/123826
> > * gcc.dg/errno-2.c: New test case.
> > * gcc.dg/errno-3.c: Likewise.
> >