public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/13719] New: 0.2*5.0>1.0 even with -O0, missing fldl probably
@ 2004-01-17 14:24 guilhem at mysql dot com
2004-01-17 14:25 ` [Bug c++/13719] " guilhem at mysql dot com
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: guilhem at mysql dot com @ 2004-01-17 14:24 UTC (permalink / raw)
To: gcc-bugs
Hi!
I have read the "most reported non-bug" about floating-point precision, but I
think it's a real bug here; please take time to read.
I personally use 3.2.2 but colleague with 3.3.2 has the same bug too (with
same testcase and same compiler options). We use Linux (Mandrake & SuSE).
Here is test.cc:
#include <stdlib.h>
int main()
{
return ((int)((atof("0.2")*atof("5.0"))>1.0));
}
Compile this with:
g++ -O0 -o test_bin test.cc
And in a shell execute:
./test_bin ; echo $?
I get 1, so comparison is done wrong.
Adding -ffloat-store does not remove the error.
Here is the problem in my humble opinion (using the output of g++ -S):
g++ -O0 -S test.cc:
.file "test.cc"
.section .rodata
.LC0:
.string "0.2"
.LC1:
.string "5.0"
.text
.align 2
.globl main
.type main,@function
main:
.LFB1:
pushl %ebp
.LCFI0:
movl %esp, %ebp
.LCFI1:
subl $8, %esp
.LCFI2:
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
subl $12, %esp
pushl $.LC0
.LCFI3:
call atof
addl $16, %esp
fstpl -8(%ebp)
subl $12, %esp
pushl $.LC1
call atof
addl $16, %esp
fldl -8(%ebp)
**multiplication of the 2 numbers
fmulp %st, %st(1)
**result of multiplication (1.000000000000000056)
**is left in FPU
**and directly used for comparison, hence the problem
fld1
fxch %st(1)
fucompp
fnstsw %ax
testb $69, %ah
sete %al
andl $255, %eax
leave
ret
.LFE1:
.Lfe1:
.size main,.Lfe1-main
.ident "GCC: (GNU) 3.2.2 (Mandrake Linux 9.1 3.2.2-3mdk)"
I guess there should be some rounding (using fldl) between multiplication and
comparison; it does not make sense to do the comparison with the extra precision
of the FPU. In the next example we see it better.
If I add a few printf(), the error appears only with -O1 (or more): here is
test2.cc:
#include <stdlib.h>
#include <stdio.h>
main()
{
double e = atof("0.2")*atof("5.0");
if (e>1.0)
printf("0.2 * 5.0 > 1.0 (ERROR)\n");
else
printf("0.2 * 5.0 <= 1.0 (OK)\n");
}
When built with g++ -O0 test2.cc it prints OK, with -01 it prints ERROR.
Here are snippets of the assembler code (the multiplication and comparison section):
with -O0:
<cut>
fmull -16(%ebp)
fstpl -8(%ebp)
fldl -8(%ebp)
fld1
fxch %st(1)
fucompp
<cut>
(see fldl which does the rounding of the multiplication result from FPU
precision to double precision).
With -O1:
<cut>
fmulp %st, %st(1)
fld1
fxch %st(1)
fucompp
<cut>
Again, the result of the multiplication (with precision of the FPU) is used
directly for comparison, without any rounding.
In the MySQL code which is were the problem originally arose (we had
SELECT ACOS(0.2*5.0) returning NULL), the problem appeared only with -O2 (or more).
I hope these testcases can be of use.
Guilhem Bichot (MySQL A.B.)
--
Summary: 0.2*5.0>1.0 even with -O0, missing fldl probably
Product: gcc
Version: 3.3.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: guilhem at mysql dot com
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13719
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/13719] 0.2*5.0>1.0 even with -O0, missing fldl probably
2004-01-17 14:24 [Bug c++/13719] New: 0.2*5.0>1.0 even with -O0, missing fldl probably guilhem at mysql dot com
@ 2004-01-17 14:25 ` guilhem at mysql dot com
2004-01-17 18:05 ` pinskia at gcc dot gnu dot org
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: guilhem at mysql dot com @ 2004-01-17 14:25 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From guilhem at mysql dot com 2004-01-17 14:25 -------
Forgot to say: reproduced on processors AMD Athlon XP2000+ and Pentium III Xeon.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13719
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/13719] 0.2*5.0>1.0 even with -O0, missing fldl probably
2004-01-17 14:24 [Bug c++/13719] New: 0.2*5.0>1.0 even with -O0, missing fldl probably guilhem at mysql dot com
2004-01-17 14:25 ` [Bug c++/13719] " guilhem at mysql dot com
@ 2004-01-17 18:05 ` pinskia at gcc dot gnu dot org
2004-01-17 19:54 ` guilhem at mysql dot com
2004-01-17 20:02 ` pinskia at gcc dot gnu dot org
3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-01-17 18:05 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2004-01-17 18:05 -------
Not a bug, it is connect to the most reported non-bug but GCC is allowed to keep intermediate
results in the excussive precision form which is happening here. If you store the multiplication into
a tempary variable it works as you are expecting, this is not a bug.
--
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13719
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/13719] 0.2*5.0>1.0 even with -O0, missing fldl probably
2004-01-17 14:24 [Bug c++/13719] New: 0.2*5.0>1.0 even with -O0, missing fldl probably guilhem at mysql dot com
2004-01-17 14:25 ` [Bug c++/13719] " guilhem at mysql dot com
2004-01-17 18:05 ` pinskia at gcc dot gnu dot org
@ 2004-01-17 19:54 ` guilhem at mysql dot com
2004-01-17 20:02 ` pinskia at gcc dot gnu dot org
3 siblings, 0 replies; 5+ messages in thread
From: guilhem at mysql dot com @ 2004-01-17 19:54 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From guilhem at mysql dot com 2004-01-17 19:54 -------
Thanks for your answer. However, the 2nd example I gave in the bug report
#include <stdlib.h>
#include <stdio.h>
main()
{
double e = atof("0.2")*atof("5.0");
if (e>1.0)
printf("0.2 * 5.0 > 1.0 (ERROR)\n");
else
printf("0.2 * 5.0 <= 1.0 (OK)\n");
}
does "store the multiplication into a temporary variable" (quoting your words)
('e'), but it certainly does not "work as I am expecting" when compiled with -O1.
Could you please explain to me?
--
What |Removed |Added
----------------------------------------------------------------------------
Status|RESOLVED |UNCONFIRMED
Resolution|INVALID |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13719
^ permalink raw reply [flat|nested] 5+ messages in thread
* [Bug c++/13719] 0.2*5.0>1.0 even with -O0, missing fldl probably
2004-01-17 14:24 [Bug c++/13719] New: 0.2*5.0>1.0 even with -O0, missing fldl probably guilhem at mysql dot com
` (2 preceding siblings ...)
2004-01-17 19:54 ` guilhem at mysql dot com
@ 2004-01-17 20:02 ` pinskia at gcc dot gnu dot org
3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-01-17 20:02 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2004-01-17 20:02 -------
Still need -ffloat-store for the second case, the first case it does not matter because of C rules and
how -ffloat-store works. Also you can use -mfpmath=sse to get the results you are expecting on
x86.
--
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |INVALID
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13719
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-01-17 20:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-17 14:24 [Bug c++/13719] New: 0.2*5.0>1.0 even with -O0, missing fldl probably guilhem at mysql dot com
2004-01-17 14:25 ` [Bug c++/13719] " guilhem at mysql dot com
2004-01-17 18:05 ` pinskia at gcc dot gnu dot org
2004-01-17 19:54 ` guilhem at mysql dot com
2004-01-17 20:02 ` pinskia at gcc dot gnu dot org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).