[Git][ghc/ghc][wip/T18347] Fix a buglet in Simplify.simplCast

Simon Peyton Jones gitlab at gitlab.haskell.org
Thu Jun 18 11:34:44 UTC 2020



Simon Peyton Jones pushed to branch wip/T18347 at Glasgow Haskell Compiler / GHC


Commits:
90d32db6 by Simon Peyton Jones at 2020-06-18T12:34:22+01:00
Fix a buglet in Simplify.simplCast

This bug, revealed by #18347, is just a missing update to
sc_hole_ty in simplCast.  I'd missed a code path when I
made the recentchanges in

    commit 6d49d5be904c0c01788fa7aae1b112d5b4dfaf1c
    Author: Simon Peyton Jones <simonpj at microsoft.com>
    Date:   Thu May 21 12:53:35 2020 +0100

    Implement cast worker/wrapper properly

The fix is very easy.

Two other minor changes

* Tidy up in SimpleOpt.simple_opt_expr. In fact I think this is an
  outright bug, introduced in the fix to #18112: we were simplifying
  the same coercion twice *with the same substitution*, which is just
  wrong.  It'd be a hard bug to trigger, so I just fixed it; less code
  too.

* Better debug printing of ApplyToVal

- - - - -


5 changed files:

- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/SimpleOpt.hs
- + testsuite/tests/simplCore/should_compile/T18347.hs
- testsuite/tests/simplCore/should_compile/all.T


Changes:

=====================================
compiler/GHC/Core/Opt/Simplify.hs
=====================================
@@ -1405,7 +1405,8 @@ simplCast env body co0 cont0
           = {-#SCC "addCoerce-pushCoValArg" #-}
             do { tail' <- addCoerceM m_co2 tail
                ; if isReflCo co1
-                 then return (cont { sc_cont = tail' })
+                 then return (cont { sc_cont = tail'
+                                   , sc_hole_ty = coercionLKind co })
                       -- Avoid simplifying if possible;
                       -- See Note [Avoiding exponential behaviour]
                  else do


=====================================
compiler/GHC/Core/Opt/Simplify/Utils.hs
=====================================
@@ -218,9 +218,10 @@ instance Outputable SimplCont where
   ppr (TickIt t cont)       = (text "TickIt" <+> ppr t) $$ ppr cont
   ppr (ApplyToTy  { sc_arg_ty = ty, sc_cont = cont })
     = (text "ApplyToTy" <+> pprParendType ty) $$ ppr cont
-  ppr (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_cont = cont })
-    = (text "ApplyToVal" <+> ppr dup <+> pprParendExpr arg)
-                                        $$ ppr cont
+  ppr (ApplyToVal { sc_arg = arg, sc_dup = dup, sc_cont = cont, sc_hole_ty = hole_ty })
+    = (hang (text "ApplyToVal" <+> ppr dup <+> text "hole" <+> ppr hole_ty)
+          2 (pprParendExpr arg))
+      $$ ppr cont
   ppr (StrictBind { sc_bndr = b, sc_cont = cont })
     = (text "StrictBind" <+> ppr b) $$ ppr cont
   ppr (StrictArg { sc_fun = ai, sc_cont = cont })


=====================================
compiler/GHC/Core/SimpleOpt.hs
=====================================
@@ -210,6 +210,7 @@ simple_opt_expr env expr
     in_scope     = substInScope subst
     in_scope_env = (in_scope, simpleUnfoldingFun)
 
+    ---------------
     go (Var v)
        | Just clo <- lookupVarEnv (soe_inl env) v
        = simple_opt_clo env clo
@@ -218,17 +219,10 @@ simple_opt_expr env expr
 
     go (App e1 e2)      = simple_app env e1 [(env,e2)]
     go (Type ty)        = Type     (substTy subst ty)
-    go (Coercion co)    = Coercion (optCoercion (soe_dflags env) (getTCvSubst subst) co)
+    go (Coercion co)    = Coercion (go_co co)
     go (Lit lit)        = Lit lit
     go (Tick tickish e) = mkTick (substTickish subst tickish) (go e)
-    go (Cast e co)      = case go e of
-                            -- flatten nested casts before calling the coercion optimizer;
-                            -- see #18112 (note that mkCast handles dropping Refl coercions)
-                            Cast e' co' -> mkCast e' (opt_co (mkTransCo co' co))
-                            e'          -> mkCast e' (opt_co co)
-                          where
-                            opt_co = optCoercion (soe_dflags env) (getTCvSubst subst)
-
+    go (Cast e co)      = mk_cast (go e) (go_co co)
     go (Let bind body)  = case simple_opt_bind env bind NotTopLevel of
                              (env', Nothing)   -> simple_opt_expr env' body
                              (env', Just bind) -> Let bind (simple_opt_expr env' body)
@@ -263,6 +257,9 @@ simple_opt_expr env expr
         e' = go e
         (env', b') = subst_opt_bndr env b
 
+    ----------------------
+    go_co co = optCoercion (soe_dflags env) (getTCvSubst subst) co
+
     ----------------------
     go_alt env (con, bndrs, rhs)
       = (con, bndrs', simple_opt_expr env' rhs)
@@ -282,6 +279,15 @@ simple_opt_expr env expr
          bs = reverse bs'
          e' = simple_opt_expr env e
 
+mk_cast :: CoreExpr -> CoercionR -> CoreExpr
+-- Like GHC.Core.Utils.mkCast, but does a full reflexivity check.
+-- mkCast doesn't do that because the Simplifier does (in simplCast)
+-- But in SimpleOpt it's nice to kill those nested casts (#18112)
+mk_cast (Cast e co1) co2        = mk_cast e (co1 `mkTransCo` co2)
+mk_cast (Tick t e)   co         = Tick t (mk_cast e co)
+mk_cast e co | isReflexiveCo co = e
+             | otherwise        = Cast e co
+
 ----------------------
 -- simple_app collects arguments for beta reduction
 simple_app :: SimpleOptEnv -> InExpr -> [SimpleClo] -> CoreExpr


=====================================
testsuite/tests/simplCore/should_compile/T18347.hs
=====================================
@@ -0,0 +1,10 @@
+module T18347 (function) where
+
+import Data.Coerce
+
+newtype All = All Bool
+
+data Encoding = Encoding (Char -> Bool)
+
+function :: Encoding -> Char -> All
+function enc v = coerce (case enc of Encoding x -> x) v


=====================================
testsuite/tests/simplCore/should_compile/all.T
=====================================
@@ -328,3 +328,4 @@ test('T18231', [ only_ways(['optasm']), grep_errmsg(r'^[\w\.]+ ::.*->.*') ], com
 # Cast WW
 test('T17673', [ only_ways(['optasm']), grep_errmsg(r'^\w+\.\$wf') ], compile, ['-ddump-simpl -dsuppress-uniques -dppr-cols=9999'])
 test('T18078', [ only_ways(['optasm']), grep_errmsg(r'^\w+\.\$wf') ], compile, ['-ddump-simpl -dsuppress-uniques -dppr-cols=9999'])
+test('T18347', normal, compile, ['-dcore-lint -O'])



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/90d32db665eb1f722673203d51c9e93021520be9

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/90d32db665eb1f722673203d51c9e93021520be9
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200618/d4550d94/attachment-0001.html>


More information about the ghc-commits mailing list