------- Comment #14 from pluto at agmk dot net 2010-03-24 13:59 -------
i've checked the Test0 from example a little on my intel Q9300 cpu.
first case: setup 32-bit code and break on libm.sin implementation.
Breakpoint 1, main (argc=1, argv=0xffffe3c4) at t.c:74
(gdb) b sin
Breakpoint 2 at 0xf7fa7110: file ../sysdeps/i386/fpu/s_sin.S, line 14.
Test 0:
(gdb) p testvalue
$1 = 43998769152
Breakpoint 2, sin () at ../sysdeps/i386/fpu/s_sin.S:14
(gdb) bt
#0 sin () at ../sysdeps/i386/fpu/s_sin.S:14
#1 0x08048682 in main (argc=1, argv=0xffffe3c4) at t.c:81
(gdb) info float
=>R7: Valid 0x4022a3e87f0000000000 +43998769152
11x RCSID("$NetBSD: s_sin.S,v 1.5 1995/05/09 00:25:54 jtc Exp $")
12x
13x ENTRY(__sin)
14x fldl 4(%esp)
15x fxam
16x fstsw %ax
17x movb $0x45, %dh
18x andb %ah, %dh
19x cmpb $0x05, %dh
20x je 3f
21x 4: fsin <==== here we calculate Test0.
22t> fnstsw %ax
23x testl $0x400,%eax
24x jnz 1f
25x ret <==== and return...
26x .align ALIGNARG(4)
27x 1: fldpi
28x fadd %st(0)
29x fxch %st(1)
30x 2: fprem1
31x fnstsw %ax
32x testl $0x400,%eax
33x jnz 2b
34x fstp %st(1)
35x fsin
36x ret
37x 3:
and the hardware result is:
(gdb) info float
=>R7: Valid 0xbfe38c41185b67ffffe4 -4.081936725100227664e-09
sin(43998769152.000000) (i.e. sin(0xa3e87f * 2^12))
is computed as -4.081937e-09 (-0x1.188230b6dp-28)
It SHOULD be ~ -4.025292e-09 (-0x1.149dafd6b8987p-28)
Relative error is 1.407% !!!!
as you can see for 32-bit implementation there's *NO* smart
argument range reduction.
second case: setup 64-bit code.
(gdb) break sin
Breakpoint 2 at 0x7ffff7b79e00: file ../sysdeps/ieee754/dbl-64/s_sin.c, line
90.
(gdb) c
Test 0:
Continuing.
Breakpoint 2, __sin (x=43998769152) at ../sysdeps/ieee754/dbl-64/s_sin.c:90
and here's some kind of range reduction for -105414350 <|x|< 281474976710656.
(gdb) fin
Run till exit from #0 __sin (x=43998769152) at
../sysdeps/ieee754/dbl-64/s_sin.c:235
0x0000000000400882 in main (argc=1, argv=0x7fffffffe298) at t.c:81
Value returned is $1 = -4.0252920638371055e-09
sin(43998769152.000000) (i.e. sin(0xa3e87f * 2^12))
is computed as -4.025292e-09 (-0x1.149dafd6b8987p-28)
It SHOULD be ~ -4.025292e-09 (-0x1.149dafd6b8987p-28)
Relative error is 0.000e+00%
finally, as you can see this NOT a gcc bug. it's a QOI bug in glibc ;)
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43490