#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, Phab:D5226 -------------------------------------+------------------------------------- Comment (by osa1): Making progress. We want to handle dataToTag# and seq# uniformly, as they're two exceptional primops that evaluate their arguments. So I added this to `app_ok`: {{{ app_ok primop_ok fun args = case idDetails fun of ... | SeqOp <- op ------------------- OLD CODE -> all (expr_ok primop_ok) args | DataToTagOp <- op ------------- NEW CODE -> all (expr_ok primop_ok) args }}} However this causes let/app invariant errors. Here's an example: {{{ $cpred_a3m9 = \ (a_a2Ix :: VecElem) -> case dataToTag# @ VecElem a_a2Ix of a#_a2Iy { __DEFAULT -> case eqInt (GHC.Types.I# 0#) (GHC.Types.I# a#_a2Iy) of { False -> tagToEnum# @ VecElem (+# a#_a2Iy -1#); True -> error @ 'LiftedRep @ VecElem ($dIP_s4eG `cast` (Sym (GHC.Classes.N:IP[0] <"callStack">_N <GHC.Stack.Types.CallStack>_N) :: GHC.Stack.Types.CallStack ~R# (?callStack::GHC.Stack.Types.CallStack))) (build @ Char (\ (@ b_a44N) -> unpackFoldrCString# @ b_a44N "pred{VecElem}: tried to take `pred' of first tag in enumeration"#)) } } }}} This is OK-for-spec, but FloatOut first transforms this into: {{{ $cpred_a3m9 :: VecElem -> VecElem [LclId, Arity=1] $cpred_a3m9 = \ (a_a2Ix :: VecElem) -> case dataToTag# @ VecElem a_a2Ix of a#_a2Iy { __DEFAULT -> case eqInt lvl_s4yV (I# a#_a2Iy) of { False -> tagToEnum# @ VecElem (+# a#_a2Iy -1#); True -> lvl_s4yY } }, }}} then simplifier: {{{ $cpred_a3m9 = \ (a_a2Ix :: VecElem) -> case a_a2Ix of lwild_s50A [Dmd=<S,U>] { __DEFAULT -> tagToEnum# @ VecElem (+# (dataToTag# @ VecElem a_a2Ix) -1#); Int8ElemRep -> lvl_s4yY } }}} which is not OK-for-spec beucase `a_a2Ix` doesn't have evaldUnfolding. The error message: {{{ *** Core Lint errors : in result of Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}) *** <no location info>: warning: In the expression: +# (dataToTag# @ VecElem a_a2Ix) -1# This argument does not satisfy the let/app invariant: dataToTag# @ VecElem a_a2Ix }}} I don't understand why we substitute `dataToTag# @ VecElem a_a2Ix` for the case binder. Simon, any ideas? (Committed the code to wip/T15696, the error happens during validate) -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15696#comment:85> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler