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"
>

Reply via email to