On Mon, Jun 18, 2018 at 4:01 PM Wilco Dijkstra <wilco.dijks...@arm.com> wrote: > > GCC currently defaults to -fmath-errno. This generates code assuming math > functions set errno and the application checks errno. 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 is reasonable to change the default to -fno-math-errno. This is > already the case for non-C languages. Only change the default for C99 and > later. > > 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 > > With -fno-math-errno: > > f: > fcvtas x0, s0 > add x0, x0, 1 > ret > > Passes regress on AArch64. OK for commit?
There are a number of regression tests that check for errno handling (I added some to avoid aliasing for example). Please make sure to add explicit -fmath-errno to those that do not already have it set (I guess such patch would be obvious and independent of this one). A grep -r errno testsuite/ is only 159 lines but it might not catch all cases - the one I'm refering to above matches because of a comment only: testsuite/gcc.dg/tree-ssa/ssa-dse-15.c: /* We should be able to DSE this store (p may point to errno). */ Following Josephs comment it may be reasonable to have the default depend on the targets C library and thus make it a target macro (IIRC the BSD libc never set errno for any math function for example). Josephs comment indicates conformance issues with a -fno-math-errno -fno-trapping-math combination (-ftrapping-math is default). Thanks, Richard. > ChangeLog: > 2018-06-18 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. > * c-family/c-opts.c (c_common_init_options_struct): Set > flag_errno_math > to special value. > (c_common_post_options): Set flag_errno_math default based on > language. > > doc/ > * invoke.texi (-fmath-errno) Update documentation. > > testsuite/ > > * gcc.dg/errno-1.c: Add -fmath-errno. > * gcc.dg/torture/pr68264.c: Likewise. > * gcc.dg/tree-ssa/ssa-dse-15.c: Likewise. > * gcc.target/aarch64/no-inline-lrint_1.c: Likewise. > -- > > diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c > index > bbcb1bb1a9c606a262a1aa362471388987629d06..b13fc122f8baf6aae0b47010be92ffd961b0147a > 100644 > --- a/gcc/c-family/c-opts.c > +++ b/gcc/c-family/c-opts.c > @@ -208,6 +208,9 @@ c_common_init_options_struct (struct gcc_options *opts) > > /* By default, C99-like requirements for complex multiply and divide. */ > opts->x_flag_complex_method = 2; > + > + /* Use a special value so the default can be set after option parsing. */ > + opts->x_flag_errno_math = 2; > } > > /* Common initialization before calling option handlers. */ > @@ -831,6 +834,11 @@ c_common_post_options (const char **pfilename) > else if (!flag_gnu89_inline && !flag_isoc99) > error ("-fno-gnu89-inline is only supported in GNU99 or C99 mode"); > > + /* If -fmath-errno isn't set (or implied by another math option), > + set the default to -fno-math-errno for C99 and later. */ > + if (flag_errno_math == 2) > + flag_errno_math = !flag_isoc99 || c_dialect_objc (); > + > /* Default to ObjC sjlj exception handling if NeXT runtime. */ > if (flag_objc_sjlj_exceptions < 0) > flag_objc_sjlj_exceptions = flag_next_runtime; > diff --git a/gcc/common.opt b/gcc/common.opt > index > d54e8e5601698c73d2c2bc8f354b55f3889a9186..e6fe11d1dcdbb39016242299dd3d76233e2bd976 > 100644 > --- a/gcc/common.opt > +++ b/gcc/common.opt > @@ -1855,7 +1855,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 > 42832c5a50013d776dff47c6d347f5bc4dbef2d8..aeda219ba0dbe169d9fb2b4358950f2ba32b5c78 > 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -9783,24 +9783,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} except in ISO C90 and C++98 modes. > > @item -funsafe-math-optimizations > @opindex funsafe-math-optimizations > @@ -21827,8 +21819,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 > 33efcc0d6e7db73ba60cab62ef146e976e75ca21..a6f228a53e1baa505a477a273fad3d00364f6893 > 100644 > --- a/gcc/opts.c > +++ b/gcc/opts.c > @@ -2581,8 +2581,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 > @@ -2595,6 +2593,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; > } > } > > diff --git a/gcc/testsuite/gcc.dg/errno-1.c b/gcc/testsuite/gcc.dg/errno-1.c > index > 0dfb00087dee04cd5ff1e916149c0c13c9b87b20..25739e4a862ca9a9c05157d3abc87216eb27ea7d > 100644 > --- a/gcc/testsuite/gcc.dg/errno-1.c > +++ b/gcc/testsuite/gcc.dg/errno-1.c > @@ -1,5 +1,5 @@ > /* { dg-do compile } */ > -/* { dg-options "-O2" } */ > +/* { dg-options "-O2 -fmath-errno" } */ > > #include <errno.h> > #include <stdlib.h> > diff --git a/gcc/testsuite/gcc.dg/torture/pr68264.c > b/gcc/testsuite/gcc.dg/torture/pr68264.c > index > 9294d5aedb79de1b91b3074e34b089b100031d54..56d7bf7bc64545566d7127a329f244045a0f2afc > 100644 > --- a/gcc/testsuite/gcc.dg/torture/pr68264.c > +++ b/gcc/testsuite/gcc.dg/torture/pr68264.c > @@ -1,5 +1,6 @@ > /* { dg-do run } */ > /* { dg-add-options ieee } */ > +/* { dg-additional-options "-fmath-errno" } */ > /* { dg-require-effective-target fenv_exceptions } */ > > #include <fenv.h> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c > b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c > index > 43a41c8eb38db1c930923f1bb0fd9d1689fac826..134febf96d38128a0f5ebf7175f137c7aefc90bc > 100644 > --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c > +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c > @@ -1,5 +1,5 @@ > /* { dg-do compile } */ > -/* { dg-options "-O2 -fdump-tree-dse1-details" } */ > +/* { dg-options "-O2 -fdump-tree-dse1-details -fmath-errno" } */ > > void *foo (int *p) > { > diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c > b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c > index > d5e9200562c166ace4d8e72d9a9f560e35846b29..229b456576a81d99427625a3e3f6cc63e937eb5a > 100644 > --- a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c > +++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c > @@ -1,6 +1,6 @@ > /* { dg-do compile } */ > /* { dg-require-effective-target lp64 } */ > -/* { dg-options "-O3" } */ > +/* { dg-options "-O3 -fmath-errno" } */ > > #include "lrint-matherr.h" >