Magnus pushed to branch wip/mangoiv/9.12.5-rc3-fixes at Glasgow Haskell Compiler / GHC
Commits:
-
f7e9b9c5
by Zubin Duggal at 2026-07-11T11:19:06+02:00
8 changed files:
- changelog.d/fix-absent-dict-projection
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Types/Literal.hs
- testsuite/tests/dmdanal/should_compile/T18982.stderr
Changes:
| 1 | 1 | section: compiler
|
| 2 | -synopsis: Fix a CorePrep miscompilation that could project a field out of an absent dictionary, resulting in a segfault.
|
|
| 2 | +synopsis: Fix a miscompilation that could project a field out of an absent dictionary, resulting in a segfault.
|
|
| 3 | 3 | issues: #25924
|
| 4 | 4 | mrs: !16219
|
| 5 | -description: We no longer speculatively evaluate bindings that we have already discovered are absent. |
|
| 5 | +description:
|
|
| 6 | + We no longer make an absent filler (a rubbish literal or error thunk) for an
|
|
| 7 | + absent dictionary or other terminating type. We also no longer speculatively
|
|
| 8 | + evaluate a binding once we have discovered that it is absent. |
| ... | ... | @@ -219,13 +219,16 @@ mkLitRubbish :: Type -> Maybe CoreExpr |
| 219 | 219 | -- Fail (returning Nothing) if
|
| 220 | 220 | -- * the RuntimeRep of the Type is not monomorphic;
|
| 221 | 221 | -- * the type is (a ~# b), the type of coercion
|
| 222 | --- See INVARIANT 1 and 2 of item (2) in Note [Rubbish literals]
|
|
| 222 | +-- * the type is terminating (isTerminatingType), e.g. a dictionary
|
|
| 223 | +-- See INVARIANT 1, 2 and 3 of item (2) in Note [Rubbish literals]
|
|
| 223 | 224 | -- in GHC.Types.Literal
|
| 224 | 225 | mkLitRubbish ty
|
| 225 | 226 | | not (noFreeVarsOfType rep)
|
| 226 | 227 | = Nothing -- Satisfy INVARIANT 1
|
| 227 | 228 | | isCoVarType ty
|
| 228 | 229 | = Nothing -- Satisfy INVARIANT 2
|
| 230 | + | isTerminatingType ty
|
|
| 231 | + = Nothing -- Satisfy INVARIANT 3
|
|
| 229 | 232 | | otherwise
|
| 230 | 233 | = Just (Lit (LitRubbish torc rep) `mkTyApps` [ty])
|
| 231 | 234 | where
|
| ... | ... | @@ -20,11 +20,13 @@ import GHC.Core.Multiplicity |
| 20 | 20 | import GHC.Core.SimpleOpt( defaultSimpleOpts, simpleOptExprWith )
|
| 21 | 21 | import GHC.Core.Predicate
|
| 22 | 22 | import GHC.Core.Coercion( Coercion )
|
| 23 | +import GHC.Core.DataCon ( StrictnessMark (..) )
|
|
| 23 | 24 | import GHC.Core.Opt.Monad
|
| 25 | + |
|
| 24 | 26 | import qualified GHC.Core.Subst as Core
|
| 25 | 27 | import GHC.Core.Unfold.Make
|
| 26 | 28 | import GHC.Core
|
| 27 | -import GHC.Core.Make ( mkLitRubbish )
|
|
| 29 | +import GHC.Core.Opt.WorkWrap.Utils ( mkAbsentFiller )
|
|
| 28 | 30 | import GHC.Core.Unify ( tcMatchTy )
|
| 29 | 31 | import GHC.Core.Rules
|
| 30 | 32 | import GHC.Core.Utils ( exprIsTrivial, exprIsTopLevelBindable
|
| ... | ... | @@ -1711,7 +1713,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
| 1711 | 1713 | |
| 1712 | 1714 | ; ( useful, rhs_env2, leftover_bndrs
|
| 1713 | 1715 | , rule_bndrs, rule_lhs_args
|
| 1714 | - , spec_bndrs1, dx_binds, spec_args) <- specHeader env rhs_bndrs all_call_args
|
|
| 1716 | + , spec_bndrs1, dx_binds, spec_args) <- specHeader this_mod env rhs_bndrs all_call_args
|
|
| 1715 | 1717 | |
| 1716 | 1718 | -- ; pprTrace "spec_call" (vcat
|
| 1717 | 1719 | -- [ text "fun: " <+> ppr fn
|
| ... | ... | @@ -2562,7 +2564,8 @@ isSpecDict _ = False |
| 2562 | 2564 | -- , [T1, T2, c, i, dEqT1, dShow1]
|
| 2563 | 2565 | -- )
|
| 2564 | 2566 | specHeader
|
| 2565 | - :: SpecEnv
|
|
| 2567 | + :: Module -- The module being compiled, for mkAbsentFiller
|
|
| 2568 | + -> SpecEnv
|
|
| 2566 | 2569 | -> [InBndr] -- The binders from the original function 'f'
|
| 2567 | 2570 | -> [SpecArg] -- From the CallInfo
|
| 2568 | 2571 | -> SpecM ( Bool -- True <=> some useful specialisation happened
|
| ... | ... | @@ -2588,7 +2591,7 @@ specHeader |
| 2588 | 2591 | -- We want to specialise on type 'T1', and so we must construct a substitution
|
| 2589 | 2592 | -- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding
|
| 2590 | 2593 | -- details.
|
| 2591 | -specHeader env (bndr : bndrs) (SpecType ty : args)
|
|
| 2594 | +specHeader mod env (bndr : bndrs) (SpecType ty : args)
|
|
| 2592 | 2595 | = do { -- Find qvars, the type variables to add to the binders for the rule
|
| 2593 | 2596 | -- Namely those free in `ty` that aren't in scope
|
| 2594 | 2597 | -- See (MP2) in Note [Specialising polymorphic dictionaries]
|
| ... | ... | @@ -2600,7 +2603,7 @@ specHeader env (bndr : bndrs) (SpecType ty : args) |
| 2600 | 2603 | ty' = substTy env1 ty
|
| 2601 | 2604 | env2 = extendTvSubst env1 bndr ty'
|
| 2602 | 2605 | ; (useful, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
| 2603 | - <- specHeader env2 bndrs args
|
|
| 2606 | + <- specHeader mod env2 bndrs args
|
|
| 2604 | 2607 | ; pure ( useful
|
| 2605 | 2608 | , env3
|
| 2606 | 2609 | , leftover_bndrs
|
| ... | ... | @@ -2616,10 +2619,10 @@ specHeader env (bndr : bndrs) (SpecType ty : args) |
| 2616 | 2619 | -- a substitution on it (in case the type refers to 'a'). Additionally, we need
|
| 2617 | 2620 | -- to produce a binder, LHS argument and RHS argument for the resulting rule,
|
| 2618 | 2621 | -- /and/ a binder for the specialised body.
|
| 2619 | -specHeader env (bndr : bndrs) (UnspecType : args)
|
|
| 2622 | +specHeader mod env (bndr : bndrs) (UnspecType : args)
|
|
| 2620 | 2623 | = do { let (env', bndr') = substBndr env bndr
|
| 2621 | 2624 | ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
| 2622 | - <- specHeader env' bndrs args
|
|
| 2625 | + <- specHeader mod env' bndrs args
|
|
| 2623 | 2626 | ; pure ( useful
|
| 2624 | 2627 | , env''
|
| 2625 | 2628 | , leftover_bndrs
|
| ... | ... | @@ -2630,18 +2633,17 @@ specHeader env (bndr : bndrs) (UnspecType : args) |
| 2630 | 2633 | , varToCoreExpr bndr' : spec_args
|
| 2631 | 2634 | )
|
| 2632 | 2635 | }
|
| 2633 | - |
|
| 2634 | 2636 | -- Next we want to specialise the 'Eq a' dict away. We need to construct
|
| 2635 | 2637 | -- a wildcard binder to match the dictionary (See Note [Specialising Calls] for
|
| 2636 | 2638 | -- the nitty-gritty), as a LHS rule and unfolding details.
|
| 2637 | -specHeader env (bndr : bndrs) (SpecDict d : args)
|
|
| 2639 | +specHeader mod env (bndr : bndrs) (SpecDict d : args)
|
|
| 2638 | 2640 | | not (isDeadBinder bndr)
|
| 2639 | 2641 | , allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)
|
| 2640 | 2642 | -- See Note [Weird special case for SpecDict]
|
| 2641 | 2643 | = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders]
|
| 2642 | 2644 | ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d
|
| 2643 | 2645 | ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
| 2644 | - <- specHeader env2 bndrs args
|
|
| 2646 | + <- specHeader mod env2 bndrs args
|
|
| 2645 | 2647 | ; pure ( True -- Ha! A useful specialisation!
|
| 2646 | 2648 | , env3
|
| 2647 | 2649 | , leftover_bndrs
|
| ... | ... | @@ -2666,21 +2668,24 @@ specHeader env (bndr : bndrs) (SpecDict d : args) |
| 2666 | 2668 | -- why 'i' doesn't appear in our RULE above. But we have no guarantee that
|
| 2667 | 2669 | -- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so
|
| 2668 | 2670 | -- this case must be here.
|
| 2669 | -specHeader env (bndr : bndrs) (_ : args)
|
|
| 2671 | +specHeader mod env (bndr : bndrs) (_ : args)
|
|
| 2670 | 2672 | -- The "_" can be UnSpecArg, or SpecDict where the bndr is dead
|
| 2671 | 2673 | = do { -- see Note [Zap occ info in rule binders]
|
| 2672 | 2674 | let (env', bndr') = substBndr env (zapIdOccInfo bndr)
|
| 2673 | 2675 | ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
| 2674 | - <- specHeader env' bndrs args
|
|
| 2675 | - |
|
| 2676 | - ; let bndr_ty = idType bndr'
|
|
| 2676 | + <- specHeader mod env' bndrs args
|
|
| 2677 | 2677 | |
| 2678 | - -- See Note [Drop dead args from specialisations]
|
|
| 2678 | + ; let -- See Note [Drop dead args from specialisations]
|
|
| 2679 | 2679 | -- C.f. GHC.Core.Opt.WorkWrap.Utils.mk_absent_let
|
| 2680 | 2680 | (mb_spec_bndr, spec_arg)
|
| 2681 | 2681 | | isDeadBinder bndr
|
| 2682 | - , Just lit_expr <- mkLitRubbish bndr_ty
|
|
| 2683 | - = (Nothing, lit_expr)
|
|
| 2682 | + , Just filler <- mkAbsentFiller mod bndr' NotMarkedStrict
|
|
| 2683 | + -- NB: mkAbsentFiller returns Nothing for a terminating type (e.g. a
|
|
| 2684 | + -- dictionary), so this guard fails and we fall through, keeping the
|
|
| 2685 | + -- argument instead of dropping it.
|
|
| 2686 | + -- See Note [Don't make fillers for terminating types]
|
|
| 2687 | + -- in GHC.Core.Opt.WorkWrap.Utils
|
|
| 2688 | + = (Nothing, filler)
|
|
| 2684 | 2689 | | otherwise
|
| 2685 | 2690 | = (Just bndr', varToCoreExpr bndr')
|
| 2686 | 2691 | |
| ... | ... | @@ -2699,12 +2704,12 @@ specHeader env (bndr : bndrs) (_ : args) |
| 2699 | 2704 | |
| 2700 | 2705 | -- If we run out of binders, stop immediately
|
| 2701 | 2706 | -- See Note [Specialisation Must Preserve Sharing]
|
| 2702 | -specHeader env [] _ = pure (False, env, [], [], [], [], [], [])
|
|
| 2707 | +specHeader _ env [] _ = pure (False, env, [], [], [], [], [], [])
|
|
| 2703 | 2708 | |
| 2704 | 2709 | -- Return all remaining binders from the original function. These have the
|
| 2705 | 2710 | -- invariant that they should all correspond to unspecialised arguments, so
|
| 2706 | 2711 | -- it's safe to stop processing at this point.
|
| 2707 | -specHeader env bndrs []
|
|
| 2712 | +specHeader _ env bndrs []
|
|
| 2708 | 2713 | = pure (False, env', bndrs', [], [], [], [], [])
|
| 2709 | 2714 | where
|
| 2710 | 2715 | (env', bndrs') = substBndrs env bndrs
|
| ... | ... | @@ -550,7 +550,7 @@ tryWW ww_opts is_rec fn_id rhs |
| 550 | 550 | -- See Note [Drop absent bindings]
|
| 551 | 551 | | isAbsDmd (demandInfo fn_info)
|
| 552 | 552 | , not (isJoinId fn_id)
|
| 553 | - , Just filler <- mkAbsentFiller ww_opts fn_id NotMarkedStrict
|
|
| 553 | + , Just filler <- mkAbsentFiller (wo_module ww_opts) fn_id NotMarkedStrict
|
|
| 554 | 554 | = return [(new_fn_id, filler)]
|
| 555 | 555 | |
| 556 | 556 | -- See Note [Don't w/w INLINE things]
|
| ... | ... | @@ -29,7 +29,6 @@ import GHC.Core.Subst |
| 29 | 29 | import GHC.Core.Type
|
| 30 | 30 | import GHC.Core.Multiplicity
|
| 31 | 31 | import GHC.Core.Coercion
|
| 32 | -import GHC.Core.Predicate( isDictTy )
|
|
| 33 | 32 | import GHC.Core.Reduction
|
| 34 | 33 | import GHC.Core.FamInstEnv
|
| 35 | 34 | import GHC.Core.TyCon
|
| ... | ... | @@ -936,7 +935,7 @@ mkWWstr_one opts arg str_mark = |
| 936 | 935 | _ | isTyVar arg -> do_nothing
|
| 937 | 936 | |
| 938 | 937 | DropAbsent
|
| 939 | - | Just absent_filler <- mkAbsentFiller opts arg str_mark
|
|
| 938 | + | Just absent_filler <- mkAbsentFiller (wo_module opts) arg str_mark
|
|
| 940 | 939 | -- Absent case. Drop the argument from the worker.
|
| 941 | 940 | -- We can't always handle absence for arbitrary
|
| 942 | 941 | -- unlifted types, so we need to choose just the cases we can
|
| ... | ... | @@ -1007,14 +1006,20 @@ unbox_one_arg opts arg_var |
| 1007 | 1006 | --
|
| 1008 | 1007 | -- If @mkAbsentFiller _ id == Just e@, then @e@ is an absent filler with the
|
| 1009 | 1008 | -- same type as @id@. Otherwise, no suitable filler could be found.
|
| 1010 | -mkAbsentFiller :: WwOpts -> Id -> StrictnessMark -> Maybe CoreExpr
|
|
| 1011 | -mkAbsentFiller opts arg str
|
|
| 1009 | +mkAbsentFiller :: Module -> Id -> StrictnessMark -> Maybe CoreExpr
|
|
| 1010 | +mkAbsentFiller mod arg str
|
|
| 1011 | + -- We never make a filler for a terminating type: it might be speculatively
|
|
| 1012 | + -- evaluated or have a field projected out of it.
|
|
| 1013 | + -- See (AF4) in Note [Absent fillers], and
|
|
| 1014 | + -- Note [Don't make fillers for terminating types].
|
|
| 1015 | + | isTerminatingType arg_ty
|
|
| 1016 | + = Nothing
|
|
| 1017 | + |
|
| 1012 | 1018 | -- The lifted case: bind 'absentError'. See (AF1) in Note [Absent fillers]
|
| 1013 | 1019 | -- We want to use this case if possible, because we get a nice runtime panic message
|
| 1014 | 1020 | -- if we are wrong (like we were in #11126). Otherwise we fall through to the
|
| 1015 | 1021 | -- less-desirable mkLitRubbish case.
|
| 1016 | 1022 | | mightBeLiftedType arg_ty
|
| 1017 | - , not (isDictTy arg_ty) -- See (AF4) in Note [Absent fillers]
|
|
| 1018 | 1023 | , not (isStrictDmd (idDemandInfo arg)) -- See (AF2)
|
| 1019 | 1024 | , not (isMarkedStrict str) -- in Note [Absent fillers]
|
| 1020 | 1025 | = Just (mkAbsentErrorApp arg_ty msg)
|
| ... | ... | @@ -1041,7 +1046,7 @@ mkAbsentFiller opts arg str |
| 1041 | 1046 | -- will have different lengths and hence different costs for
|
| 1042 | 1047 | -- the inliner leading to different inlining.
|
| 1043 | 1048 | -- See also Note [Unique Determinism] in GHC.Types.Unique
|
| 1044 | - file_msg = text "In module" <+> quotes (ppr $ wo_module opts)
|
|
| 1049 | + file_msg = text "In module" <+> quotes (ppr mod)
|
|
| 1045 | 1050 | |
| 1046 | 1051 | {- Note [Worker/wrapper for Strictness and Absence]
|
| 1047 | 1052 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1234,27 +1239,8 @@ Needless to say, there are some wrinkles: |
| 1234 | 1239 | have to be representation monomorphic. But in the future, we might allow
|
| 1235 | 1240 | levity polymorphism, e.g. a polymorphic levity variable in 'BoxedRep'.
|
| 1236 | 1241 | |
| 1237 | -(AF4) Consider (#24934)
|
|
| 1238 | - f :: (a~b) => blah {-# INLINE f #-}
|
|
| 1239 | - f d x = case eq_sel d of co -> body
|
|
| 1240 | - In #24934 it turned out that `co` was unused; and we discarded the
|
|
| 1241 | - entire case-scrutinisation via the `exprOkToDiscard` test in
|
|
| 1242 | - `GHC.Core.Opt.Simplify.Iteration.rebuildCase`. So now `d` is absent.
|
|
| 1243 | - But in the /unfolding/ for some reason we did not discard the `case`;
|
|
| 1244 | - so when we inline `f` we end up evaluating that `d` argument. So we had
|
|
| 1245 | - better not replace it with an error thunk!
|
|
| 1246 | - |
|
| 1247 | - The root of it is this: `exprOkToDiscard` assumes that a dictionary is
|
|
| 1248 | - non-bottom (Note [exprOkForSpeculation and type classes]); but then we replace
|
|
| 1249 | - the (a~b) dictionary with an error thunk, breaking the invariant that every
|
|
| 1250 | - dictionary is non-bottom. (If -XDictsStrict is on, the invariant is even
|
|
| 1251 | - more important.)
|
|
| 1252 | - |
|
| 1253 | - Simple solution: never use an error thunk for a dictionary; instead fall
|
|
| 1254 | - through to mkRubbishLit. (The only downside is that we lose the compiler
|
|
| 1255 | - debugging advantages of (AF1).)
|
|
| 1256 | - |
|
| 1257 | - This is quite delicate.
|
|
| 1242 | +(AF4) We never make an absent filler for a terminating type.
|
|
| 1243 | + See Note [Don't make fillers for terminating types].
|
|
| 1258 | 1244 | |
| 1259 | 1245 | While (AF1) and (AF2) are simply an optimisation in terms of compiler debugging
|
| 1260 | 1246 | experience, (AF3) should be irrelevant in most programs, if not all.
|
| ... | ... | @@ -1276,6 +1262,47 @@ fragile |
| 1276 | 1262 | because `MkT` is strict in its Int# argument, so we get an absentError
|
| 1277 | 1263 | exception when we shouldn't. Very annoying!
|
| 1278 | 1264 | |
| 1265 | +Note [Don't make fillers for terminating types]
|
|
| 1266 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1267 | +We never make an absent filler, error thunk or rubbish literal, for a terminating
|
|
| 1268 | +type (isTerminatingType): a non-unary class dictionary, a boxed equality, or a
|
|
| 1269 | +constraint tuple.
|
|
| 1270 | + |
|
| 1271 | +GHC relies on a dictionary value never being bottom (see
|
|
| 1272 | +Note [NON-BOTTOM-DICTS invariant] in GHC.Core). GHC uses "speculation" to
|
|
| 1273 | +evaluated guaranteed-non-bottom values: see Note [Speculative evaluation] in
|
|
| 1274 | +GHC.CoreToStg.Prep. This speculative evaluation is fundamentally incompatible
|
|
| 1275 | +with replacing a dictionary with an absent filler. Attempts to to do so gave
|
|
| 1276 | +rise to a succession of bugs including:
|
|
| 1277 | + |
|
| 1278 | + * #24934: we evaluated an absent dictionary
|
|
| 1279 | + * #25924: we selected a superclass from an absent dictionary
|
|
| 1280 | + |
|
| 1281 | +A terminating type is exactly what speculation will force: see
|
|
| 1282 | +Note [exprOkForSpeculation and type classes] in GHC.Core.Utils. So we refuse to
|
|
| 1283 | +make a filler for precisely those types.
|
|
| 1284 | + |
|
| 1285 | +So the safe thing is to make no filler at all for a terminating type. Then there
|
|
| 1286 | +is no bogus dictionary to evaluate or project from. Specifically
|
|
| 1287 | + |
|
| 1288 | + * `mkAbsentFiller` returns `Nothing` for a terminating type, so worker/wrapper
|
|
| 1289 | + keeps the real argument.
|
|
| 1290 | + |
|
| 1291 | + * `Specialise.specHeader` calls `mkAbsentFiller` too, so it likewise keeps the
|
|
| 1292 | + dead dictionary argument rather than dropping it for a filler.
|
|
| 1293 | + |
|
| 1294 | +Prior failed approaches
|
|
| 1295 | + |
|
| 1296 | +We used to paper over this. !13233 replaced the error thunk for an absent
|
|
| 1297 | +dictionary with a rubbish literal, so that it could at least be evaluated
|
|
| 1298 | +without complaint. But #25924 showed that this is not enough, because we do not
|
|
| 1299 | +only evaluate the absent dictionary, we also select a superclass from it.
|
|
| 1300 | + |
|
| 1301 | +We could instead teach speculation to leave absent bindings alone, and we do
|
|
| 1302 | +that too (see Note [Speculative evaluation] in GHC.CoreToStg.Prep). But that is
|
|
| 1303 | +not a guarantee. After optimisation a binding that holds an absent filler may no
|
|
| 1304 | +longer be marked absent, so we cannot rely on the demand to protect us.
|
|
| 1305 | + |
|
| 1279 | 1306 | Note [Unboxing through unboxed tuples]
|
| 1280 | 1307 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1281 | 1308 | We should not to a worker/wrapper split just for unboxing the components of
|
| ... | ... | @@ -1960,20 +1960,19 @@ It is also similar to Note [Do not strictify a DFun's parameter dictionaries], |
| 1960 | 1960 | where marking recursive DFuns (of undecidable *instances*) strict in dictionary
|
| 1961 | 1961 | *parameters* leads to quite the same change in termination as above.
|
| 1962 | 1962 | |
| 1963 | -Another Nasty Wrinkle: do not speculate absent bindings
|
|
| 1963 | +Belt and braces: do not speculate absent bindings
|
|
| 1964 | 1964 | |
| 1965 | -Speculative evaluation is in conflict with absent fillers (see Note [Absent
|
|
| 1966 | -fillers] in GHC.Core.Opt.WorkWrap.Utils).
|
|
| 1965 | +In 'decideFloatInfo' we decline to speculate a binding whose demand is absent.
|
|
| 1966 | +There is no point in speculating an absent binding, since its value is
|
|
| 1967 | +(presumably) not needed.
|
|
| 1967 | 1968 | |
| 1968 | -When an argument is found to be absent, worker/wrapper drops it and binds an
|
|
| 1969 | -absent filler in its place. This is supposed to be OK because the filler is
|
|
| 1970 | -absent (i.e. not evaluated by the program).
|
|
| 1971 | - |
|
| 1972 | -But speculation can force it anyway! See #25924 for how this goes wrong.
|
|
| 1973 | - |
|
| 1974 | -So in 'decideFloatInfo' we decline to speculate a binding whose demand is
|
|
| 1975 | -absent. An absent value is by definition never needed, so we lose nothing by not
|
|
| 1976 | -speculating it.
|
|
| 1969 | +This used to matter more. Worker/wrapper would bind an absent dictionary to a
|
|
| 1970 | +rubbish literal filler, and speculation could force a superclass selection out
|
|
| 1971 | +of that rubbish literal, causing a segfault (#25924). Nowadays we never make a
|
|
| 1972 | +filler for a dictionary in the first place, so this can no longer happen and
|
|
| 1973 | +the guard is merely belt and braces.
|
|
| 1974 | +See Note [Don't make fillers for terminating types]
|
|
| 1975 | +in GHC.Core.Opt.WorkWrap.Utils.
|
|
| 1977 | 1976 | |
| 1978 | 1977 | Note [BindInfo and FloatInfo]
|
| 1979 | 1978 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2227,7 +2226,7 @@ mkNonRecFloat env is_unlifted bndr rhs |
| 2227 | 2226 | -- (where it is actually bound lazily).
|
| 2228 | 2227 | --
|
| 2229 | 2228 | -- Don't speculate an absent binding. See #25924 and
|
| 2230 | - -- "Another Nasty Wrinkle" in Note [Speculative evaluation].
|
|
| 2229 | + -- "Belt and braces" in Note [Speculative evaluation].
|
|
| 2231 | 2230 | |
| 2232 | 2231 | | is_unlifted || is_strict = (CaseBound, StrictContextFloatable)
|
| 2233 | 2232 | -- These will never be floated out of a lazy RHS context
|
| ... | ... | @@ -988,6 +988,14 @@ data type. Here are the moving parts: |
| 988 | 988 | |
| 989 | 989 | This is sad, though: see #18983.
|
| 990 | 990 | |
| 991 | + INVARIANT 3: we never make a rubbish literal of a terminating type
|
|
| 992 | + (isTerminatingType), such as a class dictionary. GHC relies on a value of
|
|
| 993 | + a terminating type never being bottom, and so may speculatively evaluate
|
|
| 994 | + a dictionary or select a superclass from it. Either would crash on a
|
|
| 995 | + rubbish literal (#24934, #25924).
|
|
| 996 | + See Note [Don't make fillers for terminating types]
|
|
| 997 | + in GHC.Core.Opt.WorkWrap.Utils.
|
|
| 998 | + |
|
| 991 | 999 | 3. STG: The type app in `RUBBISH[IntRep] @Int# :: Int#` is erased and we get
|
| 992 | 1000 | the (untyped) 'StgLit' `RUBBISH[IntRep] :: Int#` in STG.
|
| 993 | 1001 |
| 1 | 1 | |
| 2 | 2 | ==================== Tidy Core ====================
|
| 3 | -Result size of Tidy Core = {terms: 295, types: 206, coercions: 4, joins: 0/0}
|
|
| 3 | +Result size of Tidy Core = {terms: 297, types: 214, coercions: 4, joins: 0/0}
|
|
| 4 | 4 | |
| 5 | 5 | -- RHS size: {terms: 8, types: 9, coercions: 1, joins: 0/0}
|
| 6 | 6 | T18982.$WExGADT :: forall e. (e ~ Int) => e %1 -> Int %1 -> ExGADT Int
|
| ... | ... | @@ -194,13 +194,13 @@ T18982.$tc'ExGADT2 = GHC.Types.TrNameS T18982.$tc'ExGADT3 |
| 194 | 194 | T18982.$tc'ExGADT :: GHC.Types.TyCon
|
| 195 | 195 | T18982.$tc'ExGADT = GHC.Types.TyCon 8468257409157161049#Word64 5503123603717080600#Word64 T18982.$trModule T18982.$tc'ExGADT2 1# T18982.$tc'ExGADT1
|
| 196 | 196 | |
| 197 | --- RHS size: {terms: 11, types: 10, coercions: 0, joins: 0/0}
|
|
| 198 | -T18982.$wi :: forall a e. (a GHC.Prim.~# Int) => e -> GHC.Prim.Int# -> GHC.Prim.Int#
|
|
| 199 | -T18982.$wi = \ (@a) (@e) (ww :: a GHC.Prim.~# Int) (ww1 :: e) (ww2 :: GHC.Prim.Int#) -> case ww1 of { __DEFAULT -> GHC.Prim.+# ww2 1# }
|
|
| 197 | +-- RHS size: {terms: 12, types: 14, coercions: 0, joins: 0/0}
|
|
| 198 | +T18982.$wi :: forall a e. (a GHC.Prim.~# Int, e ~ Int) => e -> GHC.Prim.Int# -> GHC.Prim.Int#
|
|
| 199 | +T18982.$wi = \ (@a) (@e) (ww :: a GHC.Prim.~# Int) _ (ww2 :: e) (ww3 :: GHC.Prim.Int#) -> case ww2 of { __DEFAULT -> GHC.Prim.+# ww3 1# }
|
|
| 200 | 200 | |
| 201 | --- RHS size: {terms: 15, types: 22, coercions: 1, joins: 0/0}
|
|
| 201 | +-- RHS size: {terms: 16, types: 22, coercions: 1, joins: 0/0}
|
|
| 202 | 202 | i :: forall a. ExGADT a -> Int
|
| 203 | -i = \ (@a) (ds :: ExGADT a) -> case ds of { ExGADT @e ww ww1 ww2 ww3 -> case ww3 of { GHC.Types.I# ww4 -> case T18982.$wi @a @e @~(ww :: a GHC.Prim.~# Int) ww2 ww4 of ww5 { __DEFAULT -> GHC.Types.I# ww5 } } }
|
|
| 203 | +i = \ (@a) (ds :: ExGADT a) -> case ds of { ExGADT @e ww ww1 ww2 ww3 -> case ww3 of { GHC.Types.I# ww4 -> case T18982.$wi @a @e @~(ww :: a GHC.Prim.~# Int) ww1 ww2 ww4 of ww5 { __DEFAULT -> GHC.Types.I# ww5 } } }
|
|
| 204 | 204 | |
| 205 | 205 | -- RHS size: {terms: 6, types: 7, coercions: 0, joins: 0/0}
|
| 206 | 206 | T18982.$wh :: forall a. (a GHC.Prim.~# Int) => GHC.Prim.Int# -> GHC.Prim.Int#
|