builtins.c:expand_errno_check() can only handle setting EDOM if the operation returns NaN on error. Most overflow/underflow conditions result in -Inf/+Inf instead and with non-default rounding-mode (-frounding-math) the maximum or minimum floating-point value will be returned (round to -Inf/+Inf or zero). One testcase: #include <stdio.h> #include <math.h> #include <stdlib.h> int main(int argc, char **argv) { double y = atof(argv[1]); double x = exp (y); printf("%.6e %.6e\n", y, x); perror("errno"); return 0; } which shall print "errno: Numerical result out of range" if you pass 5000 to the testcase executable but prints "errno: Success" if you build with -funsafe-math-optimizations on i686 which will do an inline expansion for exp ().

Hi, Richard. I don't understand completely what you mean. Is the problem in the builtin exp() ? Should it check its argument for large numbers?

The problem is that we believe we can handle all errno checking/setting via the expand_errno_check() routine which is not true for overflow/underflow but only for invalid arguments that result in a NaN.

(In reply to comment #2) > The problem is that we believe we can handle all errno checking/setting via > the expand_errno_check() routine which is not true for overflow/underflow but > only for invalid arguments that result in a NaN. > Is there underflow/overflow if the value is so small/big that we end up with zero/infinite? I am really confused about that. See for example bug 23572.

With overflow we end up with Inf or -Inf, with underflow we end up with 0. (or even -0.?) - but underflow doesn't seem to require a diagnostic errno setting. I don't see how this relates to PR23572 though.

When compiled with today's GCC 7 the test case prints the expected result. Is there still a problem here or can the bug be resolved as fixed? $ (set -x && cat t.c && for m in 32 64; do gcc -O2 -Wall -funsafe-math-optimizations -m$m -lm t.c && ./a.out 5000; done) + cat t.c #include <stdio.h> #include <math.h> #include <stdlib.h> int main(int argc, char **argv) { double y = atof(argv[1]); double x = exp (y); printf("%.6e %.6e\n", y, x); perror("errno"); return 0; } + for m in 32 64 + gcc -O2 -Wall -funsafe-math-optimizations -m32 -lm t.c + ./a.out 5000 5.000000e+03 inf errno: Numerical result out of range + for m in 32 64 + gcc -O2 -Wall -funsafe-math-optimizations -m64 -lm t.c + ./a.out 5000 5.000000e+03 inf errno: Numerical result out of range

Note this bug mostly applied to -mfancy-math-387 -m32 [-funsafe-math-optimizations]. It seems the expand_errno_check() optimization has been removed gradually and finally with 2015-11-17 Richard Sandiford <richard.sandiford@arm.com> * builtins.c (expand_errno_check, expand_builtin_mathfn) (expand_builtin_mathfn_2): Delete. (expand_builtin): Remove handling of functions with internal function equivalents. ... Thus this is fixed fully since GCC 6.