Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 4,866
    • Issues 4,866
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 452
    • Merge requests 452
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #21281
Closed
Open
Created Mar 22, 2022 by Teo Camarasu@teoContributor

Inlining forgets strictness properties with GHC 9.0.2

Summary

When updating a codebase to GHC 9.0.2, I noticed that some strictness tests were newly failing. I managed to reduce it to the following reproducer.

The Core produced by this program looks suspect. Inlining seems to lead to strictness properties being ignored, which doesn't happen with GHC 8.10.7.

Steps to reproduce

Take a look at the differences between the Core generated by GHC 8.10.7 and 9.0.2. Unfortunately this reproducer depends on mtl and unordered-containers, but my feeling is that this can be reproduced without them.

I used: mtl-2.2.2 and unordered-containers-0.2.17.0 for GHC 9.0.2

{-# LANGUAGE BangPatterns #-}
module Repro where
import Control.Monad.RWS.Strict

import qualified Data.HashMap.Strict as HM

data Box = Box !Int

addToList :: Box -> [Box] -> [Box]
addToList !b !bs = b : bs

trigger :: Int -> RWS Int () (HM.HashMap Int [Box]) ()
trigger !indx = do
   v <- ask
   let b = Box v
   modify' $ HM.adjust (addToList b) indx

GHC-8.10.7(good)

Repro.trigger1
  = \ (w_s2R5 :: Int)
      (w1_s2R6 :: Int)
      (w2_s2R7 :: HM.HashMap Int [Box]) ->
      case w_s2R5 of { GHC.Types.I# ww1_s2Ra ->
      case Repro.$w$sadjust
             @ [Box]
             (\ (bs_a14k :: [Box]) ->
                case w1_s2R6 of { GHC.Types.I# dt1_a18g ->
                case bs_a14k of bs1_X14s { __DEFAULT ->
                GHC.Types.: @ Box (Repro.Box dt1_a18g) bs1_X14s
                }
                })
             ww1_s2Ra
             w2_s2R7
      of vx_a2rj
      { __DEFAULT ->
      (GHC.Tuple.(), vx_a2rj, GHC.Tuple.())
      `cast` (Sym (Data.Functor.Identity.N:Identity[0]
                       <((), HM.HashMap Int [Box], ())>_R)
              :: ((), HM.HashMap Int [Box], ())
                 ~R# Identity ((), HM.HashMap Int [Box], ()))
      }
      }

GHC-9.0.2(bad)

trigger1
  = \ w_s2P9 w1_s2Pa w2_s2Pb ->
      case w_s2P9 of { I# ww1_s2Pe ->
      case $w$sadjust
             (let {
                b_s2py = case w1_s2Pa of { I# dt1_a18B -> Box dt1_a18B } } in -- LAZY!
              \ bs_a14H ->
                case w1_s2Pa of { I# dt1_a18B ->
                case bs_a14H of bs1_X4 { __DEFAULT -> : b_s2py bs1_X4 }
                })
             ww1_s2Pe
             w2_s2Pb
      of vx_a2pR
      { __DEFAULT ->
      ((), vx_a2pR, ()) `cast` 
      }
      }

GHC-9.2.1(bad)

Repro.trigger1
  = \ (w_s1Wf :: Int)
      (w1_s1Wg [OS=OneShot] :: Int)
      (w2_s1Wh [OS=OneShot] :: HM.HashMap Int [Box]) ->
      case w_s1Wf of { GHC.Types.I# ww1_s1Wk ->
      let {
        b_s1Po :: Box
        [LclId]
        b_s1Po
          = case w1_s1Wg of { GHC.Types.I# dt1_a19i ->
            Repro.Box dt1_a19i
            } } in -- LAZY!
      case Repro.$w$s$wadjust
             @[Box]
             (\ (bs_a15f :: [Box]) ->
                case w1_s1Wg of { GHC.Types.I# dt1_a19i ->
                case bs_a15f of bs1_X4 { __DEFAULT ->
                GHC.Types.: @Box b_s1Po bs1_X4
                }
                })
             ww1_s1Wk
             w2_s1Wh
      of vx_a1Uc
      { __DEFAULT ->
      (GHC.Tuple.(), vx_a1Uc, GHC.Tuple.())
      `cast` (Sym (Data.Functor.Identity.N:Identity[0]
                       <((), HM.HashMap Int [Box], ())>_R)
              :: ((), HM.HashMap Int [Box], ())
                 ~R# Identity ((), HM.HashMap Int [Box], ()))
      }
      }

Expected behaviour

The Core generated by the trigger function should respect the strictness properties of addToList and ensure that the list's elements are whnf and is spine-strict.

Environment

  • GHC version used: 9.0.2, 9.2.1
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking