Created attachment 47071 [details] Test source and build script Dear GCC team, we've found that the usage of GCCs builtin rint() or rintf() functions on x86_64 platforms, as are introduced with optimization -O1 and above results in a change of the runtime result of those functions. When compiling the attached testprogram with "-O0" or using "-O1 -fno-builtin-rint" the results are as expected as defined by the API. Using GCCs builtin some of the results differ from the expected values. It seems operations using FE_DOWNWARD and FE_UPWARD are behaving contrarily for negative floating point inputs to rint/rintf using builtin rint functions, resulting in the wrongly rounded value. The behaviour was reproduced on x86_64 platforms Ubuntu Linux 19.10, MSys2 and bare metal x86_64 toolchains with GCC compilers 8.2, 9.1, 9.2.1. Please find attached the bzipped test program (rinttest.tar.bz2), including build.sh script to compile and run. This should provide a similar output as in attached text file (rinttest_output.txt). Please let me know if I can assist any further. Best, Steffen
Created attachment 47072 [details] Test result output text.
Did you compile with -frounding-math?
Thanks for the quick reply. Just tested using -frounding-math and it seems to fix the issue. Sorry, I was not aware of this option, according to GCCs manual it is experimental. Please correct me if I'm wrong, but my expectation would be, assuming a correct program, switching from -O0 to -O1 should not influence the runtime result.
(In reply to Steffen Schmidt from comment #3) > Thanks for the quick reply. > > Just tested using -frounding-math and it seems to fix the issue. > Sorry, I was not aware of this option, according to GCCs manual it is > experimental. > > Please correct me if I'm wrong, but my expectation would be, assuming a > correct program, switching from -O0 to -O1 should not influence the runtime > result. GCC assumes you do not mess with the floating-point state but round-to-nearest is in effect. You have to use -frounding-math to remove this assumption but then still correct operation isn't guaranteed (thus the "experimental" tag for this option).
Note that if GCC would be standards-conforming here your program would still need #pragma STDC FENV_ACCESS ON since you are accessing and modifying the floating-point state (where the pragma has no effect for GCC)
See PR34678 for issues of -frounding-math.
So it works (with -frounding-math), closing.