[GHC] #13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: Compile-time Unknown/Multiple | crash or panic Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Giving GHC 8.0.2rc2 a closer look I stumbled over this one: This works fine in GHC 7.10.3, but fails to compile with GHC 8.0.2rc2: {{{ Resolving dependencies... In order, the following will be built (use -v for more details): - vivid-0.1.0.3 {vivid-0.1.0.3-inplace} (lib) (first run) Configuring component lib from vivid-0.1.0.3... Preprocessing library vivid-0.1.0.3... [ 1 of 10] Compiling Vivid.SynthDef.Types ( Vivid/SynthDef/Types.hs, /tmp/vivid-0.1.0.3/dist- newstyle/build/x86_64-linux/ghc-8.0.1.20161213/vivid-0.1.0.3/build/Vivid/SynthDef/Types.o ) [ 2 of 10] Compiling Vivid.SynthDef.CrazyTypes ( Vivid/SynthDef/CrazyTypes.hs, /tmp/vivid-0.1.0.3/dist- newstyle/build/x86_64-linux/ghc-8.0.1.20161213/vivid-0.1.0.3/build/Vivid/SynthDef/CrazyTypes.o ) [ 3 of 10] Compiling Vivid.OSC.Util ( Vivid/OSC/Util.hs, /tmp/vivid-0.1.0.3/dist- newstyle/build/x86_64-linux/ghc-8.0.1.20161213/vivid-0.1.0.3/build/Vivid/OSC/Util.o ) [ 4 of 10] Compiling Vivid.SynthDef.Literally ( Vivid/SynthDef/Literally.hs, /tmp/vivid-0.1.0.3/dist- newstyle/build/x86_64-linux/ghc-8.0.1.20161213/vivid-0.1.0.3/build/Vivid/SynthDef/Literally.o ) [ 5 of 10] Compiling Vivid.OSC ( Vivid/OSC.hs, /tmp/vivid-0.1.0.3 /dist- newstyle/build/x86_64-linux/ghc-8.0.1.20161213/vivid-0.1.0.3/build/Vivid/OSC.o ) [ 6 of 10] Compiling Vivid.SCServer ( Vivid/SCServer.hs, /tmp/vivid-0.1.0.3/dist- newstyle/build/x86_64-linux/ghc-8.0.1.20161213/vivid-0.1.0.3/build/Vivid/SCServer.o ) /tmp/ghc12095_0/ghc_27.s: Assembler messages: /tmp/ghc12095_0/ghc_27.s:5860:0: error: Error: symbol `vividzm0zi1zi0zi3zminplace_VividziSCServer_scServerState_closure' is already defined /tmp/ghc12095_0/ghc_27.s:10988:0: error: Error: symbol `vividzm0zi1zi0zi3zminplace_VividziSCServer_scServerState_closure' is already defined /tmp/ghc12095_0/ghc_27.s:11751:0: error: Error: symbol `vividzm0zi1zi0zi3zminplace_VividziSCServer_scServerState_closure' is already defined `gcc' failed in phase `Assembler'. (Exit code: 1) }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by RyanGlScott): Here's a minimized version with no dependencies: {{{#!hs {-# LANGUAGE BangPatterns #-} module Bug (foo, bar) where import Data.IORef (IORef, newIORef, readIORef, writeIORef) import System.IO.Unsafe (unsafePerformIO) {-# NOINLINE scServerState #-} scServerState :: SCServerState scServerState = unsafePerformIO (return undefined) data SCServerState = SCServerState { scServer_socket :: IORef (Maybe Int) } foo :: IO Int foo = do let !_ = scServerState readIORef (scServer_socket scServerState) >>= \xs -> case xs of Nothing -> do s <- undefined writeIORef (scServer_socket scServerState) (Just s) return s Just s -> return s bar :: IO () bar = do let !_ = scServerState return () }}} You can get this error message with GHC 8.0.1, 8.0.2, or HEAD: {{{ $ /opt/ghc/8.0.1/bin/ghc -fforce-recomp -O1 Bug.hs [1 of 1] Compiling Bug ( Bug.hs, Bug.o ) /tmp/ghc654_0/ghc_2.s: Assembler messages: /tmp/ghc654_0/ghc_2.s:562:0: error: Error: symbol `Bug_scServerState_closure' is already defined `gcc' failed in phase `Assembler'. (Exit code: 1) }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:1> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): I think this is a duplicate of an existing ticket, the `let !_ = ...` "pattern" looks familiar. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:2> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by RyanGlScott): * cc: simonpj (added) Comment: Simon's commit 649cb346a38684df2e932987065817c5cafc2d90 is responsible for this regression. Reid, do you know which ticket this is a dupe of? If so, I'll close this in favor of that one. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:3> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by rwbarton): * related: => #12595 Comment: Hmm, it was #12595, but it claims to have been fixed in 8.0 already. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:4> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.2 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): I did a bit of digging into what is happening here: early in simplification we have the core, {{{#!hs scServerState [InlPrag=NOINLINE] :: SCServerState scServerState = ... foo_s1Sx :: State# RealWorld -> (# State# RealWorld, Int #) foo_s1Sx = \ (eta_B1 [OS=OneShot] :: State# RealWorld) -> case case scServerState of _ [InlPrag=NOINLINE, Occ=Dead] { SCServerState ipv_s1S8 -> GHC.Tuple.() } of _ [Occ=Dead] { () -> ... }}} Eventually case-of-case (and perhaps something else) fires, giving us, {{{#!hs foo_s1Sx = \ (eta_B1 [OS=OneShot] :: State# GHC.Prim.RealWorld) -> case scServerState of scServerState [InlPrag=NOINLINE] { SCServerState ipv_s1S8 -> case scServerState of _ [Occ=Dead] { SCServerState ds_d1Qj -> ... }}} Note that we are now shadowing the `scServerState` binder. This already seems suspicious. This then gets transformed to a `let` by the lifted case elimination simplification (see `Note [Case elimination: lifted case]`), {{{#!hs -- from phase foo_s1Sx = \ (eta_B1 [Dmd=<S,U>, OS=OneShot] :: State# GHC.Prim.RealWorld) -> let { scServerState [InlPrag=NOINLINE, Dmd=<S(S(S)),1*U(1*U(U))>] :: SCServerState [LclId, Str=DmdType, Unf=Unf{Src=<vanilla>, TopLvl=False, Value=False, ConLike=False, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True)}] scServerState = scServerState } in case scServerState of _ [Occ=Dead, Dmd=<L,A>] { SCServerState ds_d1Qj [Dmd=<S(S),1*U(U)>] -> ... }}} The let-bound `scServerState` is then floated to the top-level, resulting in the duplicate closures we see here. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:5> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.3 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * milestone: 8.0.2 => 8.0.3 Comment: I'm going to bump this off until a possible 8.0.3. It's unfortunate that such a regression will be present in 8.0.2, likely the last release in the 8.0 series, but I just can't afford to push the release at this point. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:6> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.0.3 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by Simon Peyton Jones <simonpj@…>): In [changeset:"baf9ebe55a51827c0511b3a670e60b9bb3617ab5/ghc" baf9ebe5/ghc]: {{{ #!CommitTicketReference repository="ghc" revision="baf9ebe55a51827c0511b3a670e60b9bb3617ab5" Ensure nested binders have Internal Names This is a long-standing bug. A nested (non-top-level) binder in Core should not have an External Name, like M.x. But - Lint was not checking this invariant - The desugarer could generate programs that failed the invariant. An example is in tests/deSugar/should_compile/T13043, which had let !_ = M.scState in ... This desugared to let ds = case M.scSate of M.scState { DEFAULT -> () } in case ds of () -> ... We were wrongly re-using that scrutinee as a case binder. And Trac #13043 showed that could ultimately lead to two top-level bindings with the same closure name. Alas! - The desugarer had one other place (in DsUtils.mkCoreAppDs) that could generate bogus code This patch fixes all three bugs, and adds a regression test. }}} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:7> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: merge Priority: normal | Milestone: 8.0.3 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by simonpj): * status: new => merge Comment: Turns out that my patch in comment:3 didn't cause the bug, but it did ''expose'' it. It's been there for ages! Anyway fixed now. Merge to 8.0.3. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:8> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
#13043: GHC 7.10->8.0 regression: GHC code-generates duplicate _closures -------------------------------------+------------------------------------- Reporter: hvr | Owner: Type: bug | Status: merge Priority: normal | Milestone: 8.0.3 Component: Compiler | Version: 8.0.2-rc2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Compile-time | Unknown/Multiple crash or panic | Test Case: Blocked By: | Blocking: Related Tickets: #12595 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): PS thank you for a nice repro case -- made it far easier to find. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13043#comment:9> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler
participants (1)
-
GHC