diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2018-03-20 16:30:01 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2018-03-20 16:33:01 +0000 |
commit | abaf43d9d88d6fdf7345b936a571d17cfe1fa140 (patch) | |
tree | ca3971da6ca25d2d670305d68722f5fbb2d8c1d2 /compiler/coreSyn | |
parent | 0a778ebeccefe6c3c2540a06d5a1c585f18e01ab (diff) | |
download | haskell-abaf43d9d88d6fdf7345b936a571d17cfe1fa140.tar.gz |
Fix seq# case of exprOkForSpeculation
This subtle patch fixes Trac #5129 (again; comment:20
and following).
I took the opportunity to document seq# properly; see
Note [seq# magic] in PrelRules, and Note [seq# and expr_ok]
in CoreUtils.
Diffstat (limited to 'compiler/coreSyn')
-rw-r--r-- | compiler/coreSyn/CoreUtils.hs | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/compiler/coreSyn/CoreUtils.hs b/compiler/coreSyn/CoreUtils.hs index 4db9d8fc29..5608afc334 100644 --- a/compiler/coreSyn/CoreUtils.hs +++ b/compiler/coreSyn/CoreUtils.hs @@ -1449,8 +1449,11 @@ app_ok primop_ok fun args -- Often there is a literal divisor, and this -- can get rid of a thunk in an inner loop + | SeqOp <- op -- See Note [seq# and expr_ok] + -> all (expr_ok primop_ok) args + | otherwise - -> primop_ok op -- Check the primop itself + -> primop_ok op -- Check the primop itself && and (zipWith arg_ok arg_tys args) -- Check the arguments _other -> isUnliftedType (idType fun) -- c.f. the Var case of exprIsHNF @@ -1607,6 +1610,25 @@ See also Note [dataToTag#] in primops.txt.pp. Bottom line: * in exprOkForSpeculation we simply ignore all lifted arguments. + * except see Note [seq# and expr_ok] for an exception + + +Note [seq# and expr_ok] +~~~~~~~~~~~~~~~~~~~~~~~ +Recall that + seq# :: forall a s . a -> State# s -> (# State# s, a #) +must always evaluate its first argument. So it's really a +counter-example to Note [Primops with lifted arguments]. In +the case of seq# we must check the argument to seq#. Remember +item (d) of the specification of exprOkForSpeculation: + + -- Precisely, it returns @True@ iff: + -- a) The expression guarantees to terminate, + ... + -- d) without throwing a Haskell exception + +The lack of this special case caused Trac #5129 to go bad again. +See comment:24 and following ************************************************************************ |