Hi,

Recently, we discovered some floating point precision diffs when using GCC8 to 
build our 
application on arm64: After some investigation, it turns out that this is due 
to the 
-ffp-contract=fast option that is on by default. Therefore, we have to 
explicitly add 
-ffp-contract=off and do a full-rebuild.  

GCC by default turns -ffp-contract=fast on.
https://gcc.gnu.org/onlinedocs/gcc-8.5.0/gcc/Optimize-Options.html#Optimize-Options
https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Optimize-Options.html#Optimize-Options

"
-ffp-contract=style
-ffp-contract=off disables floating-point expression contraction. 
-ffp-contract=fast enables
floating-point expression contraction such as forming of fused multiply-add 
operations if 
the target has native support for them. -ffp-contract=on enables floating-point 
expression
contraction if allowed by the language standard. This is currently not 
implemented and 
treated equal to -ffp-contract=off.

The default is -ffp-contract=fast.
"

This can be shown by a small example for arm64 with gcc8.5 in 
https://godbolt.org/z/MxYfnG8TE. 
Only when adding -std=c89 explicitly, this transformaton is off.

another exmaple also shows that Clang and MSVC only allow this transformation 
when speifiying
ffast-math and fp:fast:  https://godbolt.org/z/o54bYfPbP 

When searching online, we found that there were similar discussions recently on 
the exact same issue:
https://github.com/dotnet/runtime/issues/64604
https://github.com/dotnet/runtime/issues/64591

a summary of these discussions is:

1. "fmadd" is a fused operation and will return a different result for many 
inputs;  
2. therefore, -ffp-contract=fast is not a safe optimization to be on by default;
3. Clang and MSVC only allow this when specifying ffast-math and fp:fast since 
this is not an
  IEEE754 compliant optimization;
4. The reasons why GCC turns on this option by default are:
  A. GNU C language spec allows such transformation. 
  B. this did not expose real problem for most X86/X64 apps previously since 
FMA instructions
     didn't exist until 2013 when the FMA3 instruction set was added, and also 
these instructions
     were not always available.. 
5. Arm64 has fused multiply-add instructions as "baseline" and are always 
available. therefore
  -ffp-contract=fast exposed more serious problems on Arm64 platforms.  

our major question:

Should GCC turn off -ffp-contract=fast by default since it's not IEEE754 
compliant and more
  modern processors have the FMA instructions available by default?

Thanks.

Qing

Reply via email to