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