public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
@ 2020-01-21 14:52 Ulrich Weigand
  2020-01-21 15:05 ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Ulrich Weigand @ 2020-01-21 14:52 UTC (permalink / raw)
  To: gcc, joseph

Hello,

the -ffast-math command line option sets a bunch of other flags
internally, as implemented in set_fast_math_flags.  It is possible
to selectively override those flags on the command line as well.

I'm now wondering under what circumstances the __FAST_MATH__ macro
should still be defined.  This is currently implemented in the
fast_math_flags_set_p routine, which checks the status of *some*
(but not all!) of the flags implied by -ffast-math.

This has the effect that e.g. after

  -ffast-math -fno-finite-math-only

the __FAST_MATH__ macro is no longer predefined, but after

  -ffast-math -fno-associative-math

the __FAST_MATH__ macro still *is* predefined, even though both
-ffinite-math-only and -fassociative-math are implied by -ffast-math.

Is this deliberate?  (If so, is it documented somewhere?)

Or is this just a bug and fast_math_flags_set_p ought to check
all flags implied by -ffast-math?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-21 14:52 fast_math_flags_set_p vs. set_fast_math_flags inconsistency? Ulrich Weigand
@ 2020-01-21 15:05 ` Joseph Myers
  2020-01-21 15:39   ` Ulrich Weigand
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2020-01-21 15:05 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

On Mon, 20 Jan 2020, Ulrich Weigand wrote:

> This has the effect that e.g. after
> 
>   -ffast-math -fno-finite-math-only
> 
> the __FAST_MATH__ macro is no longer predefined, but after
> 
>   -ffast-math -fno-associative-math
> 
> the __FAST_MATH__ macro still *is* predefined, even though both
> -ffinite-math-only and -fassociative-math are implied by -ffast-math.
> 
> Is this deliberate?  (If so, is it documented somewhere?)

I'd expect both to cause it to be undefined.  My guess would be that some 
past patch, after fast_math_flags_set_p was added, added more flags to 
-ffast-math but accidentally failed to update fast_math_flags_set_p; you'd 
need to look at past patches adding flags to -ffast-math to confirm if 
it's accidental.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-21 15:05 ` Joseph Myers
@ 2020-01-21 15:39   ` Ulrich Weigand
  2020-01-21 18:50     ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Ulrich Weigand @ 2020-01-21 15:39 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc

Joseph Myers wrote:
> On Mon, 20 Jan 2020, Ulrich Weigand wrote:
> 
> > This has the effect that e.g. after
> > 
> >   -ffast-math -fno-finite-math-only
> > 
> > the __FAST_MATH__ macro is no longer predefined, but after
> > 
> >   -ffast-math -fno-associative-math
> > 
> > the __FAST_MATH__ macro still *is* predefined, even though both
> > -ffinite-math-only and -fassociative-math are implied by -ffast-math.
> > 
> > Is this deliberate?  (If so, is it documented somewhere?)
> 
> I'd expect both to cause it to be undefined.  My guess would be that some 
> past patch, after fast_math_flags_set_p was added, added more flags to 
> -ffast-math but accidentally failed to update fast_math_flags_set_p; you'd 
> need to look at past patches adding flags to -ffast-math to confirm if 
> it's accidental.

It looks like there's multiple cases here.  For the two flags
-fassociative-math and -freciprocal-math, it seems to have happened just as
you describe: they were created (split out of -funsafe-math-optimizations)
in commit a1a826110720eda37c73f829daa4ee243ee953f5, which however did not
update fast_math_flags_set_p.

For the other three flags, -fsignaling-nans, -frounding-math, and
-fcx-limited-range, the story appears to be a bit different: from the
very beginning, those were treated somewhat differently: these are
only modified as a result of -ffast-math, not -fno-fast-math (like
the other flags derived from -ffast-math), and they are not considered
by fast_math_flags_set_p.  (I'm not sure if there is any particular
reason why these should be treated differently here, though.)

Finally, there is one "mixed" flag, -fexcess-precision, which is handled
like the above three in that its default is only modified as a result of
-ffast-math, not -fno-fast-math; but nevertheless this flag *is* checked
in fast_math_flags_set_p.

Do you think there is something that ought to be fixed here?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-21 15:39   ` Ulrich Weigand
@ 2020-01-21 18:50     ` Joseph Myers
  2020-01-28 15:55       ` Ulrich Weigand
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2020-01-21 18:50 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

On Tue, 21 Jan 2020, Ulrich Weigand wrote:

> It looks like there's multiple cases here.  For the two flags
> -fassociative-math and -freciprocal-math, it seems to have happened just as
> you describe: they were created (split out of -funsafe-math-optimizations)
> in commit a1a826110720eda37c73f829daa4ee243ee953f5, which however did not
> update fast_math_flags_set_p.

So that's a bug.

> For the other three flags, -fsignaling-nans, -frounding-math, and
> -fcx-limited-range, the story appears to be a bit different: from the

The first two of those are disabled by default as well as disabled by 
-ffast-math, so it seems right that -fno-fast-math does nothing with them 
and that they aren't checked by fast_math_flags_set_p.

The last one is disabled by default but enabled by -ffast-math.  So it 
would seem appropriate to handle it like other such options, disable it 
with -fno-fast-math, and check it in fast_math_flags_set_p.

> Finally, there is one "mixed" flag, -fexcess-precision, which is handled
> like the above three in that its default is only modified as a result of
> -ffast-math, not -fno-fast-math; but nevertheless this flag *is* checked
> in fast_math_flags_set_p.

That one's trickier because the default depends on whether a C standards 
conformance mode is specified.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-21 18:50     ` Joseph Myers
@ 2020-01-28 15:55       ` Ulrich Weigand
  2020-01-28 17:19         ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Ulrich Weigand @ 2020-01-28 15:55 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc

Joseph Myers wrote:
> On Tue, 21 Jan 2020, Ulrich Weigand wrote:
> 
> > It looks like there's multiple cases here.  For the two flags
> > -fassociative-math and -freciprocal-math, it seems to have happened just as
> > you describe: they were created (split out of -funsafe-math-optimizations)
> > in commit a1a826110720eda37c73f829daa4ee243ee953f5, which however did not
> > update fast_math_flags_set_p.
> 
> So that's a bug.

OK, agreed.

> > For the other three flags, -fsignaling-nans, -frounding-math, and
> > -fcx-limited-range, the story appears to be a bit different: from the
> 
> The first two of those are disabled by default as well as disabled by 
> -ffast-math, so it seems right that -fno-fast-math does nothing with them 
> and that they aren't checked by fast_math_flags_set_p.

I see.  I guess that makes me wonder what -fno-fast-math *ever* does
(except canceling a -ffast-math earlier on the command line).  Looking
at the current code, -fno-fast-math (just like -ffast-math) only ever
sets flags whose default is not overridden on the command line, but
then it always sets them to their default value!

Am I missing something here?  If that's the intent, it might be cleaner
to write set_fast_math_flags as just one big
  if (set)
    {
    }

> The last one is disabled by default but enabled by -ffast-math.  So it 
> would seem appropriate to handle it like other such options, disable it 
> with -fno-fast-math, and check it in fast_math_flags_set_p.

OK.

> > Finally, there is one "mixed" flag, -fexcess-precision, which is handled
> > like the above three in that its default is only modified as a result of
> > -ffast-math, not -fno-fast-math; but nevertheless this flag *is* checked
> > in fast_math_flags_set_p.
> 
> That one's trickier because the default depends on whether a C standards 
> conformance mode is specified.

This also makes sense if we consider the semantics of -fno-fast-math to
just leave all component flags at their default, as above ...

(As an aside, the current code is even more confusing as it has a dead
condition:

  if (set)
    {
      if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT)
        opts->x_flag_excess_precision
          = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;

The second test of "set" must always be true here, so this will never actually
actively set the flag to EXCESS_PRECISION_DEFAULT.)

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-28 15:55       ` Ulrich Weigand
@ 2020-01-28 17:19         ` Joseph Myers
  2020-01-30  5:44           ` Ulrich Weigand
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2020-01-28 17:19 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

On Mon, 27 Jan 2020, Ulrich Weigand wrote:

> I see.  I guess that makes me wonder what -fno-fast-math *ever* does
> (except canceling a -ffast-math earlier on the command line).  Looking
> at the current code, -fno-fast-math (just like -ffast-math) only ever
> sets flags whose default is not overridden on the command line, but
> then it always sets them to their default value!

As a general principle, more specific flags take precedence over less 
specific ones, regardless of the command-line order.  So it's correct for 
-ffast-math and -fno-fast-math not to do anything with a flag that was 
explicitly overridden by the user (modulo any issues where a particular 
combination of flags is unsupported by GCC, as with the 
"%<-fassociative-math%> disabled; other options take precedence" case in 
toplev.c).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-28 17:19         ` Joseph Myers
@ 2020-01-30  5:44           ` Ulrich Weigand
  2020-01-30 10:00             ` Joseph Myers
  0 siblings, 1 reply; 9+ messages in thread
From: Ulrich Weigand @ 2020-01-30  5:44 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc

Joseph Myers wrote:
> On Mon, 27 Jan 2020, Ulrich Weigand wrote:
> > I see.  I guess that makes me wonder what -fno-fast-math *ever* does
> > (except canceling a -ffast-math earlier on the command line).  Looking
> > at the current code, -fno-fast-math (just like -ffast-math) only ever
> > sets flags whose default is not overridden on the command line, but
> > then it always sets them to their default value!
> 
> As a general principle, more specific flags take precedence over less 
> specific ones, regardless of the command-line order.  So it's correct for 
> -ffast-math and -fno-fast-math not to do anything with a flag that was 
> explicitly overridden by the user (modulo any issues where a particular 
> combination of flags is unsupported by GCC, as with the 
> "%<-fassociative-math%> disabled; other options take precedence" case in 
> toplev.c).

Sure, I agree with the intended behavior as you describe.  I was just 
confused under what circumstances set_fast_math_flags with set == 0
ever does anything.  However, I've now understood that this is required
e.g. for the -Ofast -fno-fast-math case (this seems to be the only case
where set_fast_math_flags is called twice, first with set == 1 and then
with set == 0).

And indeed, in this case we see the effect of not resetting the
flag_cx_limited_range (on x86_64):

$ gcc -E -dD -x c /dev/null -std=c99 | grep GCC_IEC
#define __GCC_IEC_559 2
#define __GCC_IEC_559_COMPLEX 2
$ gcc -E -dD -x c /dev/null -std=c99 -Ofast | grep GCC_IEC
#define __GCC_IEC_559 0
#define __GCC_IEC_559_COMPLEX 0
$ gcc -E -dD -x c /dev/null -std=c99 -Ofast -fno-fast-math | grep GCC_IEC
#define __GCC_IEC_559 2
#define __GCC_IEC_559_COMPLEX 0

Note how __GCC_IEC_559_COMPLEX is not properly reset.

Similarly, we see the effect of not resetting flag_excess_precision
(only on i386):

$ gcc -E -dD -x c /dev/null -m32 -std=c99 | grep GCC_IEC
#define __GCC_IEC_559 2
#define __GCC_IEC_559_COMPLEX 2
$ gcc -E -dD -x c /dev/null -m32 -std=c99 -Ofast | grep GCC_IEC
#define __GCC_IEC_559 0
#define __GCC_IEC_559_COMPLEX 0
$ gcc -E -dD -x c /dev/null -m32 -std=c99 -Ofast -fno-fast-math | grep GCC_IEC
#define __GCC_IEC_559 0
#define __GCC_IEC_559_COMPLEX 0

Note how __GCC_IEC_559 is not properly reset either.

So it seems to me that indeed both of these should be reset
in the !set case of set_fast_math_flags.

In addition, we've already agreed that these three flags should be
checked in fast_math_flags_set_p, where they are currently missing:

  flag_associative_math
  flag_reciprocal_math
  flag_cx_limited_range

Finally, this remaining piece of code in set_fast_math_flags:

 if (set)
   {
     if (!opts->frontend_set_flag_signaling_nans)
       opts->x_flag_signaling_nans = 0;
     if (!opts->frontend_set_flag_rounding_math)
       opts->x_flag_rounding_math = 0;
   }

seems always a no-op since it only ever sets the flags to their
default value when they still must have that same default value.

For clarity, I'd suggest to either remove this code or replace
it with a comment.


The following patch (not yet fully tested) implements the above changes.
Note that this now brings the set of flags set and reset by
set_fast_math_flags completely in sync with the set of flags
tested in fast_math_flags_set_p.

Does this make sense to you?

Thanks,
Ulrich


ChangeLog:

	* opts.c (set_fast_math_flags): In the !set case, also reset
	x_flag_cx_limited_range and x_flag_excess_precision.  Remove dead
	code resetting x_flag_signaling_nans and x_flag_rounding_math.
	(fast_math_flags_set_p): Also test x_flag_cx_limited_range,
	x_flag_associative_math, and x_flag_reciprocal_math.


diff --git a/gcc/opts.c b/gcc/opts.c
index 7affeb4..4452793 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2850,18 +2850,14 @@ set_fast_math_flags (struct gcc_options *opts, int set)
     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 == EXCESS_PRECISION_DEFAULT)
-	opts->x_flag_excess_precision
-	  = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
-      if (!opts->frontend_set_flag_signaling_nans)
-	opts->x_flag_signaling_nans = 0;
-      if (!opts->frontend_set_flag_rounding_math)
-	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_cx_limited_range)
+    opts->x_flag_cx_limited_range = set;
+  if (!opts->frontend_set_flag_excess_precision)
+    opts->x_flag_excess_precision
+      = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
+
+  // -ffast-math should also reset -fsignaling-nans and -frounding-math,
+  // but since those are off by default, there's nothing to do for now.
 }
 
 /* When -funsafe-math-optimizations is set the following
@@ -2884,10 +2880,13 @@ bool
 fast_math_flags_set_p (const struct gcc_options *opts)
 {
   return (!opts->x_flag_trapping_math
+	  && !opts->x_flag_signed_zeros
+	  && opts->x_flag_associative_math
+	  && opts->x_flag_reciprocal_math
 	  && opts->x_flag_unsafe_math_optimizations
 	  && opts->x_flag_finite_math_only
-	  && !opts->x_flag_signed_zeros
 	  && !opts->x_flag_errno_math
+	  && opts->x_flag_cx_limited_range
 	  && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST);
 }
 

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-30  5:44           ` Ulrich Weigand
@ 2020-01-30 10:00             ` Joseph Myers
  2020-01-30 12:33               ` Ulrich Weigand
  0 siblings, 1 reply; 9+ messages in thread
From: Joseph Myers @ 2020-01-30 10:00 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

On Tue, 28 Jan 2020, Ulrich Weigand wrote:

> The following patch (not yet fully tested) implements the above changes.
> Note that this now brings the set of flags set and reset by
> set_fast_math_flags completely in sync with the set of flags
> tested in fast_math_flags_set_p.
> 
> Does this make sense to you?

It makes sense, but this is not a review of the patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: fast_math_flags_set_p vs. set_fast_math_flags inconsistency?
  2020-01-30 10:00             ` Joseph Myers
@ 2020-01-30 12:33               ` Ulrich Weigand
  0 siblings, 0 replies; 9+ messages in thread
From: Ulrich Weigand @ 2020-01-30 12:33 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc

Joseph Myers wrote:
> On Tue, 28 Jan 2020, Ulrich Weigand wrote:
> 
> > The following patch (not yet fully tested) implements the above changes.
> > Note that this now brings the set of flags set and reset by
> > set_fast_math_flags completely in sync with the set of flags
> > tested in fast_math_flags_set_p.
> > 
> > Does this make sense to you?
> 
> It makes sense, but this is not a review of the patch.

Understood, thanks for having a look!  I'll go ahead and submit the
patch for review as usual then.

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-01-29  9:52 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-21 14:52 fast_math_flags_set_p vs. set_fast_math_flags inconsistency? Ulrich Weigand
2020-01-21 15:05 ` Joseph Myers
2020-01-21 15:39   ` Ulrich Weigand
2020-01-21 18:50     ` Joseph Myers
2020-01-28 15:55       ` Ulrich Weigand
2020-01-28 17:19         ` Joseph Myers
2020-01-30  5:44           ` Ulrich Weigand
2020-01-30 10:00             ` Joseph Myers
2020-01-30 12:33               ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).