$ cat test.c #include <stdio.h> int main() { _Decimal128 const a=1.111111111111111111111111111111111dl; _Decimal128 const b=1.1111111e-6158dl; _Decimal128 volatile x=a; _Decimal128 volatile y=b; double ab=a*b*1.0e6000dl; double xy=x*y*1.0e6000dl; printf("ab=%g\n",ab); printf("xy=%g\n",xy); }
$ gcc test.c && ./a.out ab=9.64506e-159 xy=9.64506e-159 $ gcc -O test.c && ./a.out ab=1.23457e-158 xy=9.64506e-159 $ gcc --version | head -1 gcc (GCC) 4.5.1 20100418 (prerelease) The correct value is 1.23457e-158: $ echo "1.111111111111111111111111111111111*1.1111111" | bc 1.234567888888888888888888888888888 A simple modification of test.c can show that it is x*y and a*b, when computed by libbid, are incorrect. The a*b expression, when computed by gcc (with -O), is correct. To further diagnose, I extracted libbid from the gcc source tree and compiled it outside of gcc to link it with the above test.c program. I added some #defines to compile the library and renamed some functions to call them directly from the test. I found that if compiled with -O only, libbid multiplies correctly. With -O -ftree-pre, it multiplies incorrectly. The real job is done by bid128_ext_fma() (about 3000 C lines). -- Summary: [4.5 regression] -O -ftree-pre options compile libbid wrong Product: gcc Version: 4.5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: roman at binarylife dot net GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43783