[GHC] #9533: Signed/unsigned integer difference between compiled and interpreted code
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: MichaelBurge | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Keywords: | Operating System: Windows Architecture: x86_64 (amd64) | Type of failure: Incorrect Difficulty: Unknown | result at runtime Blocked By: | Test Case: Related Tickets: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- The following code outputs "A". {{{#!hs import Data.Word x :: Word x = 10 y :: Word y = 11 test = case x - y of -1 -> "A" _ -> "B" main = putStrLn $ show test }}} However, adding a new case that isn't matched causes the output to change: {{{#!hs import Data.Word x :: Word x = 10 y :: Word y = 11 test = case x - y of 5 -> "C" -1 -> "A" _ -> "B" main = putStrLn $ show test }}} With the extra '5 -> "C"' line in the case, the output is "B". It gets weirder - interpreted code actually continues to match the -1 case. With the second example in a file 'T.hs', here is a GHCi session: {{{ Prelude Main> :l *T.hs [1 of 1] Compiling Main ( T.hs, interpreted ) Ok, modules loaded: Main. *Main> main "A" *Main> :l T.hs Ok, modules loaded: Main. Prelude Main> main "B" Prelude Main> }}} These examples suggest to me at least 3 improvements: * Issue a warning when a negative number is used in a case statement in unsigned context * Interpreted code should give the same result as compiled code * Adding a case that isn't matched shouldn't change which other patterns get matched -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: | Owner: MichaelBurge | Status: new Type: bug | Milestone: Priority: high | Version: 7.8.3 Component: Compiler | Keywords: Resolution: | Architecture: x86_64 (amd64) Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: Incorrect | Related Tickets: result at runtime | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by rwbarton): * priority: normal => high * os: Windows => Unknown/Multiple Comment: Wow, nice catch. Something is wrong with the translation of STG-level `case` on `Word#` into Cmm. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: | Owner: MichaelBurge | Status: new Type: bug | Milestone: Priority: high | Version: 7.8.3 Component: Compiler | Keywords: Resolution: | Architecture: x86_64 (amd64) Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: Incorrect | Related Tickets: result at runtime | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by rwbarton): It's not specific to `Word#` actually. The following program has the same wrong behavior. {{{ x :: Int x = 11 y :: Int y = 10 test = case x - y of 3 -> "D" -- comment out either of these two lines and output will be "A" 5 -> "C" 18446744073709551617 -> "A" -- 2^64 + 1 _ -> "B" main = putStrLn $ show test }}} If I build ghc with `-DDEBUG` I get panics like {{{ ghc-stage2: panic! (the 'impossible' happened) (GHC version 7.9.20140831 for x86_64-unknown-linux): ASSERT failed! file compiler/basicTypes/Literal.lhs line 222 18446744073709551617 }}} so I suppose the error is really in creating these `Literal`s with out-of- range values. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: | Owner: MichaelBurge | Status: new Type: bug | Milestone: Priority: high | Version: 7.8.3 Component: Compiler | Keywords: Resolution: | Architecture: x86_64 (amd64) Operating System: | Difficulty: Unknown Unknown/Multiple | Blocked By: Type of failure: Incorrect | Related Tickets: result at runtime | Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by rwbarton): Some more good stuff. {{{ test = case 1 :: Int of 18446744073709551617 -> "A" -- 2^64 + 1 _ -> "B" main = putStrLn $ show test }}} prints "B". The `KnownBranch` optimization fires (even without `-O`) and thinks that 1 is not 18446744073709551617. I'm inclined to conclude that Core `Literal`s should always be wrapped to the range of integers that their type can represent. I assume that `HsLit`s should hold the actual integer in the source program, though, so we can display expressions as the user wrote them. Simon, any thoughts? Also, there is no warning about the out-of-range literal patterns in any of these programs. Perhaps that ought to be a separate feature request ticket. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: MichaelBurge | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by nomeata): Also see #10246, which is basically the same, it seems. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: MichaelBurge | Owner: Type: bug | Status: new Priority: high | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): I created #13256 and #13257 for the suggestion of "Issue a warning when a negative number is used in a case statement in unsigned context". -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: MichaelBurge | Owner: (none) Type: bug | Status: new Priority: high | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Ben Gamari <ben@…>): In [changeset:"6dfc5ebf70df8f0fdccc5004d914b777f21f3b72/ghc" 6dfc5eb/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="6dfc5ebf70df8f0fdccc5004d914b777f21f3b72" Ensure that Literals are in range This commit fixes several bugs related to case expressions involving numeric literals which are not in the range of values of their (fixed-width, integral) type. There is a new invariant on Literal: The argument of a MachInt[64] or MachWord[64] must lie within the range of the corresponding primitive type Int[64]# or Word[64]#, as defined by the target machine. This invariant is enforced in mkMachInt[64]/mkMachWord[64] by wrapping the argument to the target type's range if necessary. Test Plan: Test Plan: make slowtest TEST="T9533 T9533b T9533c T10245 T10246" Trac issues: #9533, #10245, #10246, #13171 Reviewers: simonmar, simonpj, austin, bgamari, nomeata Reviewed By: bgamari Subscribers: thomie, rwbarton Differential Revision: https://phabricator.haskell.org/D810 }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#9533: Signed/unsigned integer difference between compiled and interpreted code -------------------------------------+------------------------------------- Reporter: MichaelBurge | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: 8.2.1 Component: Compiler | Version: 7.8.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => closed * resolution: => fixed * milestone: => 8.2.1 -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9533#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC