Skip to content

Faulty Word64 arithmetic if optimized

The following program produces different results depending on optimization:

Checked.hs:

module Checked ((.-.)) where

(.-.) :: (Bounded a, Integral a) => a -> a -> Maybe a
x .-. y | x >= 0 && y < 0 = if z > x  then Just z
                                      else Nothing
        | x >= 0          = if z <= x then Just z
                                      else Nothing
        | x < 0 && y > 0  = if z < x  then Just z
                                      else Nothing
        | otherwise       = Just z
    where z = x - y

Main.hs:

module Main (main) where

import Data.Maybe
import Data.Word
import Numeric
import Checked

main :: IO ()
main = print $ showHex (fromJust ((0xFFFFFFFF00000000 :: Word64) .-. 0x00000000FFFFFFFF)) ""
D:\dev\haskell\ch1>ghc --make Checked.hs Main.hs
[1 of 2] Compiling Checked          ( Checked.hs, Checked.o )
[2 of 2] Compiling Main             ( Main.hs, Main.o )
Linking Main.exe ...

D:\dev\haskell\ch1>Main.exe
"fffffffe00000001"

D:\dev\haskell\ch1>del *.hi *.o *.exe

D:\dev\haskell\ch1>ghc --make -O2 Checked.hs Main.hs
[1 of 2] Compiling Checked          ( Checked.hs, Checked.o )
[2 of 2] Compiling Main             ( Main.hs, Main.o )
Linking Main.exe ...

D:\dev\haskell\ch1>Main.exe
"fffe00000001"

D:\dev\haskell\ch1>

The bug disappears if definition and usage of (.-.) are in the same module.

Trac metadata
Trac field Value
Version 7.4.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information