Simon Jakobi pushed to branch wip/sjakobi/T27368-cbe-expand-subst at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • changelog.d/27368
    1
    +section: compiler
    
    2
    +synopsis: Fix a ``setInfoTableStackMap`` panic caused by common block elimination
    
    3
    +  leaving references to eliminated blocks.
    
    4
    +issues: #27368
    
    5
    +mrs: !16765

  • compiler/GHC/Cmm/CommonBlockElim.hs
    ... ... @@ -90,6 +90,10 @@ elimCommonBlocks g =
    90 90
     -- (so avoid comparing them again)
    
    91 91
     type DistinctBlocks = [CmmBlock]
    
    92 92
     type Key = [Label]
    
    93
    +
    
    94
    +-- | A substitution maps each eliminated block to its replacement.
    
    95
    +--
    
    96
    +-- Invariant: no value is a key, i.e. there are no chains @x->y->z@.
    
    93 97
     type Subst = LabelMap BlockId
    
    94 98
     
    
    95 99
     -- The outer list groups by hash. We retain this grouping throughout.
    
    ... ... @@ -108,9 +112,19 @@ iterate subst blocks
    108 112
               where
    
    109 113
                 (new_subst2, db) = mergeBlockList subst dbs
    
    110 114
     
    
    111
    -    subst' = subst `mapUnion` new_substs
    
    115
    +    subst' = extendSubst subst new_substs
    
    112 116
         updated_blocks = map (map (first (map (lookupBid subst')))) merged_blocks
    
    113 117
     
    
    118
    +-- | Add the substitutions of one round of 'iterate'.
    
    119
    +--
    
    120
    +-- A block that won a merge in an earlier round may have lost one in this
    
    121
    +-- round, so the older substitutions are updated to keep the result chain-free.
    
    122
    +extendSubst :: Subst -> Subst -> Subst
    
    123
    +extendSubst subst new = assert (chainFree subst') subst'
    
    124
    +  where
    
    125
    +    subst' = mapMap (lookupBid new) subst `mapUnion` new
    
    126
    +    chainFree s = not (any (`mapMember` s) s)
    
    127
    +
    
    114 128
     -- Combine two lists of blocks.
    
    115 129
     -- While they are internally distinct they can still share common blocks.
    
    116 130
     mergeBlocks :: Subst -> DistinctBlocks -> DistinctBlocks -> (Subst, DistinctBlocks)
    
    ... ... @@ -218,9 +232,7 @@ dont_care _other = False
    218 232
     eqBid :: LabelMap BlockId -> BlockId -> BlockId -> Bool
    
    219 233
     eqBid subst bid bid' = lookupBid subst bid == lookupBid subst bid'
    
    220 234
     lookupBid :: LabelMap BlockId -> BlockId -> BlockId
    
    221
    -lookupBid subst bid = case mapLookup bid subst of
    
    222
    -                        Just bid  -> lookupBid subst bid
    
    223
    -                        Nothing -> bid
    
    235
    +lookupBid subst bid = mapFindWithDefault bid bid subst
    
    224 236
     
    
    225 237
     -- Middle nodes and expressions can contain BlockIds, in particular in
    
    226 238
     -- CmmStackSlot and CmmBlock, so we have to use a special equality for
    

  • testsuite/tests/codeGen/should_compile/T27368.hs
    1
    +-- Common block elimination merges the duplicated blocks over several
    
    2
    +-- rounds. Compiling this at -O panicked in setInfoTableStackMap (#27368).
    
    3
    +
    
    4
    +module T27368 (f) where
    
    5
    +
    
    6
    +{-# NOINLINE put #-}
    
    7
    +put :: Int -> Int -> IO ()
    
    8
    +put h x = if h + x == 12345 then errorWithoutStackTrace "boom" else pure ()
    
    9
    +
    
    10
    +data T = N | J Int | K
    
    11
    +
    
    12
    +f :: Int -> Bool -> T -> IO ()
    
    13
    +f h a t = do
    
    14
    +  if a
    
    15
    +    then do put h 1; case t of { N -> pure (); J _ -> put h 3; K -> put h 4 }; put h 0; put h 0; put h 0; put h 0
    
    16
    +    else do put h 2; case t of { N -> pure (); J _ -> put h 3; K -> put h 4 }; put h 0; put h 0; put h 0; put h 0
    
    17
    +  put h 0

  • testsuite/tests/codeGen/should_compile/all.T
    ... ... @@ -150,3 +150,5 @@ test('T16351', normal, compile, ['-O2 -ddump-simpl -dno-typeable-binds -dsuppres
    150 150
     test('T20298a', normal, compile, ['-O2 -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques'])
    
    151 151
     test('T20298b', normal, compile, ['-O2 -dno-bignum-rules -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques'])
    
    152 152
     test('T20298c', normal, compile, ['-O2 -dno-builtin-rules -ddump-simpl -dno-typeable-binds -dsuppress-all -dsuppress-uniques'])
    
    153
    +
    
    154
    +test('T27368', normal, compile, ['-O'])