[GHC] #15696: Derived Ord instance for enumerations with more than 8 elements seems to be incorrect
GHC
ghc-devs at haskell.org
Fri Oct 12 12:01:38 UTC 2018
#15696: Derived Ord instance for enumerations with more than 8 elements seems to be
incorrect
-------------------------------------+-------------------------------------
Reporter: mrkkrp | Owner: osa1
Type: bug | Status: patch
Priority: highest | Milestone: 8.6.2
Component: Compiler | Version: 8.6.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Incorrect result | Unknown/Multiple
at runtime | Test Case:
Blocked By: | Blocking:
Related Tickets: #14677, #15155 | Differential Rev(s): Phab:D5196,
Wiki Page: | Phab:D5201
-------------------------------------+-------------------------------------
Comment (by osa1):
I did (4) and tried to validate. There are 4 regressions. 2 of them are
perf,
the other 2 are tests with checks on -ddump-simpl output. They're all
basically
the same problem: worker/wrapper results change slightly after the patch,
and
worker functions take more boxed params. Here's an example (T10482).
Original
program is this:
{{{
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE TypeFamilies #-}
module T10482 where
data family Foo a
data instance Foo (a, b) = FooPair !(Foo a) !(Foo b)
newtype instance Foo Int = Foo Int
foo :: Foo ((Int, Int), Int) -> Int -> Int
foo !f k =
if k == 0 then 0
else if even k then foo f (k-1)
else case f of
FooPair (FooPair (Foo n) _) _ -> n
}}}
`$wfoo` originally:
{{{
Rec {
-- RHS size: {terms: 19, types: 4, coercions: 0, joins: 0/0}
T10482.$wfoo [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
:: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int#
[GblId,
Arity=2,
Caf=NoCafRefs,
Str=<L,1*U><S,1*U>,
Unf=OtherCon []]
T10482.$wfoo
= \ (ww_s2Qy :: GHC.Prim.Int#) (ww1_s2QG :: GHC.Prim.Int#) ->
case ww1_s2QG of wild_X1v {
__DEFAULT ->
case GHC.Prim.remInt# wild_X1v 2# of {
__DEFAULT -> ww_s2Qy;
0# -> T10482.$wfoo ww_s2Qy (GHC.Prim.-# wild_X1v 1#)
};
0# -> 0#
}
end Rec }
}}}
after the patch (`wip/T15696`):
{{{
Rec {
-- RHS size: {terms: 22, types: 7, coercions: 3, joins: 0/0}
T10482.$wfoo [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
:: Foo Int -> GHC.Prim.Int# -> GHC.Prim.Int#
[GblId,
Arity=2,
Caf=NoCafRefs,
Str=<L,1*U(1*U)><S,1*U>,
Unf=OtherCon []]
T10482.$wfoo
= \ (ww_s2Qs
:: Foo Int
Unf=OtherCon [])
(ww1_s2Qz :: GHC.Prim.Int#) ->
case ww1_s2Qz of wild_X1l {
__DEFAULT ->
case GHC.Prim.remInt# wild_X1l 2# of {
__DEFAULT ->
case ww_s2Qs
`cast` (T10482.D:R:FooInt0[0] ; T10482.N:R:FooInt[0]
:: Foo Int ~R# Int)
of
{ GHC.Types.I# ww3_s2QD ->
ww3_s2QD
};
0# -> T10482.$wfoo ww_s2Qs (GHC.Prim.-# wild_X1l 1#)
};
0# -> 0#
}
end Rec }
}}}
The difference is that the first argument is now boxed `Int` instead of
`Int#`
as before.
I think the reason for this change is this: originally evaluation of
`ww_s2Qs`
happens after `remInt# wild_X1l 2#`, but if we pass `ww_s2Qs` unboxed
that'd
mean evaluating it before `remInt#`. This is possible if at least one of
those
expressions are OK-for-speculation. `remInt#` is not OK-for-speculation
because
it can fail. `ww_s2Qs` was previously (without `wip/T15696`) OK-for-
speculation,
but we just made `app_ok` more strict by removing a disjunct which was
actually
holding for this expression:
- `n_val_args == 0` holds because it has no args
- `isEvaldUnfolding (idUnfolding fun)` apparently also somehow holds. I
don't
know how exactly, but I'm guessing that because of the strictness
annotation
on the data con field we give this id `evaldUnfolding`.
Other 3 regressions are also of similar nature (worker function with less
unboxing).
What to do? I think it's correct to consider the data con field as strict
here
and pass an unboxed value to the worker. While we may not actually have a
tagged
value there (or even an evaluated one! e.g. #14677, #15155), the
programmer
indicated that it's fine to evaluate the field eagerly. As long as we
don't
expect (in the generated code) evaluated or tagged value it's fine.
So perhaps we should not do the change in `ok_app`.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15696#comment:76>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list