
#10246: Literal Pattern match loses order -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: closed Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 7.10.1 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: #9533 | Differential Rev(s): Phab:D810 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: patch => closed * resolution: => fixed * milestone: => 8.2.1 Old description:
I found this long-standing bug while investigating #10245:
Consider this code: {{{ f1 :: Int -> String f1 n = case n of 0 -> "bar" 0x10000000000000000 -> "foo" _ -> "c" {-# NOINLINE f1 #-}
g1 :: Int -> String g1 n = if n == 0 then "bar" else if n == 0x10000000000000000 then "foo" else "c" {-# NOINLINE g1 #-}
f2 :: Int -> String f2 n = case n of 0x10000000000000000 -> "foo" 0 -> "bar" _ -> "c" {-# NOINLINE f2 #-}
g2 :: Int -> String g2 n = if n == 0x10000000000000000 then "foo" else if n == 0 then "bar" else "c" {-# NOINLINE g2 #-}
main = do let i = read "0" :: Int print (f1 i) print (g1 i) print (f2 i) print (g2 i) }}}
According to the report, `f1` should behave like `g1` and `f2` should behave like `g2`. But that is not the case: I get {{{ "foo" "bar" "foo" "foo" }}}
The reason is that the branches are sorted, to create fancy code for it, but this does not take into account that `0x10000000000000000 = 0`, at least for `Int`.
This bug is present also in 7.8.4, and not (directly) related to my CmmSwitch code: It can also be observed with interpreted code, so the fix must happen earlier.
New description: I found this long-standing bug while investigating #10245: Consider this code: {{{#!hs f1 :: Int -> String f1 n = case n of 0 -> "bar" 0x10000000000000000 -> "foo" _ -> "c" {-# NOINLINE f1 #-} g1 :: Int -> String g1 n = if n == 0 then "bar" else if n == 0x10000000000000000 then "foo" else "c" {-# NOINLINE g1 #-} f2 :: Int -> String f2 n = case n of 0x10000000000000000 -> "foo" 0 -> "bar" _ -> "c" {-# NOINLINE f2 #-} g2 :: Int -> String g2 n = if n == 0x10000000000000000 then "foo" else if n == 0 then "bar" else "c" {-# NOINLINE g2 #-} main = do let i = read "0" :: Int print (f1 i) print (g1 i) print (f2 i) print (g2 i) }}} According to the report, `f1` should behave like `g1` and `f2` should behave like `g2`. But that is not the case: I get {{{ "foo" "bar" "foo" "foo" }}} The reason is that the branches are sorted, to create fancy code for it, but this does not take into account that `0x10000000000000000 = 0`, at least for `Int`. This bug is present also in 7.8.4, and not (directly) related to my CmmSwitch code: It can also be observed with interpreted code, so the fix must happen earlier. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10246#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler