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

GHC ghc-devs at haskell.org
Thu Oct 11 18:39:38 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
-------------------------------------+-------------------------------------

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


More information about the ghc-tickets mailing list