#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