[GHC] #15225: `-fno-state-hack` produces incorrect results in nofib

#15225: `-fno-state-hack` produces incorrect results in nofib
-------------------------------------+-------------------------------------
Reporter: tdammers | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.5
Keywords: | Operating System: Linux
Architecture: x86_64 | Type of failure: Incorrect result
(amd64) | at runtime
Test Case: | Blocked By:
Blocking: | Related Tickets: #7411
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
While investigating #7411, I found that nofib fails with incorrect output
from the `fasta` test.
A vanilla `prof` build behaves normally; however, with the following
modifications, `nofib` fails:
- Compile GHC from scratch with:
{{{
GhcStage2HcOpts = -O -fno-state-hack
GhcLibHcOpts = -O -fno-state-hack
}}}
- Run nofib with `EXTRA_HC_OPTS=-fno-state-hack`
Doing this, the nofib test output is:
{{{
------------------------------------------------------------------------
== make all --no-print-directory;
in /home/tobias/well-typed/devel/ghc/HEAD/nofib/shootout/fasta
------------------------------------------------------------------------
HC = /home/tobias/well-typed/devel/ghc/HEAD/inplace/bin/ghc-stage2
HC_OPTS = -O2 -Rghc-timing -H32m -hisuf hi -fno-state-hack -O2 -rtsopts
-O2 -XBangPatterns -XOverloadedStrings -package bytestring
RUNTEST_OPTS = -ghc-timing
==nofib== fasta: time to compile Main follows...
/home/tobias/well-typed/devel/ghc/HEAD/inplace/bin/ghc-stage2 -O2 -Rghc-
timing -H32m -hisuf hi -fno-state-hack -O2 -rtsopts -O2 -XBangPatterns
-XOverloadedStrings -package bytestring -c Main.hs -o Main.o
Main.hs:30:1: warning: [-Wtabs]
Tab character found here, and in 13 further locations.
Please use spaces instead.
|
30 | let !k = min modulus (floor (fromIntegral modulus *
(p::Float) + 1))
| ^^^^^^^^
<

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by alpmestan): * cc: alpmestan (added) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by tdammers): * owner: (none) => tdammers -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by tdammers): Running only nofib with `-fno-state-hack`, but with GHC and libraries compiled normally, the problem does not appear. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by tdammers): Two more test runs: - GHC with state hack, libraries without state hack, nofib without state hack triggers problem - GHC with state hack, libraries without state hack, nofib with state hack does not trigger problem So apparently, in order to trigger the problem, both nofib and libraries must be compiled with `-fno-state-hack`. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by tdammers): So here's a hint. The documentation to `unsafeUseAsCString` mentions this:
After calling this function the `CString` shares the underlying byte buffer with the original `ByteString`. Thus **modifying the `CString`**, either in C, or **using poke**, will cause the contents of the `ByteString` to change, **breaking referential transparency**. Other `ByteStrings` created by sharing (such as those produced via 'take' or 'drop') will also reflect these changes. Modifying the `CString` will break referential transparency. To avoid this, use `useAsCString`, which makes a copy of the original `ByteString`.
(emphasis mine). And then in the `fasta/Main.hs` source code, we see this: {{{#!hs unsafeUseAsCString line $ \ptr -> do --- snip --- plusPtr ptr i `poke` unsafeIndex lookupTable newseed --- snip --- }}} In other words, `fasta` does exactly what the documentation says not to do. Which would suggest that the state hack itself isn't really to blame, it just causes different sharing behavior. I'll run a few tests to get more certainty here. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): Yikes! Indeed that does look quite suspicious since `line` is also used elsewhere in this block. Sounds like this is the culprit. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib
-------------------------------------+-------------------------------------
Reporter: tdammers | Owner: tdammers
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.5
Resolution: | Keywords:
Operating System: Linux | Architecture: x86_64
Type of failure: Incorrect result | (amd64)
at runtime | Test Case:
Blocked By: | Blocking:
Related Tickets: #7411 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by tdammers):
I quickly and naively tried just using `useAsCString` instead of
`unsafeUseAsCString`, but of course that doesn't quite work - probably
because the code relies on actually manipulating the bytestring in place,
whereas `useAsCString` creates a copy and manipulates that. So the output
no longer matches that of the C implementation, but the `-fno-state-hack`
flag no longer causes the output to differ.
So I went a step further, and rewrote the relevant part in more idiomatic
Haskell, using `ByteString.unfoldrN` instead of manipulating C strings in-
place:
{{{#!diff
commit dc2753f4e10fec79c02ed293b72573f1aeaa2271
Author: Tobias Dammers

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Phab:D4868 Wiki Page: | -------------------------------------+------------------------------------- Changes (by tdammers): * differential: => Phab:D4868 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15225: `-fno-state-hack` produces incorrect results in nofib -------------------------------------+------------------------------------- Reporter: tdammers | Owner: tdammers Type: bug | Status: closed Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.5 Resolution: fixed | Keywords: Operating System: Linux | Architecture: x86_64 Type of failure: Incorrect result | (amd64) at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #7411 | Differential Rev(s): Phab:D4868 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: new => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15225#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC