
#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@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