$ 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