This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: disabling the effects of -ffast-math at specific locations


On 9/9/2011 10:54 PM, Sam Hocevar wrote:
    I am using -ffast-math because 99% of the time it has a very positive
impact on my resulting binaries. However, from time to time I would like
to avoid some of the assumptions it makes.

Consider the following code, doing some fast rounding magic:

      static double moo(double f, double g)
      {
          g *= 4503599627370496.0; // 2 ** 52
          f += g;
          f -= g;
          return f;
      }

On amd64, it compiles to the following assembly code using -Os:

	.cfi_startproc
	mulsd	.LC0(%rip), %xmm1
	addsd	%xmm1, %xmm0
	subsd	%xmm1, %xmm0
	ret
	.cfi_endproc

As documented, when using -ffast-math everything gets optimised away:

	.cfi_startproc
	rep
	ret
	.cfi_endproc

But everything goes back to what I want with this asm call:

      static double moo(double f, double g)
      {
          g *= 4503599627370496.0; // 2 ** 52
          f += g;
          __asm__("" : "+x" (f));
          f -= g;
          return f;
      }

    So my question is: is this guaranteed to always work? Am I sure that
f will always be in an "x" register?

Perhaps you want the -protect-parens option (and a recent enough version of gcc to support that)? I think I've been informed that this option is a default for gcc 4.6. This option would allow
f = (f + g) -g
to produce the result you appear to want.



-- Tim Prince


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]