Magnus pushed to branch wip/mangoiv/9.12.5-rc4 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • Repro019_minimal.hs
    1
    +module Repro019_minimal where
    
    2
    +
    
    3
    +unpack :: Int -> [Int]
    
    4
    +unpack b = unpackGo b
    
    5
    +{-# NOINLINE unpack #-}
    
    6
    +
    
    7
    +unpackGo :: Int -> [Int]
    
    8
    +unpackGo len = go len
    
    9
    +  where go i = if i == 0 then [] else i : go (i - 1)
    
    10
    +{-# INLINE unpackGo #-}
    
    11
    +
    
    12
    +{-# RULES "unpack/late" [0] forall b. unpack b = unpackGo b #-}
    
    13
    +
    
    14
    +conv :: [Int] -> Int
    
    15
    +conv input = case unpack (length input) of
    
    16
    +  [] -> undefined
    
    17
    +  _  -> 0
    
    18
    +
    
    19
    +opaque :: Int -> Bool
    
    20
    +opaque x = x > 0
    
    21
    +{-# NOINLINE opaque #-}
    
    22
    +
    
    23
    +getUnchecked :: Int -> IO (Int, Maybe Int)
    
    24
    +getUnchecked x = get x >>= maybe undefined pure
    
    25
    +
    
    26
    +get :: Int -> IO (Maybe (Int, Maybe Int))
    
    27
    +get x = do
    
    28
    +  a <- ((if opaque x then pure Nothing else pure (Just 0)) >>= \r -> case r of
    
    29
    +          Just _ -> pure (Just (1 :: Int))
    
    30
    +          _      -> pure Nothing)
    
    31
    +  b <- (if opaque x then pure Nothing else pure (Just 0))
    
    32
    +  pure ((,) <$> a <*> Just (fmap (conv . unpack) b))
    
    33
    +{-# INLINE get #-}
    
    34
    +
    
    35
    +top :: IO ()
    
    36
    +top = () <$ getUnchecked (undefined :: Int)
    
    37
    +

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -1211,14 +1211,21 @@ specExpr env (Tick tickish body)
    1211 1211
     ---------------- Applications might generate a call instance --------------------
    
    1212 1212
     specExpr env expr@(App {})
    
    1213 1213
       = do { let (fun_in, args_in) = collectArgs expr
    
    1214
    +       ; (fun_out, uds_fun)   <- specExpr env fun_in
    
    1214 1215
            ; (args_out, uds_args) <- mapAndCombineSM (specExpr env) args_in
    
    1215
    -       ; let env_args = env `bringFloatedDictsIntoScope` ud_binds uds_args
    
    1216
    -                -- Some dicts may have floated out of args_in;
    
    1217
    -                -- they should be in scope for fireRewriteRules (#21689)
    
    1218
    -             (fun_in', args_out') = fireRewriteRules env_args fun_in args_out
    
    1219
    -       ; (fun_out', uds_fun) <- specExpr env fun_in'
    
    1216
    +       ; let uds_app  = uds_fun `thenUDs` uds_args
    
    1217
    +             env_args = zapSubst env `bringFloatedDictsIntoScope` ud_binds uds_app
    
    1218
    +                -- zapSubst: we have now fully applied the substitution
    
    1219
    +                -- bringFloatedDictsIntoScope: some dicts may have floated out of
    
    1220
    +                -- args_in; they should be in scope for fireRewriteRules (#21689)
    
    1221
    +
    
    1222
    +       -- Try firing rewrite rules
    
    1223
    +       -- See Note [Fire rules in the specialiser]
    
    1224
    +       ; let (fun_out', args_out') = fireRewriteRules env_args fun_out args_out
    
    1225
    +
    
    1226
    +       -- Make a call record, and return
    
    1220 1227
            ; let uds_call = mkCallUDs env fun_out' args_out'
    
    1221
    -       ; return (fun_out' `mkApps` args_out', uds_fun `thenUDs` uds_call `thenUDs` uds_args) }
    
    1228
    +       ; return (fun_out' `mkApps` args_out', uds_app `thenUDs` uds_call) }
    
    1222 1229
     
    
    1223 1230
     ---------------- Lambda/case require dumping of usage details --------------------
    
    1224 1231
     specExpr env e@(Lam {})
    
    ... ... @@ -1252,16 +1259,17 @@ specExpr env (Let bind body)
    1252 1259
     -- See Note [Specialisation modulo dictionary selectors]
    
    1253 1260
     --     Note [ClassOp/DFun selection]
    
    1254 1261
     --     Note [Fire rules in the specialiser]
    
    1255
    -fireRewriteRules :: SpecEnv -> InExpr -> [OutExpr] -> (InExpr, [OutExpr])
    
    1262
    +fireRewriteRules :: SpecEnv   -- Substitution is already zapped
    
    1263
    +                 -> OutExpr -> [OutExpr] -> (OutExpr, [OutExpr])
    
    1256 1264
     fireRewriteRules env (Var f) args
    
    1257 1265
       | Just (rule, expr) <- specLookupRule env f args InitialPhase (getRules (se_rules env) f)
    
    1258 1266
       , let rest_args    = drop (ruleArity rule) args -- See Note [Extra args in the target]
    
    1259
    -        zapped_subst = Core.zapSubst (se_subst env)
    
    1260
    -        expr'        = simpleOptExprWith defaultSimpleOpts zapped_subst expr
    
    1267
    +        zapped_subst = se_subst env   -- Just needed for the InScopeSet
    
    1268
    +        expr'        = simpleOptExprWith defaultSimpleOpts zapped_subst (mkApps expr rest_args)
    
    1261 1269
                            -- simplOptExpr needed because lookupRule returns
    
    1262 1270
                            --   (\x y. rhs) arg1 arg2
    
    1263
    -  , (fun, args) <- collectArgs expr'
    
    1264
    -  = fireRewriteRules env fun (args++rest_args)
    
    1271
    +  , (fun', args') <- collectArgs expr'
    
    1272
    +  = fireRewriteRules env fun' args'
    
    1265 1273
     fireRewriteRules _ fun args = (fun, args)
    
    1266 1274
     
    
    1267 1275
     --------------
    
    ... ... @@ -1736,6 +1744,12 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs
    1736 1744
             do { -- Run the specialiser on the specialised RHS
    
    1737 1745
                  -- The "1" suffix is before we maybe add the void arg
    
    1738 1746
                ; (rhs_body', rhs_uds) <- specExpr rhs_env2 rhs_body
    
    1747
    +
    
    1748
    +{-         ; pprTrace "spec_call2" (vcat
    
    1749
    +                 [ text "fun:" <+> ppr fn
    
    1750
    +                 , text "rhs_body':" <+> ppr rhs_body' ]) $
    
    1751
    +             return ()
    
    1752
    +-}
    
    1739 1753
                     -- Add the { d1' = dx1; d2' = dx2 } usage stuff
    
    1740 1754
                     -- to the rhs_uds; see Note [Specialising Calls]
    
    1741 1755
                ; let rhs_uds_w_dx   = dx_binds `consDictBinds` rhs_uds
    

  • testsuite/tests/simplCore/should_compile/T27766.hs
    1
    +module Repro019_minimal where
    
    2
    +
    
    3
    +unpack :: Int -> [Int]
    
    4
    +unpack b = unpackGo b
    
    5
    +{-# NOINLINE unpack #-}
    
    6
    +
    
    7
    +unpackGo :: Int -> [Int]
    
    8
    +unpackGo len = go len
    
    9
    +  where go i = if i == 0 then [] else i : go (i - 1)
    
    10
    +{-# INLINE unpackGo #-}
    
    11
    +
    
    12
    +{-# RULES "unpack/late" [0] forall b. unpack b = unpackGo b #-}
    
    13
    +
    
    14
    +conv :: [Int] -> Int
    
    15
    +conv input = case unpack (length input) of
    
    16
    +  [] -> undefined
    
    17
    +  _  -> 0
    
    18
    +
    
    19
    +opaque :: Int -> Bool
    
    20
    +opaque x = x > 0
    
    21
    +{-# NOINLINE opaque #-}
    
    22
    +
    
    23
    +getUnchecked :: Int -> IO (Int, Maybe Int)
    
    24
    +getUnchecked x = get x >>= maybe undefined pure
    
    25
    +
    
    26
    +get :: Int -> IO (Maybe (Int, Maybe Int))
    
    27
    +get x = do
    
    28
    +  a <- ((if opaque x then pure Nothing else pure (Just 0)) >>= \r -> case r of
    
    29
    +          Just _ -> pure (Just (1 :: Int))
    
    30
    +          _      -> pure Nothing)
    
    31
    +  b <- (if opaque x then pure Nothing else pure (Just 0))
    
    32
    +  pure ((,) <$> a <*> Just (fmap (conv . unpack) b))
    
    33
    +{-# INLINE get #-}
    
    34
    +
    
    35
    +top :: IO ()
    
    36
    +top = () <$ getUnchecked (undefined :: Int)
    
    37
    +

  • testsuite/tests/simplCore/should_compile/all.T
    ... ... @@ -542,3 +542,4 @@ test('T26681', normal, compile, ['-O'])
    542 542
     test('T26903', [grep_errmsg(r'reverse')], compile, ['-O -dno-typeable-binds -ddump-simpl -dsuppress-uniques -dsuppress-all'])
    
    543 543
     test('T26682',  normal, multimod_compile, ['T26682', '-O -v0'])
    
    544 544
     test('T27261', [extra_files(['T27261_aux.hs'])], multimod_compile, ['T27261', '-v0 -O'])
    
    545
    +test('T27766',  normal, compile, ['-O2 -flate-specialise'])