[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