summaryrefslogtreecommitdiff
path: root/compiler/coreSyn
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2018-03-20 16:30:01 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2018-03-20 16:33:01 +0000
commitabaf43d9d88d6fdf7345b936a571d17cfe1fa140 (patch)
treeca3971da6ca25d2d670305d68722f5fbb2d8c1d2 /compiler/coreSyn
parent0a778ebeccefe6c3c2540a06d5a1c585f18e01ab (diff)
downloadhaskell-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.hs24
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
************************************************************************