This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
disabling the effects of -ffast-math at specific locations
- From: Sam Hocevar <sam at hocevar dot net>
- To: gcc-help at gcc dot gnu dot org
- Date: Sat, 10 Sep 2011 04:54:37 +0200
- Subject: disabling the effects of -ffast-math at specific locations
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?
And do I have a way to make this portable? On PowerPC it's just a
matter of replacing "+x" with "+f" (which is exactly what Apple does in
its libm). But on i386, I don't know in what kind of register f will be,
and I'm stuck with using "+m", which has an awful performance impact.
Or maybe I'm trying to solve the wrong problem? Is there another
method that will more likely do what I want?
Cheers,
--
Sam.