Bug 37390 - wrong-code on i486-linux-gnu with -O[12], -O0 works
Summary: wrong-code on i486-linux-gnu with -O[12], -O0 works
Status: RESOLVED DUPLICATE of bug 323
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2008-09-05 22:43 UTC by Matthias Klose
Modified: 2008-09-06 22:19 UTC (History)
64 users (show)

See Also:
Host:
Target: i486-linux-gnu
Build:
Known to work:
Known to fail: 4.2.4 4.3.2
Last reconfirmed:


Attachments
example (373 bytes, text/x-csrc)
2008-09-05 22:43 UTC, Matthias Klose
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Klose 2008-09-05 22:43:34 UTC
this is the example from
http://gcc.gnu.org/ml/gcc/2008-08/msg00376.html

seen with 4.2.4 and 4.3.2

root@edubuntu:/home/junk/prog/tju# gcc bug_short.c -lm -O2
root@edubuntu:/home/junk/prog/tju# ./a.out
2383,1
31727,1
132265613,1
3145439247023686464
root@edubuntu:/home/junk/prog/tju# gcc bug_short.c -lm
root@edubuntu:/home/junk/prog/tju# ./a.out
2383,1
31727,1
132265613,1
10004511787964928
Comment 1 Matthias Klose 2008-09-05 22:43:55 UTC
Created attachment 16238 [details]
example
Comment 2 Andrew Pinski 2008-09-05 22:54:48 UTC
I think this is really PR 323.  Using -ffloat-store gives the correct answer.
  D.2639 = pow ((double) a, (double) b + 1.0e+0);
  num = (ull) D.2639 - 1.0e+0;

So I don't know what else to say, except -ffloat-store or use -mfpmath=sse.
Comment 3 Matthias Klose 2008-09-06 14:18:58 UTC
> So I don't know what else to say

mark as duplicate of PR 323?
Comment 4 Niklaus 2008-09-06 17:42:08 UTC
On the below version of gcc on cygwin (winXP SP3) i don't have any problems with optimization on or off. They produce consistent correct result. Why is it a  problem with linux ? or am i doing something wrong.

I tried gcc -mfpmath=387  a.c -O2 and without -O2 , still the same correct results on both.

Even with -ffloat-store . Is it glibc ?

$ gcc -v
Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr -
-exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man
--infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without
-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-
awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-j
ava-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enabl
e-libstdcxx-debug
Thread model: posix
gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

$


Comment 5 pinskia@gmail.com 2008-09-06 17:56:12 UTC
Subject: Re:  wrong-code on i486-linux-gnu with -O[12], -O0 works



Sent from my iPhone

On Sep 6, 2008, at 10:42, "niklaus at gmail dot com" <gcc-bugzilla@gcc.gnu.org 
 > wrote:

>
>
> ------- Comment #4 from niklaus at gmail dot com  2008-09-06 17:42  
> -------
> On the below version of gcc on cygwin (winXP SP3) i don't have any  
> problems
> with optimization on or off. They produce consistent correct result.  
> Why is it
> a  problem with linux ? or am i doing something wrong.


Because on x86 gnu/Linux, the precision is set to 80bits rather than  
64bit like it is on windows.
>
>
> I tried gcc -mfpmath=387  a.c -O2 and without -O2 , still the same  
> correct
> results on both.
>
> Even with -ffloat-store . Is it glibc ?
>
> $ gcc -v
> Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
> Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/ 
> configure
> --verbose --prefix=/usr -
> -exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/ 
> usr/lib
> --mandir=/usr/share/man
> --infodir=/usr/share/info --enable-languages=c,ada,c+ 
> +,d,f77,pascal,java,objc
> --enable-nls --without
> -included-gettext --enable-version-specific-runtime-libs --without-x
> --enable-libgcj --disable-java-
> awt --with-system-zlib --enable-interpreter --disable-libgcj-debug
> --enable-threads=posix --enable-j
> ava-gc=boehm --disable-win32-registry --enable-sjlj-exceptions
> --enable-hash-synchronization --enabl
> e-libstdcxx-debug
> Thread model: posix
> gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
>
> $
>
>
> -- 
>
> niklaus at gmail dot com changed:
>
>           What    |Removed                     |Added
> --- 
> --- 
> ----------------------------------------------------------------------
>                 CC|                            |niklaus at gmail dot  
> com
>
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37390
>
Comment 6 Andrew Pinski 2008-09-06 18:01:22 UTC

*** This bug has been marked as a duplicate of 323 ***
Comment 7 Niklaus 2008-09-06 18:28:53 UTC
(In reply to comment #5)
> Subject: Re:  wrong-code on i486-linux-gnu with -O[12], -O0 works
> 
> Because on x86 gnu/Linux, the precision is set to 80bits rather than  
> 64bit like it is on windows.
> >

Does increasing bits cause floating point errors. How could 64 bit precison give correct result where as 80 bit give incorrect one.

 I mean with changing the pow to powl and double to long double fixes the issue with optimization. Isn't long double precision 80 bits ?


Also 1 more question .

junk@edubuntu:~/prog/tju$ gcc -O2 -mfpmath=sse bug_short.c -lm
bug_short.c:1: warning: SSE instruction set disabled, using 387 arithmetics

Shouldn't this be SSE instruction enabled and 387 disabled. 387 is causing the problem right ? 
I could be wrong , thats what i could figure out from the mail thread you marked as duplicate.
Comment 8 Vincent Lefèvre 2008-09-06 18:42:35 UTC
(In reply to comment #7)
> Does increasing bits cause floating point errors. How could 64 bit precison
> give correct result where as 80 bit give incorrect one.

You can have rounding errors whether you increase the precision or not. In particular, in practice, function pow() is not correctly rounded, and worse, the error may be quite high. So, I'd say that whatever the choice made by Linux, your code may be regarded as wrong (and I think this bug is just invalid, as you could have similar problems with SSE2).

> junk@edubuntu:~/prog/tju$ gcc -O2 -mfpmath=sse bug_short.c -lm
> bug_short.c:1: warning: SSE instruction set disabled, using 387 arithmetics

You probably need another compilation flag, like -march=pentium4.
Comment 9 brian 2008-09-06 20:31:41 UTC
Subject: Re:  wrong-code on i486-linux-gnu with -O[12], -O0 
 works

pinskia at gmail dot com wrote:

> Because on x86 gnu/Linux, the precision is set to 80bits rather than
> 64bit like it is on windows.

That is only true of the Microsoft toolchain.  Both Cygwin and MinGW set
the precision to 80 bits.  (On MinGW, you can use the default Microsoft
setting by including CRT_FP8.o explicitly on the link command.)

I think the observed difference is simply because this is in the
undefined behavior category: it depends on details of how the register
allocator happened to decide to operate, whether it spilled the values
to memory.
Comment 10 Niklaus 2008-09-06 21:23:58 UTC
(In reply to comment #8)
> (In reply to comment #7)
> > Does increasing bits cause floating point errors. How could 64 bit precison
> > give correct result where as 80 bit give incorrect one.
> 
> You can have rounding errors whether you increase the precision or not. In
> particular, in practice, function pow() is not correctly rounded, and worse,
> the error may be quite high. So, I'd say that whatever the choice made by
> Linux, your code may be regarded as wrong (and I think this bug is just
> invalid, as you could have similar problems with SSE2).

The funny thing is that this only happens with -O2 or -O1 but not with -O0 ie no optimization it is all correct , when we optimize the results start varying.

> 
> > junk@edubuntu:~/prog/tju$ gcc -O2 -mfpmath=sse bug_short.c -lm
> > bug_short.c:1: warning: SSE instruction set disabled, using 387 arithmetics
> 
> You probably need another compilation flag, like -march=pentium4.
> 

Comment 11 Vincent Lefèvre 2008-09-06 22:19:17 UTC
(In reply to comment #10)
> The funny thing is that this only happens with -O2 or -O1 but not with -O0 ie
> no optimization it is all correct , when we optimize the results start varying.

Because with -O0, some values are stored to memory and re-read from memory, hence rounded to double precision (53-bit significand), a bit like with -ffloat-store.