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: