
#13027: Core lint errors compiling containers HEAD with GHC HEAD -------------------------------------+------------------------------------- Reporter: erikd | Owner: Type: bug | Status: new Priority: normal | Milestone: 8.2.1 Component: Compiler | Version: 8.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: Building GHC | Test Case: failed | simplCore/should_compile/T13027 Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj):
Is there some way to make this tracking more robust?
Yes: (1) and (2) are precisely about ensuring that when something is supposed to be evaluated, it really is.
Is there a reason not to make exprOkForSpeculation more lenient for reallyUnsafePtrEquality#
No, no big reason. We could consult the primops strictness info; or we could have a special case in `CoreUtils.app_ok`. -------- HOWEVER, in answering this question I also came across this (in `CoreUtils`): {{{ Note [dataToTag speculation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Is this OK? f x = let v::Int# = dataToTag# x in ... We say "yes", even though 'x' may not be evaluated. Reasons * dataToTag#'s strictness means that its argument often will be evaluated, but FloatOut makes that temporarily untrue case x of y -> let v = dataToTag# y in ... --> case x of y -> let v = dataToTag# x in ... Note that we look at 'x' instead of 'y' (this is to improve floating in FloatOut). So Lint complains. Moreover, it really *might* improve floating to let the v-binding float out * CorePrep makes sure dataToTag#'s argument is evaluated, just before code gen. Until then, it's not guaranteed }}} The plot thickens. When I wrote this I clearly intended that (contrary to (2)) Core would ''not'' guarantee that the argument to `dataToTag#` is evaluated. Instead, we arrange that it is evaluated to being with; accept that may not be true forever; but re-establish it in `CorePrep` if necessary. That is indeed a viable path. Moreover, the first bullet of the above Note is persuasive: guaranteeing evaluated-ness is quite hard! But if we follow that path (an ''alternative'' to the to-dos in comment:21), then we should do consistently: * Ensure that `exprOkForSpeculation` on ''any'' primop does not look at lifted arguments (like the current special case for `dataToTag#`) What about strict constructors? We could use `CorePrep` to ensure that arguments to strict constructors are evaluated, just as we do for `dataToTag#`. But for `dataToTag#` the actual argument must be a pointer to the evaluated object, otherwise `dataToTag#` will fail (give a bogus answer). But for strict constructors all we care about is that the argument has been evaluated (a semantic property), and that is ensured by the wrapper. To be sure, a bogus Core-to-Core pass could apply the constructor to a non-evaluated argument, but nothing would actually go wrong. So arguably it'd be redundant to add extra evals in `CorePrep`. The third to-do in comment:21 would still be useful. Knowing evaluated- ness is always a good thing. Bottom line: this alternative path looks attractive. In summary it would entail * Treating all primops with boxed arguments like `dataToTag#` in `exprOkForSpeculation`. * Documenting the reasoning along the lines above. * Make worker/wrapper produce eval'd flags on the wrapper for CPR. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13027#comment:23 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler