[GHC] #15696: Derived Ord instance for enumerations with more than 8 elements seems to be incorrect

GHC ghc-devs at haskell.org
Fri Oct 19 14:01:49 UTC 2018


#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


More information about the ghc-tickets mailing list