
$ g++ -O2 -frounding-math bug.cc $ a.out 123456792 123456792 123456792 123456792 123456792 123456792 123456784 123456784 $ g++ -O2 -fno-inline -frounding-math bug.cc $ a.out 123456784 123456792 123456784 123456792 123456784 123456792 123456784 123456792
Someone knows if this is the expected behaviour?
GCC bugs apart we definitely need a way to avoid this mess, someone knows a way?

Abramo Bagnara ha scritto:
$ g++ -O2 -frounding-math bug.cc $ a.out 123456792 123456792 123456792 123456792 123456792 123456792 123456784 123456784 $ g++ -O2 -fno-inline -frounding-math bug.cc $ a.out 123456784 123456792 123456784 123456792 123456784 123456792 123456784 123456792
Someone knows if this is the expected behaviour?
GCC bugs apart we definitely need a way to avoid this mess, someone knows a way?
The attached file show the trick I've found to solve that.
The magic asm force gcc to store in memory the variable and induce gcc to believe that something unknown happens to the content then avoiding common subexpressions elimination (CSE).
arg1 = unknown(arg1); ... argn = unknown(argn); to = func(arg1, ..., argn); to = unknown(argn);
Please, please don't ask me why it's needed also to have
avoid_cse(to);
as I've no idea.
I've verified empirically that not only it's needed (although only in int and long long case), but contributes in all cases to generate better code too (?!?).
Unfortunately this idea is original and I've been unable to find similar solutions and the exact reason why it works so well.
The sweet thing is that as far as I've read other libraries disables optimization locally to avoid the problem ;-)
However take in account that rounding direction change is almost always avoided using sign inversion trick. I've discovered the trouble converting from big integer to float, where the unconditional sign inversion cannot be done because the possible overflow.
Here:
$ gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.1 20060525 (Red Hat 4.1.1-1)
the generated code for the file attached is optimal, I like very much you make further tests with other compilers and other architectures.
participants (1)
-
Abramo Bagnara