[GHC] #14680: GHC 8.4.1-alpha panics when optimizing function using getTag and tagToEnum#

GHC ghc-devs at haskell.org
Tue Jan 23 15:33:36 UTC 2018


#14680: GHC 8.4.1-alpha panics when optimizing function using getTag and tagToEnum#
-------------------------------------+-------------------------------------
        Reporter:  RyanGlScott       |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  highest           |            Milestone:  8.4.1
       Component:  Compiler          |              Version:  8.4.1-alpha1
      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):

 It turns out that this is actually generating ill typed Core, as
 demonstrated in this Core Lint error:

 {{{
 $ inplace/bin/ghc-stage2 -O1 -fforce-recomp -dcore-lint ../Bug.hs
 [1 of 1] Compiling Bug              ( ../Bug.hs, ../Bug.o )
 *** Core Lint errors : in result of Simplifier ***
 <no location info>: warning:
     In a case alternative: (TyFamilyEnum3)
     In a case alternative, data constructor isn't in scrutinee type:
     Scrutinee type constructor: TyFamilyEnum
     Data con: TyFamilyEnum3
 *** Offending Program ***

 <elided>

 suc :: TyFamilyEnum -> TyFamilyEnum
 [LclIdX,
  Arity=1,
  Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
          WorkFree=True, Expandable=True, Guidance=IF_ARGS [20] 33 0}]
 suc
   = \ (a_aaf8_awR :: TyFamilyEnum) ->
       case a_aaf8_awR
            `cast` (D:R:TyFamilyEnum0[0]
                    :: (TyFamilyEnum :: *) ~R# (R:TyFamilyEnum :: *))
       of nt_s2jO
       { __DEFAULT ->
       case nt_s2jO
            `cast` (Sym (D:R:TyFamilyEnum0[0])
                    :: (R:TyFamilyEnum :: *) ~R# (TyFamilyEnum :: *))
       of lwild_s2k1 {
         __DEFAULT ->
           case dataToTag# @ TyFamilyEnum lwild_s2k1 of a_aaf9_awS
           { __DEFAULT ->
           (tagToEnum# @ R:TyFamilyEnum (+# a_aaf9_awS 1#))
           `cast` (Sym (D:R:TyFamilyEnum0[0])
                   :: (R:TyFamilyEnum :: *) ~R# (TyFamilyEnum :: *))
           };
         TyFamilyEnum3 ->
           let {
             a_aaf9_awS :: Int#
             [LclId, Unf=OtherCon []]
             a_aaf9_awS = 2# } in
           lvl_s2jL
       }
       }

 *** End of Offense ***
 }}}

 I've highlighted the relevant part, which is the Core for `suc`. Notice
 how it first `cast`s the argument from type `TyFamilyEnum` (the data
 family tycon) to type `R:TyFamilyEnum` (the representation tycon). This
 part is definitely correct, since you can't pattern-match on the argument
 unless it's at the representation type.

 But immediately after this `cast`, it proceeds to `cast` it //again//,
 from type `R:TyFamilyEnum` back to `TyFamilyEnum`! This makes the whole
 `case` expression following it ill typed, and likely results in
 shenanigans later during compilation.

 Now my question is: where is this extra cast coming from?

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14680#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list