[GHC] #10246: Literal Pattern match loses order

#10246: Literal Pattern match loses order -------------------------------------+------------------------------------- Reporter: nomeata | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Blocked By: Test Case: | Related Tickets: Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- 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. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10246 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10246: Literal Pattern match loses order
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Comment (by Joachim Breitner

#10246: Literal Pattern match loses order -------------------------------------+------------------------------------- Reporter: nomeata | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by nomeata): * cc: rwbarton, simonmar (added) Comment: Currently, the above code will produce {{{ ghc-stage2: panic! (the 'impossible' happened) (GHC version 7.11.20150403 for x86_64-unknown-linux): ASSERT failed! file compiler/basicTypes/Literal.hs line 220 18446744073709551616 }}} Maybe that is a hint as to where this needs to be fixed? Maybe {{{ mkMachInt :: DynFlags -> Integer -> Literal mkMachInt dflags x = ASSERT2( inIntRange dflags x, integer x ) MachInt x }}} is where the clamping to the range of the machine integers should happen? Can we always deduce that from the `dflags`? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10246#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10246: Literal Pattern match loses order -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- Changes (by nomeata): * owner: => nomeata Comment: Or maybe the problem is the part of the code that changes the patter {{{ 0x10000000000000000 -> "foo" }}} to {{{ I# 0x10000000000000000# -> "foo" }}} which would be `tidyNPat` in `MatchLit.hs`. Unfortunately, that is far way from the nearest `dflags`. Maybe `hsLitKey :: DynFlags -> HsLit -> Literal` is a good spot for making sure the literal is in range... that seems to work. I’ll shortly open a DR with some questions to those in the know in these matters. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10246#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10246: Literal Pattern match loses order -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: Phab:D810 -------------------------------------+------------------------------------- Changes (by nomeata): * status: new => patch * differential: => Phab:D810 Comment: See Phab:D810 for a possible fix. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10246#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10246: Literal Pattern match loses order -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: None/Unknown | Unknown/Multiple Blocked By: | Test Case: Related Tickets: #9533 | Blocking: | Differential Revisions: Phab:D810 -------------------------------------+------------------------------------- Changes (by nomeata): * related: => #9533 Comment: Has come up before: #9533. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10246#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#10246: Literal Pattern match loses order
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner: nomeata
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.1
Resolution: | 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
-------------------------------------+-------------------------------------
Comment (by Ben Gamari

#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
participants (1)
-
GHC