GCC currently defaults to -fmath-errno. This generates code assuming math functions set errno and the application checks errno. Very few applications test errno and various systems and math libraries no longer set errno since it is optional. GCC generates much faster code for simple math functions with -fno-math-errno such as sqrt and lround (avoiding a call and PLT redirection). Therefore it seems reasonable to change the default to -fno-math-errno.
long f(float x) { return lroundf(x) + 1; } by default: f: str x30, [sp, -16]! bl lroundf add x0, x0, 1 ldr x30, [sp], 16 ret lroundf in GLIBC doesn't set errno, so all the inefficiency was for nothing: 0000000000000000 <__lroundf>: 0: 9e240000 fcvtas x0, s0 4: d65f03c0 ret With -fno-math-errno: f: fcvtas x0, s0 add x0, x0, 1 ret OK for commit? 2017-10-27 Wilco Dijkstra <wdijk...@arm.com> * common.opt (fmath-errno): Change default to 0. * opts.c (set_fast_math_flags): Force -fno-math-errno with -ffast-math. doc/ * invoke.texi (-fmath-errno) Update documentation. -- diff --git a/gcc/common.opt b/gcc/common.opt index 836f05b95a219d17614f35e8dad61b22fef7d748..1bb87353f760d7c60c39de8b9de4311c1ec3d892 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1842,7 +1842,7 @@ Common Report Var(flag_lto_report_wpa) Init(0) Report various link-time optimization statistics for WPA only. fmath-errno -Common Report Var(flag_errno_math) Init(1) Optimization SetByCombined +Common Report Var(flag_errno_math) Init(0) Optimization SetByCombined Set errno after built-in math functions. fmax-errors= diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 71b2445f70fd5b832c68c08e69e71d8ecad37a4a..3328a3b5fafa6a98007eff52d2a26af520de9128 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -9397,24 +9397,16 @@ that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications. -@item -fno-math-errno -@opindex fno-math-errno -Do not set @code{errno} after calling math functions that are executed -with a single instruction, e.g., @code{sqrt}. A program that relies on -IEEE exceptions for math error handling may want to use this flag -for speed while maintaining IEEE arithmetic compatibility. +@item -fmath-errno +@opindex fmath-errno +Generate code that assumes math functions may set errno. This disables +inlining of simple math functions like @code{sqrt} and @code{lround}. -This option is not turned on by any @option{-O} option since -it can result in incorrect output for programs that depend on -an exact implementation of IEEE or ISO rules/specifications for -math functions. It may, however, yield faster code for programs -that do not require the guarantees of these specifications. - -The default is @option{-fmath-errno}. +A program which relies on math functions setting errno may need to +use this flag. However note various systems and math libraries never +set errno. -On Darwin systems, the math library never sets @code{errno}. There is -therefore no reason for the compiler to consider the possibility that -it might, and @option{-fno-math-errno} is the default. +The default is @option{-fno-math-errno}. @item -funsafe-math-optimizations @opindex funsafe-math-optimizations @@ -21315,8 +21307,8 @@ truncation towards zero. @item @samp{round} Conversion from single-precision floating point to signed integer, rounding to the nearest integer and ties away from zero. -This corresponds to the @code{__builtin_lroundf} function when -@option{-fno-math-errno} is used. +This corresponds to the @code{__builtin_lroundf} function unless +@option{-fmath-errno} is used. @item @samp{floatis}, @samp{floatus}, @samp{floatid}, @samp{floatud} Conversion from signed or unsigned integer types to floating-point types. diff --git a/gcc/opts.c b/gcc/opts.c index 6600a5afd488e89262e6327f7370057c7ae234ba..dfad955e220870a3250198640f3790c804b191e0 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2530,8 +2530,6 @@ set_fast_math_flags (struct gcc_options *opts, int set) } if (!opts->frontend_set_flag_finite_math_only) opts->x_flag_finite_math_only = set; - if (!opts->frontend_set_flag_errno_math) - opts->x_flag_errno_math = !set; if (set) { if (opts->frontend_set_flag_excess_precision_cmdline @@ -2544,6 +2542,8 @@ set_fast_math_flags (struct gcc_options *opts, int set) opts->x_flag_rounding_math = 0; if (!opts->frontend_set_flag_cx_limited_range) opts->x_flag_cx_limited_range = 1; + if (!opts->frontend_set_flag_errno_math) + opts->x_flag_errno_math = 0; } }