#15696: Derived Ord instance for enumerations with more than 8 elements seems to be incorrect -------------------------------------+------------------------------------- Reporter: mrkkrp | Owner: osa1 Type: bug | Status: patch Priority: highest | Milestone: 8.6.2 Component: Compiler | Version: 8.6.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: #14677, #15155 | Differential Rev(s): Phab:D5196, Wiki Page: | Phab:D5201 -------------------------------------+------------------------------------- Comment (by simonpj): I took a look 1. We should give `dataToTag#` a strictness signatures in `primops.txt.pp`. After all, it's strict. If we do that then, {{{ case x of y { DEFAULT -> daataToTag# y } }}} will correctly optimise to `dataToTag# x`. 2. We should remove the bang from `GHC.Base.getTag`. Currenlty it says {{{ getTag !x = dataToTag# x }}} But now the bang is unnecessary, and has to be optimised away by (1). 3. That's also the source of the extra stuff like {{{ case a#_a4k2 :: Int# of a#_X4Mq [Dmd=<L,A>] { __DEFAULT -> ... } }}} which you report in comment:70. This is ''not'' the output of the simplifier; since that simplifier run we have done (a) exitification, (b) float-out and (c) CSE. The last of these left those redudant cases; they would, I believe, disappear in the next simplifier run (if only we reached it). But after (1) and (2) they won't even be there in the first place. 4. I see why the ASSERT trips. In the ''input'' to float-in we have {{{ case a#_a4k2 :: Int# of a#_X4Mq { __DEFAULT -> 1# } }}} So float-in picks up that case-expression and pushes it inwards. But it immediately hits the literal. The ASSERT wasn't expecting to have bindings that were ''dead'' in the input; but here is exactly such a binding, and there's nothign actually wrong with it. The same ASSERT failure would happen with {{{ let x = e in 1# }}} Of course the simplifer would usually eliminate such a thing, but there is no reason for float-in to require that. Just change {{{ fiExpr _ to_drop (_, AnnLit lit) = ASSERT( null to_drop ) Lit lit }}} to {{{ fiExpr _ to_drop (_, AnnLit lit) = wrapFloats to_drop (Lit lit) -- See Note [Dead bindings] {- Note dead bindings ~~~~~~~~~~~~~~~~~~~~~ At a literal we won't usually have any floated bindings; the only way that can happen is if the binding wrapped the literal /in the original input program/. e.g. case x of { DEFAULT -> 1# } But, while this may be unusual it is not actually wrong, and it did once happen (Trac #15696). }} -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15696#comment:73> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler