Simplifier failes to eliminate redundant boxing/unboxing
Consider this
f :: Bool -> Int -> Int
f b 0 = 0
f b x = let y = case b of
True -> case f b (x-1) of
I# v -> I# (v -# 1#)
False -> case f b (x-1) of
I# v -> I# (v +# 1#)
in
case b of
True -> case y of
I# w -> I# (w -# 1#)
False -> case y of
I# w -> I# (w +# 1#)
GHC 6.12 -O generates this:
T4941.$wf =
\ (w_shC :: GHC.Bool.Bool) (ww_shF :: GHC.Prim.Int#) ->
case ww_shF of ds_Xhm {
__DEFAULT ->
let {
y_shQ :: GHC.Types.Int
LclId
[Str: DmdType m]
y_shQ =
case w_shC of _ {
GHC.Bool.False ->
case T4941.$wf GHC.Bool.False (GHC.Prim.-# ds_Xhm 1)
of ww1_shJ { __DEFAULT ->
GHC.Types.I# (GHC.Prim.+# ww1_shJ 1)
};
GHC.Bool.True ->
case T4941.$wf GHC.Bool.True (GHC.Prim.-# ds_Xhm 1)
of ww1_shJ { __DEFAULT ->
GHC.Types.I# (GHC.Prim.-# ww1_shJ 1)
}
} } in
case w_shC of _ {
GHC.Bool.False ->
case y_shQ of _ { GHC.Types.I# w1_adk -> GHC.Prim.+# w1_adk 1 };
GHC.Bool.True ->
case y_shQ of _ { GHC.Types.I# w1_adj -> GHC.Prim.-# w1_adj 1 }
};
0 -> 0
}
Here y is used strictly, and boxes its value in every branch, and those uses immediately unbox it. We'd prefer to generate an unboxed value for 'y'.
This ticket is derived from #4941.
Trac metadata
Trac field | Value |
---|---|
Version | 7.0.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |