Missed optimization opportunity with redundant case expression.
Motivation
Consider the following function:
f :: Int -> Int
f n = case n of
2 -> n
n -> n
GHC is of course smart enough to know that it does not have to evaluate the case expression. The resulting STG looks like this.
Test.f :: GHC.Types.Int -> GHC.Types.Int
[GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U(U)>m, Unf=OtherCon []] =
\r [n_s1pK] n_s1pK;
However, you could also write the function like this and the semantics should be the same.
g :: Int -> Int
g n = case n of
2 -> 2
n -> n
But GHC does not eliminate the case-expression in the STG.
Test.g1 :: GHC.Types.Int
[GblId, Caf=NoCafRefs, Str=m, Unf=OtherCon []] =
CCS_DONT_CARE GHC.Types.I#! [2#];
Test.g :: GHC.Types.Int -> GHC.Types.Int
[GblId,
Arity=1,
Caf=NoCafRefs,
Str=<S(S),1*U(U)>m,
Unf=OtherCon []] =
\r [n_s1pL]
case n_s1pL of wild_s1pM [Occ=Once] {
GHC.Types.I# ds_s1pN [Occ=Once!] ->
case ds_s1pN of {
__DEFAULT -> wild_s1pM;
2# -> Test.g1;
};
};
GHC seems to be able to perform this optimization, because when using unboxed types, the STG looks fine.
h :: Int# -> Int#
h n = case n of
2# -> 2#
n -> n
Test.h :: GHC.Prim.Int# -> GHC.Prim.Int#
[GblId, Arity=1, Caf=NoCafRefs, Str=<S,1*U>, Unf=OtherCon []] =
\r [n_s1pP] n_s1pP;
The STG output was produced by GHC 9.0.1 with -O2. Source is attached.
Proposal
f
and g
should produce the same code.