Skip to content

Worker/wrapper can break the let-app invariant

Consider this

{-# LANGUAGE MagicHash #-}
module Bar where
import GHC.Exts

data X = A | B | C

data T = MkT !X Int# Int#

f (MkT x 0# _) = True
f (MkT x n  _)  = let v = case x of
                         A -> 1#
                         B -> 2#
                         C -> n
                  in f (MkT x v v)

Compile with -O and (with GHC 8) you'll get

*** Core Lint errors : in result of Simplifier ***
Bar.hs:10:23: Warning:
    [RHS of v_s1IX :: Int#]
    The type of this binder is primitive: v_s1IX
    Binder's type: Int#
*** Offending Program ***
Rec {
f [InlPrag=INLINE[0]] :: T -> Bool
[LclIdX,
 Arity=1,
 Str=DmdType <S(SSL),1*U(U,1*U,A)>,
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False)
         Tmpl= \ (w_s1Jq [Occ=Once!] :: T) ->
                 case w_s1Jq
                 of _ [Occ=Dead]
                 { MkT ww_s1Jt [Occ=Once] ww_s1Ju [Occ=Once] _ [Occ=Dead] ->
                 $wf_s1Jx ww_s1Jt ww_s1Ju
                 }}]
f =
  \ (w_s1Jq :: T) ->
    case w_s1Jq of _ [Occ=Dead] { MkT ww_s1Jt ww_s1Ju ww_s1Jv ->
    $wf_s1Jx ww_s1Jt ww_s1Ju
    }

$wf_s1Jx [InlPrag=[0], Occ=LoopBreaker] :: X -> Int# -> Bool
[LclId,
 Arity=2,
 Str=DmdType <S,U><S,1*U>,
 Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True, Guidance=IF_ARGS [40 30] 80 10}]
$wf_s1Jx =
  \ (ww_s1Jt :: X) (ww_s1Ju :: Int#) ->
    case ww_s1Ju of ds_X1IO [Dmd=<L,1*U>] {
      __DEFAULT ->
        let {
          v_s1IX [Dmd=<S,U>] :: Int#
          [LclId,
           Str=DmdType,
           Unf=Unf{Src=<vanilla>, TopLvl=False, Value=False, ConLike=False,
                   WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}]
          v_s1IX =
            case ww_s1Jt of _ [Occ=Dead, Dmd=<L,A>] {
              A -> 1;
              B -> 2;
              C -> ds_X1IO
            } } in
        $wf_s1Jx ww_s1Jt v_s1IX;
      0 -> True
    }
end Rec }

Reason: in the worker, the lambda-bound arguments don't say they are evaluated, so the previously ok-for-speculation RHS of the 'let' is no longer so.

Trac metadata
Trac field Value
Version 8.0.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information