[GHC] #12433: GHCi produces incorrect results when evaluating with compiled code
GHC
ghc-devs at haskell.org
Tue Jul 26 00:20:28 UTC 2016
#12433: GHCi produces incorrect results when evaluating with compiled code
-------------------------------------+-------------------------------------
Reporter: diatchki | Owner:
Type: bug | Status: new
Priority: highest | Milestone:
Component: Compiler | Version: 8.0.1
Resolution: | Keywords: ghci, dynamic
| linking, compiled code
Operating System: Linux | Architecture: x86_64
Type of failure: Incorrect result | (amd64)
at runtime | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by rwbarton):
The problem is in PIC code generation for jump tables (CmmSwitch). Here is
the problematic part of `haskellLex62`:
{{{
call $wcclass_r2lE_info(R2) returns to c2s5, args: 8, res: 8,
upd: 8;
c2s5:
_s2mn::I64 = I64[Sp + 8];
_s2mo::I64 = R1;
if (%MO_S_Ge_W64(R1, 12)) goto c2sB; else goto u2t1;
u2t1:
if (%MO_S_Lt_W64(_s2mo::I64, 0)) goto c2sB; else goto u2t2;
u2t2:
switch [0 .. 11] _s2mo::I64 {
case 0, 1, 2, 3, 4 : goto u2t7;
case 10 : goto c2sT;
case 11 : goto c2sV;
default: goto c2sB;
}
c2sV:
Hp = Hp + 48;
if (Hp > HpLim) goto c2sY; else goto c2sX;
c2sY:
HpAlloc = 48;
R1 = _s2mo::I64;
call stg_gc_unbx_r1(R1) returns to c2s5, args: 8, res: 8, upd:
8;
c2sX:
I64[Hp - 40] = sat_s2mp_info;
P64[Hp - 24] = P64[Sp + 24];
I64[Hp - 16] = :_con_info;
P64[Hp - 8] = GHC.Tuple.()_closure+1;
P64[Hp] = Hp - 40;
R1 = Hp - 14;
Sp = Sp + 32;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
}}}
Observe that `c2s5` is the continuation for the call to `$wcclass_r2lE`,
but it can also be returned to from the garbage collector after a failed
heap check. The variable `_s2mo` is initialized at `c2s5` and then still
live in the failed heap check block `c2sY`.
However, the assembly generated for the switch looks like
{{{
_c2s5:
movq 8(%rbp),%rax
movq %rbx,%rcx ; %rcx is _s2mo, set to R1 = %rbx
cmpq $18,%rbx
jge _c2sB
_u2t1:
testq %rcx,%rcx
jl _c2sB
_u2t2:
leaq _n2tK(%rip),%rbx
movslq (%rbx,%rcx,8),%rcx
addq %rcx,%rbx
jmp *%rbx
;; then a big jump table named _n2tK; in the case of 11, it jumps to _c2sV
_c2sY:
movq $48,904(%r13)
movq %rcx,%rbx
jmp *stg_gc_unbx_r1 at gotpcrel(%rip)
_c2sV:
addq $48,%r12
cmpq 856(%r13),%r12
ja _c2sY
}}}
In the failed heap check code at `_c2sY`, ghc thinks that `_s2mo` is still
in `%rcx`. But actually it was clobbered by the jump table calculation at
`_u2t2`.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12433#comment:3>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list