#4867: Incorrect result from trig functions
-------------------------------+--------------------------------------------
Reporter: gwright | Owner: gwright
Type: bug | Status: new
Priority: high | Milestone: 7.0.2
Component: GHCi | Version: 7.0.1
Keywords: | Testcase:
Blockedby: | Difficulty:
Os: MacOS X | Blocking:
Architecture: x86_64 (amd64) | Failure: Incorrect result at runtime
-------------------------------+--------------------------------------------
Comment(by gwright):
In short, the correct answer is returned by the tanh function in
libSystem.B and is placed on the heap. Below is what `gdb` says.
I start `gdb` and source the `gdbinit` macros and my load `gdb_ghc`
script. The latter is
{{{
gwright-macbook> cat gdb_ghc
file /Users/gwright/tmp/ghc-7-branch/ghc/inplace/lib/ghc-stage2
set args +RTS -V0 -i0 -RTS
-B/Users/gwright/tmp/ghc-7-branch/ghc/inplace/lib -pgmc /usr/bin/gcc-4.2
-pgma /usr/bin/gcc-4.2 -pgml /usr/bin/gcc-4.2 -pgmP "/usr/bin/gcc-4.2 -E
-undef -traditional" --interactive
break tanh
}}}
Here's the transcript:
{{{
gwright-macbook> gdb
GNU gdb 6.3.50-20050815 (Apple version gdb-1510) (Wed Sep 22 02:45:02 UTC
2010)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you
are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "x86_64-apple-darwin".
(gdb) source gdbinit
(gdb) source gdb_ghc
Reading symbols for shared libraries ..... done
Breakpoint 1 at 0x3126e978bbfb80
(gdb) run
Starting program: /Users/gwright/tmp/ghc-7-branch/ghc/inplace/lib/ghc-
stage2 +RTS -V0 -i0 -RTS -B/Users/gwright/tmp/ghc-7-branch/ghc/inplace/lib
-pgmc /usr/bin/gcc-4.2 -pgma /usr/bin/gcc-4.2 -pgml /usr/bin/gcc-4.2 -pgmP
"/usr/bin/gcc-4.2 -E -undef -traditional" --interactive
Reading symbols for shared libraries ++++. done
GHCi, version 7.0.1.20101221: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> tanh(-0.0001)
Breakpoint 1, 0x00007fff80036b80 in tanh$fenv_access_off ()
(gdb)
}}}
continuing from that point to the end of the tanh function,
{{{
(gdb) display/i $rip
1: x/i $rip 0x7fff80036b80 <tanh$fenv_access_off>: movapd %xmm0,%xmm1
(gdb) stepi
0x00007fff80036b84 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036b84 <tanh$fenv_access_off+4>: andpd
0x144054(%rip),%xmm0 # 0x7fff8017abe0 <abs_mask>
(gdb)
0x00007fff80036b8c in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036b8c <tanh$fenv_access_off+12>: movq %xmm0,%rax
(gdb) stepi
0x00007fff80036b91 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036b91 <tanh$fenv_access_off+17>: movapd %xmm1,%xmm7
(gdb) stepi
0x00007fff80036b95 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036b95 <tanh$fenv_access_off+21>: sub
0x130654(%rip),%rax # 0x7fff801671f0 <two>
(gdb) stepi
0x00007fff80036b9c in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036b9c <tanh$fenv_access_off+28>: xorpd %xmm0,%xmm7
(gdb) stepi
0x00007fff80036ba0 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036ba0 <tanh$fenv_access_off+32>: cmp
0x130661(%rip),%rax # 0x7fff80167208 <eighth_m_two+8>
(gdb) stepi
0x00007fff80036ba7 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036ba7 <tanh$fenv_access_off+39>: ja
0x7fff80036cf4 <tanh$fenv_access_off+372>
(gdb) stepi
0x00007fff80036cf4 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036cf4 <tanh$fenv_access_off+372>: jg
0x7fff80036e97 <tanh$fenv_access_off+791>
(gdb) stepi
0x00007fff80036cfa in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036cfa <tanh$fenv_access_off+378>: cmp
0x1304ff(%rip),%rax # 0x7fff80167200 <eighth_m_two>
(gdb) stepi
0x00007fff80036d01 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036d01 <tanh$fenv_access_off+385>: jbe
0x7fff80036dd6 <tanh$fenv_access_off+598>
(gdb) stepi
0x00007fff80036dd6 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036dd6 <tanh$fenv_access_off+598>: cmp
0x13041b(%rip),%rax # 0x7fff801671f8 <tiny_m_two>
(gdb) stepi
0x00007fff80036ddd in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036ddd <tanh$fenv_access_off+605>: jbe
0x7fff80036e31 <tanh$fenv_access_off+689>
(gdb) stepi
0x00007fff80036ddf in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036ddf <tanh$fenv_access_off+607>: lea
0x144a9a(%rip),%rdx # 0x7fff8017b880 <small_poly>
(gdb) stepi
0x00007fff80036de6 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036de6 <tanh$fenv_access_off+614>: mulsd %xmm0,%xmm0
(gdb) stepi
0x00007fff80036dea in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036dea <tanh$fenv_access_off+618>: movapd %xmm1,%xmm2
(gdb) stepi
0x00007fff80036dee in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036dee <tanh$fenv_access_off+622>: mulsd
0x40(%rdx),%xmm1
(gdb) stepi
0x00007fff80036df3 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036df3 <tanh$fenv_access_off+627>: movlhps
%xmm0,%xmm0
(gdb) stepi
0x00007fff80036df6 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036df6 <tanh$fenv_access_off+630>: movapd %xmm0,%xmm3
(gdb) stepi
0x00007fff80036dfa in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036dfa <tanh$fenv_access_off+634>: movapd %xmm3,%xmm4
(gdb) stepi
0x00007fff80036dfe in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036dfe <tanh$fenv_access_off+638>: addpd
(%rdx),%xmm0
(gdb) stepi
0x00007fff80036e02 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e02 <tanh$fenv_access_off+642>: addpd
0x10(%rdx),%xmm3
(gdb) stepi
0x00007fff80036e07 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e07 <tanh$fenv_access_off+647>: mulpd %xmm4,%xmm0
(gdb) stepi
0x00007fff80036e0b in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e0b <tanh$fenv_access_off+651>: mulpd %xmm4,%xmm3
(gdb) stepi
0x00007fff80036e0f in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e0f <tanh$fenv_access_off+655>: mulsd %xmm4,%xmm1
(gdb) stepi
0x00007fff80036e13 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e13 <tanh$fenv_access_off+659>: addpd
0x20(%rdx),%xmm0
(gdb) stepi
0x00007fff80036e18 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e18 <tanh$fenv_access_off+664>: addpd
0x30(%rdx),%xmm3
(gdb) stepi
0x00007fff80036e1d in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e1d <tanh$fenv_access_off+669>: mulpd %xmm3,%xmm0
(gdb) stepi
0x00007fff80036e21 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e21 <tanh$fenv_access_off+673>: mulsd %xmm0,%xmm1
(gdb) stepi
0x00007fff80036e25 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e25 <tanh$fenv_access_off+677>: movhlps
%xmm0,%xmm0
(gdb) stepi
0x00007fff80036e28 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e28 <tanh$fenv_access_off+680>: mulsd %xmm1,%xmm0
(gdb) stepi
0x00007fff80036e2c in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e2c <tanh$fenv_access_off+684>: addsd %xmm2,%xmm0
(gdb) stepi
0x00007fff80036e30 in tanh$fenv_access_off ()
1: x/i $rip 0x7fff80036e30 <tanh$fenv_access_off+688>: retq
(gdb) stepi
0x000000010524fd0c in ?? ()
1: x/i $rip 0x10524fd0c: lea -0x10047b(%rip),%rax #
0x10514f898
(gdb) p $xmm0
$1 = {
v4_float = {3.08506751, -1.63840696e-06, -0.602399945, -2.4928418e+25},
v2_double = {42.888663036703718, -9.9999999666666668e-05},
v16_int8 = {64, 69, 113, -65, -75, -37, -25, 60, -65, 26, 54, -30, -23,
-92, -10, 98},
v8_int16 = {16453, 29119, -18981, -6340, -16614, 14050, -5724, -2462},
v4_int32 = {1078292927, -1243879620, -1088801054, -375064990},
v2_int64 = {4631232860024203068, -4676364914860427678},
uint128 = 0x404571bfb5dbe73cbf1a36e2e9a4f662
}
(gdb)
}}}
The correct answer, about -0.0001, is in $xmm0. Continuing a few more
instructions,
{{{
(gdb) stepi
0x000000010524fd13 in ?? ()
1: x/i $rip 0x10524fd13: mov %rax,-0x8(%r12)
(gdb) stepi
0x000000010524fd18 in ?? ()
1: x/i $rip 0x10524fd18: movsd %xmm0,(%r12)
(gdb) stepi
0x000000010524fd1e in ?? ()
1: x/i $rip 0x10524fd1e: lea -0x7(%r12),%rbx
(gdb) p8 $r12
0x1044a9f90: 0x1044a9f39
0x1044a9f88: 0x1044a9f49
0x1044a9f80: 0x1044a9f58
0x1044a9f78: 0x10094eb08
<ghczm7zi0zi1zi20101221_CoreSyn_UnfIfGoodArgs_con_info>
0x1044a9f70: 0x0
0x1044a9f68: 0x0
0x1044a9f60: 0x102266d01 <ghczmprim_GHCziTypes_ZMZN_closure+1>
0x1044a9f58: 0xbf1a36e2e9a4f662
(gdb) x/gf $r12
0x1044a9f58: -9.9999999666666668e-05
(gdb)
}}}
The correct result is now pointed to by $r12, the heap pointer on x86_64.
So as noted earlier, the hyperbolic tangent is computed correctly and the
right value ends up on the heap. Whatever goes wrong must happen later.
There are about 4600 machine instructions between the end of the tanh and
when the (wrong) answer is printed out. The bug's in there somewhere.
It would be helpful if someone could sketch what ghci does when evaluating
a statement at the prompt. (At least which files to look in; I didn't
find anything about this in the commentary.)
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4867#comment:11>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs