Useless code for some empty cases
Summary
GHC should force known-void values first.
Steps to reproduce
import Data.Void
data Wat = Wat !Void !Int
hello :: Void -> Int -> Wat
hello v i = Wat v $ product [1..i]
This produces Core
hello :: Void -> Int -> Wat
[GblId,
Arity=2,
Caf=NoCafRefs,
Str=<B,1*U><B,1*H>b,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=True)
Tmpl= \ (v_a19r [Occ=Once] :: Void) (i_a19s [Occ=Once!] :: Int) ->
case i_a19s of { I# _ [Occ=Dead] -> case v_a19r of { } }}]
hello
= \ (v_a19r :: Void) (i_a19s :: Int) ->
case i_a19s of { I# y_a2k3 -> case v_a19r of { } }
This is a bit strange! We produce code to match on the Int even though we know we will fail on the inner case. This feature seems (to my uneducated eye) to persist into assembly. This bloats the binary.
Expected behavior
I'd expect the compiled code to look like
hello
= \ (v_a19r :: Void) (i_a19s :: Int) ->
case i_a19r of { }
I don't know whether it would be helpful or harmful to change the unfolding similarly.
Environment
- GHC version used: 8.10.1
Optional:
- Operating System:
- System Architecture: