Simon Jakobi pushed to branch wip/sjakobi/T27368-cbe-expand-subst at Glasgow Haskell Compiler / GHC
Commits:
-
63c9eb84
by Simon Jakobi at 2026-10-05T00:58:03+02:00
4 changed files:
- + changelog.d/27368
- compiler/GHC/Cmm/CommonBlockElim.hs
- + testsuite/tests/codeGen/should_compile/T27368.hs
- testsuite/tests/codeGen/should_compile/all.T
Changes:
| 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: !16543 |
| ... | ... | @@ -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
|
| 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 |
| ... | ... | @@ -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']) |