[GHC] #15696: Derived Ord instance for enumerations with more than 8 elements seems to be incorrect
GHC
ghc-devs at haskell.org
Wed Oct 3 10:41:08 UTC 2018
#15696: Derived Ord instance for enumerations with more than 8 elements seems to be
incorrect
-------------------------------------+-------------------------------------
Reporter: mrkkrp | Owner: (none)
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: | Differential Rev(s): Phab:D5196
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
> Are you maybe confused because in the STG dump you also see the STG for
cmpT? It's actually inlined in main so the top-level for cmpT is not used.
That is exactly what I was doing. Thanks!
I backed up some more to look at comment:6, which does not have a top-
level no-inline CAF. I see this:
{{{
$sgo_r5Tk :: Main.T -> Main.T -> Main.Set Main.T -> Main.Set Main.T
[GblId, Arity=3, Str=<L,1*U><L,U><S,1*U>, Unf=OtherCon []] =
sat-only [] \r [orig_s5Wj ds_s5Wk ds1_s5Wl]
case ds1_s5Wl of wild_s5Wm [Occ=Once] {
Main.Bin y_s5Wn l_s5Wo [Occ=Once] r_s5Wp [Occ=Once] ->
case
case ds_s5Wk of sat_s5Wq [Occ=Once] {
__DEFAULT -> dataToTag# [sat_s5Wq];
}
of
a'_s5Wr
{ __DEFAULT ->
case dataToTag# [y_s5Wn] of b'_s5Ws {
__DEFAULT ->
case <# [a'_s5Wr b'_s5Ws] of {
__DEFAULT ->
...
}}}
Here we take apart a `Bin`, and call `dataToTag#` on the contents; and
because of the `exprIsHNF` stuff there is
no guarantee that the argument to `Bin` points directly to the data value.
But in looking at this I found something else! In coment:6 there is no
top-level CAF with a NOINLINE, so
how do things go wrong. Here's how.
* We start with
{{{
thk = f ()
g x = ...(case thk of v -> Bin v Tip Tip)...
}}}
So far so good; the argument to `Bin` (which is strict) is evaluated.
* Now we do float-out. And in doing so we do a reverse binder-swap (see
`Note [Binder-swap during float-out]` in `SetLevels`) thus
{{{
g x = ...(case thk of v -> Bin thk Nil Nil)...
}}}
The goal of the reverse binder-swap is to allow more floating -- and it
does! We float the `Bin` to top level:
{{{
lvl = Bin thk Tip Tip
g x = ...(case thk of v -> lvl))...
}}}
* Now you can see that the argument of `Bin`, namely `thk`, points to the
thunk, not to the value as it did before; and that gives rise to the bug.
Is this wrong? Not really. We are still guaranteed that the argument to
`Bin` in `lvl` will be evaluated (by that `case thk`) before `lvl` is
used. But we are no longer guaranteed that the argument to `Bin` points
directly to the evaluated value.
So now I understand.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15696#comment:36>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list