[GHC] #9238: Negative zero broken
GHC
ghc-devs at haskell.org
Fri Nov 14 20:25:23 UTC 2014
#9238: Negative zero broken
-------------------------------------+-------------------------------------
Reporter: augustss | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 7.10.1
Component: Compiler | Version: 7.8.2
Resolution: | Keywords:
Operating System: | Architecture: Unknown/Multiple
Unknown/Multiple | Difficulty: Unknown
Type of failure: Incorrect | Blocked By:
result at runtime | Related Tickets: #7858, #9451
Test Case: |
Blocking: |
Differential Revisions: |
-------------------------------------+-------------------------------------
Description changed by thomie:
Old description:
> Try the following program
> {{{
> compareDouble :: Double -> Double -> Ordering
> compareDouble x y =
> case (isNaN x, isNaN y) of
> (True, True) -> EQ
> (True, False) -> LT
> (False, True) -> GT
> (False, False) ->
> -- Make -0 less than 0
> case (x == 0, y == 0, isNegativeZero x, isNegativeZero y) of
> (True, True, True, False) -> LT
> (True, True, False, True) -> GT
> _ -> x `compare` y
>
> main = do
> let l = [-0, 0]
> print [ (x, y, compareDouble x y) | x <- l, y <- l ]
> }}}
>
> Compile and run with -O0
> {{{
> $ ghc -O0 D.hs
> [1 of 1] Compiling Main ( D.hs, D.o )
> Linking D.exe ...
> $ ./D
> [(-0.0,-0.0,EQ),(-0.0,0.0,LT),(0.0,-0.0,GT),(0.0,0.0,EQ)]
> }}}
> This is the correct output.
>
> Compile and run with -O1
> {{{
> $ ghc -O1 D.hs
> [1 of 1] Compiling Main ( D.hs, D.o )
> Linking D.exe ...
> $ ./D
> [(-0.0,-0.0,LT),(-0.0,0.0,LT),(0.0,-0.0,EQ),(0.0,0.0,EQ)]
> }}}
> This is wrong.
>
> Put a NOINLINE pragma on compareDouble:
> {{{
> $ ghc -O1 D.hs
> [1 of 1] Compiling Main ( D.hs, D.o )
> Linking D.exe ...
> $ ./D
> [(-0.0,-0.0,EQ),(-0.0,0.0,EQ),(0.0,-0.0,EQ),(0.0,0.0,EQ)]
> }}}
> This is wrong in a different way.
New description:
Try the following program
{{{
compareDouble :: Double -> Double -> Ordering
compareDouble x y =
case (isNaN x, isNaN y) of
(True, True) -> EQ
(True, False) -> LT
(False, True) -> GT
(False, False) ->
-- Make -0 less than 0
case (x == 0, y == 0, isNegativeZero x, isNegativeZero y) of
(True, True, True, False) -> LT
(True, True, False, True) -> GT
_ -> x `compare` y
main = do
let l = [-0, 0]
print [ (x, y, compareDouble x y) | x <- l, y <- l ]
}}}
Compile and run with -O0
{{{
$ ghc -O0 -fforce-recomp D.hs
[1 of 1] Compiling Main ( D.hs, D.o )
Linking D.exe ...
$ ./D
[(-0.0,-0.0,EQ),(-0.0,0.0,LT),(0.0,-0.0,GT),(0.0,0.0,EQ)]
}}}
This is the correct output.
Compile and run with -O1
{{{
$ ghc -O1 -fforce-recomp D.hs
[1 of 1] Compiling Main ( D.hs, D.o )
Linking D.exe ...
$ ./D
[(-0.0,-0.0,LT),(-0.0,0.0,LT),(0.0,-0.0,EQ),(0.0,0.0,EQ)]
}}}
This is wrong.
Put a NOINLINE pragma on compareDouble:
{{{
$ ghc -O1 -fforce-recomp D.hs
[1 of 1] Compiling Main ( D.hs, D.o )
Linking D.exe ...
$ ./D
[(-0.0,-0.0,EQ),(-0.0,0.0,EQ),(0.0,-0.0,EQ),(0.0,0.0,EQ)]
}}}
This is wrong in a different way.
--
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9238#comment:10>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list