logo       

RE: succ optimization bug with derived Eq and Enum: msg#00001

lang.haskell.glasgow.bugs

Subject: RE: succ optimization bug with derived Eq and Enum

Brian

Thanks for reporting this grievous bug. It's now fixed and there's a
test in the regression suite for it (cg055). Particular thanks for
boiling it down to such a small case.

Simon

| -----Original Message-----
| From: glasgow-haskell-bugs-bounces@xxxxxxxxxxx
[mailto:glasgow-haskell-bugs-
| bounces@xxxxxxxxxxx] On Behalf Of Brian Alliet
| Sent: 20 January 2005 13:13
| To: glasgow-haskell-bugs@xxxxxxxxxxx
| Subject: succ optimization bug with derived Eq and Enum
|
| GHC 6.2.2 (and a few older 6.2.x versions I tried) seems to improperly
| optimize the expression "succ x == y" when using the derived Eq and
Enum
| instances. Using the data declaration below "isFive Five" will be
False.
|
| data Digit = Zero | One | Two | Three | Four | Five
| | Six | Seven | Eight deriving (Eq,Enum)
| isFive x = succ x == Six
|
| This only happens when using the derived Eq and Enum. If either of
| them are replaced with a hand written instance everything works fine.
It
| also has something to do with the number constructors the datatype
has. If
| there are less than 9 constructors everything works fine. Finally, the
bug
| only shows up when the -O flag is used.
|
| Plenty more details (including a self contained test case) are below.
|
| -Brian
|
| transam:~/tmp$ cat GHCBug.lhs
| \begin{code}
| import System (getArgs)
|
| -- NOTE: When if you remove Eight (or any other constructor)
everything works
| -- Having at least 9 constructors has something to do with the bug
| data Digit = Zero | One | Two | Three | Four | Five | Six | Seven |
Eight
| deriving (Eq,Enum)
|
| instance Show Digit where
| show Five = "Five"
| show Six = "Six"
| show _ = undefined
|
| -- Use either of these instances (instead of derived) and everything
works
| {-instance Enum Digit where
| fromEnum Five = 5
| fromEnum _ = undefined
| toEnum 6 = Six
| toEnum _ = undefined-}
|
| {-instance Eq Digit where
| Five == Five = True
| Six == Six = True
| _ == _ = undefined-}
|
| isFive :: Digit -> Bool
| isFive a = succ a == Six
|
| main :: IO()
| main = do
| putStrLn ("======")
| -- These next two lines are just here to keep ghc from optimizing
away stuff
| args <- getArgs
| let x = if length args == -1 then undefined else Five
| putStrLn ("x: " ++ show x)
| let y = succ x
| putStrLn ("let y = succ x")
| putStrLn ("y: " ++ show y)
| putStrLn ("y == Six: " ++ show (y == Six))
| putStrLn ("succ x == Six: " ++ show (succ x == Six))
| putStrLn ("isFive x: " ++ show (isFive x))
| \end{code}
| transam:~/tmp$ ghc -no-recomp -o GHCBug GHCBug.lhs && ./GHCBug
| ======
| x: Five
| let y = succ x
| y: Six
| y == Six: True
| succ x == Six: True
| isFive x: True
| transam:~/tmp$ ghc -O -no-recomp -o GHCBug GHCBug.lhs && ./GHCBug
| ======
| x: Five
| let y = succ x
| y: Six
| y == Six: True
| succ x == Six: False
| isFive x: False
| transam:~/tmp$ ghci GHCBug.lhs
| ___ ___ _
| / _ \ /\ /\/ __(_)
| / /_\// /_/ / / | | GHC Interactive, version 6.2.2, for Haskell
98.
| / /_\\/ __ / /___| | http://www.haskell.org/ghc/
| \____/\/ /_/\____/|_| Type :? for help.
|
| Loading package base ... linking ... done.
| Skipping Main ( GHCBug.lhs, GHCBug.o )
| Ok, modules loaded: Main.
| Prelude Main> isFive Five
| Loading package haskell98 ... linking ... done.
| False
| Prelude Main> :q
| Leaving GHCi.
| _______________________________________________
| Glasgow-haskell-bugs mailing list
| Glasgow-haskell-bugs@xxxxxxxxxxx
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise