Mulitple comparisons on Word types produce redundant comparisons
The Ord and Eq instances that are derived for Word types seems to be inefficient (and appeared while writing a ByteString decoder for UTF8, which does a lot of Word8 matching).
The following code:
bad :: Word -> Bool
bad c | c < 1 = True
| c < 2 = True
| otherwise = False
compiles to the rather horrible:
case GHC.Prim.eqWord# ww_sXC __word 1 of wild2_aSC {
GHC.Base.False ->
case GHC.Prim.ltWord# ww_sXC __word 1 of wild_B1 {
GHC.Base.False ->
case GHC.Prim.eqWord# ww_sXC __word 2 of wild21_XUq {
GHC.Base.False -> GHC.Prim.ltWord# ww_sXC __word 2;
GHC.Base.True -> GHC.Base.False
};
GHC.Base.True -> GHC.Base.True
};
GHC.Base.True ->
case GHC.Prim.eqWord# ww_sXC __word 2 of wild21_XUo {
GHC.Base.False -> GHC.Prim.ltWord# ww_sXC __word 2;
In particular, notice the (<) on Word becomes a case eqWord# of case ltWord# of ...
While the equivalent at an Int type, using the hand written Ord/Eq instances in GHC.Base, produces:
M.good =
\ (c_ag0 :: GHC.Base.Int) ->
case c_ag0 of wild_aRF { GHC.Base.I# x_aRH ->
case GHC.Prim.<# x_aRH 1 of wild1_B1 {
GHC.Base.False -> GHC.Prim.<# x_aRH 2; GHC.Base.True -> GHC.Base.True
}
}
The poor code only seems to be generated if there's more than 1 comparison against the value.
If I manually wrap Word, and write an instance Eq and Ord for it, based on the ones for Int (attached), we get identical code to the Int case:
M.good =
\ (c_agn :: M.MyWord) ->
case c_agn `cast` ((M.:CoMyWord) :: M.MyWord ~ GHC.Word.Word)
of wild_B1 { GHC.Word.W# x_agV ->
case GHC.Prim.ltWord# x_agV __word 1 of wild1_X33 {
GHC.Base.False -> GHC.Prim.ltWord# x_agV __word 2;
GHC.Base.True -> GHC.Base.True
}
}
The Ord and Eq instances for Word seem to be deeply magic:
data Word = W# Word# deriving (Eq, Ord)
Are the instances wired in?
The solution to this might be to have similar instances of Eq and Ord for Word, as for Int, or to change the built-in deriving.
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.2 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | dons@galois.com |
Operating system | Multiple |
Architecture | Unknown |