[GHC] #15696: Derived Ord instance for enumerations with more than 8 elements seems to be incorrect
GHC
ghc-devs at haskell.org
Thu Oct 4 07:54:23 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: | Phab:D5201
-------------------------------------+-------------------------------------
Changes (by osa1):
* differential: Phab:D5196 => Phab:D5196, Phab:D5201
Comment:
> As for the type-driven rewriting
This is not possible unless we somehow distinguish "stuff that directly
points to a value (without going through indirections)" from other at the
type level.
----
I submitted another diff that fixes this bug in Cmm. It also does a bunch
of simplifications in other parts of the compiler (removes notes, special
cases, and hacks for `dataToTag#`). Here are some example code we
generate:
Program:
{{{
data T = T1 | T2
main = do
print (I# (dataToTag# f))
print (I# (dataToTag# a))
where
{-# NOINLINE f #-}
f = T2
{-# NOINLINE a #-}
a = f
}}}
For the first `dataToTag#` we generate:
{{{
_s1yo::I64 = 1; // CmmAssign
}}}
for the second
{{{
// ======= DATA TO TAG ========
Hp = Hp - 16; // CmmAssign
I64[Sp - 24] = c1yE; // CmmStore
R1 = a_r1lF_closure; // CmmAssign
Sp = Sp - 24; // CmmAssign
if (R1 & 7 != 0) goto c1yE; else goto c1yF; // CmmCondBranch
c1yF: // global
call (I64[R1])(R1) returns to c1yE, args: 8, res: 8, upd: 24; //
CmmCall, this is where we evalaute the arg
c1yE: // global
_c1yD::I64 = R1; // CmmAssign
// ======= DATA TO TAG SMALL FAMILY ========
_s1yr::I64 = _c1yD::I64 & 7 - 1; // CmmAssign, read the tag bits
}}}
If I make this type a "big family", then we generate (for the second
`dataToTag#`)
{{{
// ======= DATA TO TAG ========
Hp = Hp - 16; // CmmAssign
I64[Sp - 24] = c1A0; // CmmStore
R1 = a_r1mL_closure; // CmmAssign
Sp = Sp - 24; // CmmAssign
if (R1 & 7 != 0) goto c1A0; else goto c1A1; // CmmCondBranch
c1A1: // global
call (I64[R1])(R1) returns to c1A0, args: 8, res: 8, upd: 24; //
CmmCall, enter the argument
c1A0: // global
_c1zZ::I64 = R1; // CmmAssign
// ======= DATA TO TAG GENERAL CASE ========
_s1zN::I64 = %MO_UU_Conv_W32_W64(I32[I64[_c1zZ::I64 & (-8)] - 4]);
// CmmAssign, read info table
}}}
The patch is not ready (I'll need to update some notes, I also left some
TODOs and questions in the code) but it fixes the bug and demonstrates
that this is possible (and even easy) to do in Cmm.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15696#comment:43>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list