Optimization problem with zip and iterate
Summary
When compiling under -O2
, the pipeline head . map snd . zip [1] . iterate id $ x
is optimized to head . iterate id $ x
instead of x
.
Steps to reproduce
{-# LANGUAGE BangPatterns #-}
test :: Int -> Int
{-# NOINLINE test #-}
test !x = head . map snd . zip [1] . iterate id $ x
test2 :: Int -> Int
{-# NOINLINE test2 #-}
test2 !x = head . iterate id $ x
main = do putStrLn . show $ test 3 + test2 2
Compiling the above code with ghc -O2 -ddump-simpl optimize_test.hs > optimize_test.core
results in
-- RHS size: {terms: 8, types: 12, coercions: 0, joins: 0/0}
Main.$wtest [InlPrag=NOINLINE] :: GHC.Prim.Int# -> Int
[GblId, Arity=1, Caf=NoCafRefs, Str=<L,U>, Unf=OtherCon []]
Main.$wtest
= \ (ww_s1H7 :: GHC.Prim.Int#) ->
case GHC.List.$witerate @ Int (id @ Int) (GHC.Types.I# ww_s1H7) of
{ (# ww2_aOT, ww3_aOU #) ->
ww2_aOT
}
-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0}
Main.$wtest2 [InlPrag=NOINLINE] :: GHC.Prim.Int# -> GHC.Prim.Int#
[GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U>, Unf=OtherCon []]
Main.$wtest2 = \ (ww_s1Hd :: GHC.Prim.Int#) -> ww_s1Hd
Expected behavior
In test
, I would expect GHC to first eliminate map snd . zip [1]
, and then eliminate iterate
. GHC can obviously do this as shown in test2
. I suspect some rewrite ordering issue or some problem with boxed/unboxed integers.
Environment
- GHC version used:
ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.1