Parallel list comprehensions crash at runtime with unboxed patterns
Summary
The desugaring of parallel list comprehensions does not work when some of the generators produce unboxed values. The Core is bogus from the start, and under the right circumstances it segfaults.
Steps to reproduce
{-# language ParallelListComp, MagicHash #-}
import GHC.Exts
gore :: [Maybe Int] -> [Int] -> [Int]
gore xs ys =
[ I# (x +# y)
| Just (I# x) <- xs
| I# y <- ys
]
main = print $ take 5 . drop (10^7) $ gore [Just i | i <- [1..]] [10..]
Compile this with optimizations and run it for a segfault. For some reason, I couldn't get it to segfault without optimizations. This occurs in both GHC 9.0 and 9.2. I have not been able to reproduce the crash in 8.10, but the bug is obviously there already.
Expected behavior
I expect it to print
[20000011,20000013,20000015,20000017,20000019]
Discussion
The problem appears right at the beginning. --dump-ds-preopt
gives
gore :: [Maybe Int] -> [Int] -> [Int]
[LclIdX]
gore
= \ (xs_az3 :: [Maybe Int]) (ys_az4 :: [Int]) ->
letrec {
ds_d1Tx :: [(Int#, Int#)] -> [Int]
[LclId]
ds_d1Tx
= \ (ds_d1Ty :: [(Int#, Int#)]) ->
case ds_d1Ty of ds_d1Ty {
[] -> GHC.Types.[] @Int;
: ds_d1Tz ds_d1TA ->
case ds_d1Tz of wild_00 { (x_az5, y_az6) ->
GHC.Types.:
@Int
((\ (ds_d1TB :: Int#) -> GHC.Types.I# ds_d1TB) (+# x_az5 y_az6))
(ds_d1Tx ds_d1TA)
}
}; } in
ds_d1Tx
(letrec {
ds_d1Tw :: [Int#] -> [Int#] -> [(Int#, Int#)]
[LclId]
ds_d1Tw
= \ (ds_d1Tq :: [Int#]) (ds_d1Tr :: [Int#]) ->
case ds_d1Tq of ds_d1Tq {
[] -> GHC.Types.[] @(Int#, Int#);
: ds_d1Ts ds_d1Tu ->
case ds_d1Tr of ds_d1Tr {
[] -> GHC.Types.[] @(Int#, Int#);
: ds_d1Tt ds_d1Tv ->
GHC.Types.:
@(Int#, Int#) (ds_d1Ts, ds_d1Tt) (ds_d1Tw ds_d1Tu ds_d1Tv)
}
}; } in
ds_d1Tw
(build
@Int#
(\ (@a_d1Td)
(c_d1Te :: Int# -> a_d1Td -> a_d1Td)
(n_d1Tf :: a_d1Td) ->
GHC.Base.foldr
@(Maybe Int)
@a_d1Td
(\ (ds_d1Th :: Maybe Int) (ds_d1Tg :: a_d1Td) ->
let {
fail_d1Tj :: Void# -> a_d1Td
[LclId]
fail_d1Tj = \ (ds_d1Tk [OS=OneShot] :: Void#) -> ds_d1Tg } in
case ds_d1Th of wild_00 {
__DEFAULT -> fail_d1Tj void#;
Just ds_d1Ti ->
case ds_d1Ti of wild_00 { I# x_az5 -> c_d1Te x_az5 ds_d1Tg }
})
n_d1Tf
xs_az3))
(build
@Int#
(\ (@a_d1Tl)
(c_d1Tm :: Int# -> a_d1Tl -> a_d1Tl)
(n_d1Tn :: a_d1Tl) ->
GHC.Base.foldr
@Int
@a_d1Tl
(\ (ds_d1Tp :: Int) (ds_d1To :: a_d1Tl) ->
case ds_d1Tp of wild_00 { I# y_az6 -> c_d1Tm y_az6 ds_d1To })
n_d1Tn
ys_az4)))
-dcore-lint
, of course, throws a bunch of warnings, since (Int#, Int#)
and [Int#]
are kind errors.
Environment
- GHC version used: 9.2
Optional:
- Operating System:
- System Architecture: