Test 4221 (under the ffi folder) segfaults with the new codegen turned on. Before:
0xb7a68c78: 0x822fadc <stg_ap_v_info> 0xb7a68c74: 0xb7ab8f94 0xb7a68c70: 0xb7ab8fa4 0xb7a68c6c: 0x8134dc0 <stT_info> 0xb7a68c68: 0xb7ab8f94 0xb7a68c64: 0x822f9f4 <stg_marked_upd_frame_info> 0xb7a68c60: 0xb7ab8f48 0xb7a68c5c: 0xb7ab8f88 0xb7a68c58: 0x4063a000 # this is the counted float; this 0xb7a68c54: 0x0 # val is 157.0 0xb7a68c50: 0x804bbc0 <c1jG_info> After: 0xb7a68c78: 0x822fadc <stg_ap_v_info> 0xb7a68c74: 0xb7ab8f94 0xb7a68c70: 0xb7ab8fa4 0xb7a68c6c: 0x8134dc0 <stT_info> 0xb7a68c68: 0xb7ab8f94 0xb7a68c64: 0x822f9f4 <stg_marked_upd_frame_info> 0xb7a68c60: 0xb7ab8f48 0xb7a68c5c: 0xb7ab8f88 0xb7a68c58: 0x4063a000 0xb7a68c54: 0x0 It then jumps c1jL_entry to which jumps to stg_gc_d1_info which segfaults on return because 0xb7a68c54 is not a valid address. The offending assembly: (gdb) disas Dump of assembler code for function c1jG_info: 0x0804bbc0 <+0>: fldl 0x4(%ebp) 0x0804bbc3 <+3>: fstp %st(1) 0x0804bbc5 <+5>: fstl 0x4(%ebp) 0x0804bbc8 <+8>: add $0x4,%ebp => 0x0804bbcb <+11>: ffree %st(0) 0x0804bbcd <+13>: ffree %st(1) 0x0804bbcf <+15>: ffree %st(2) 0x0804bbd1 <+17>: ffree %st(3) 0x0804bbd3 <+19>: ffree %st(4) 0x0804bbd5 <+21>: ffree %st(5) 0x0804bbd7 <+23>: jmp 0x804bbdc <c1jL_entry> 0x0804bbd9 <+25>: lea 0x0(%esi),%esi Optimized C--: block_c1jG_entry() { [const 484;, const 32;] } c1jG: // emitReturn: Sequel: Assign _s1ev::F64 = F64[Sp + 4]; ; F64[Sp + 4] = _s1ev::F64; Sp = Sp + 4; jump block_c1jL_entry (); } Regardless of whether or not it's right, this is pretty dumb code, so we should fix the codegen not to do that. I'm not sure what this code is /supposed/ to be doing, or what generated it. This bit might be correct and the FFI call leading up to it may be wrong. I have a prodigous amout of difficulty trying to figure out if what's on the stack is right or not: maybe we could have a chat about this. Cheers, Edward Some possible useful raw data: Raw C--: block_c1jh_entry() { [const 484;, const 32;] } c1jh: // emitReturn: Sequel: Assign _s1ev::F64 = F64[Sp + 4]; _s1ev::F64 = _s1ev::F64; F64[Sp + 4] = _s1ev::F64; Sp = Sp + 4; jump block_c1jm_entry (); } after manifest SP {offset c1j0: _s1el::I32 = I32[Sp + 4]; // CmmAssign I32[Sp - 4] = _s1el::I32; // CmmStore _s1ei::I32 = I32[Sp + 0]; // CmmAssign if (Sp - 12 < SpLim) goto u1Am; else goto u1Ao; // CmmCondBranch u1Am: Sp = Sp + 12; // CmmAssign goto c1j7; // CmmBranch c1j7: // outOfLine here R1 = call_fn_blob_rk2_closure; // CmmAssign Sp = Sp - 12; // CmmAssign call (stg_gc_fun)(...) returns to Nothing (12) (0) with update frame 12; // CmmCall u1Ao: Sp = Sp + 12; // CmmAssign goto c1j3; // CmmBranch c1j3: // outOfLine should follow: if (_s1ei::I32 & 3 != 0) goto c1j9; else goto c1j8; // CmmCondBranch c1j9: // emitReturn: Sequel: Assign _s1fO::I32 = _s1ei::I32; // CmmAssign I32[Sp - 20] = _s1fO::I32; // CmmStore goto u1Ai; // CmmBranch u1Ai: Sp = Sp - 20; // CmmAssign goto c1jc; // CmmBranch c1j8: // emitCall: Sequel: Assign R1 = _s1ei::I32; // CmmAssign I32[Sp - 20] = c1iw; // CmmStore Sp = Sp - 20; // CmmAssign call (I32[_s1ei::I32])(...) returns to Just c1iw (4) (4) with update frame 4; // CmmCall c1iw: _s1fO::I32 = R1; // CmmAssign I32[Sp + 0] = _s1fO::I32; // CmmStore Sp = Sp + 4; // CmmAssign goto u1Af; // CmmBranch u1Af: Sp = Sp - 4; // CmmAssign goto c1jc; // CmmBranch c1jc: // outOfLine should follow: _s1fO::I32 = I32[Sp + 0]; // CmmAssign _s1ep::I32 = I32[_s1fO::I32 + 3]; // CmmAssign I32[Sp + 0] = _s1ep::I32; // CmmStore _s1el::I32 = I32[Sp + 4]; // CmmAssign if (_s1el::I32 & 3 != 0) goto c1jf; else goto c1je; // CmmCondBranch c1jf: // emitReturn: Sequel: Assign _s1el::I32 = I32[Sp + 4]; // CmmAssign _s1fP::I32 = _s1el::I32; // CmmAssign I32[Sp - 4] = _s1fP::I32; // CmmStore goto u1Aj; // CmmBranch u1Aj: Sp = Sp - 4; // CmmAssign goto c1jj; // CmmBranch c1je: // emitCall: Sequel: Assign _s1el::I32 = I32[Sp + 4]; // CmmAssign R1 = _s1el::I32; // CmmAssign I32[Sp - 4] = c1iG; // CmmStore _s1el::I32 = I32[Sp + 4]; // CmmAssign Sp = Sp - 4; // CmmAssign call (I32[_s1el::I32])(...) returns to Just c1iG (4) (4) with update frame 4; // CmmCall c1iG: _s1fP::I32 = R1; // CmmAssign I32[Sp + 0] = _s1fP::I32; // CmmStore Sp = Sp + 4; // CmmAssign goto u1Ag; // CmmBranch u1Ag: Sp = Sp - 4; // CmmAssign goto c1jj; // CmmBranch c1jj: // outOfLine should follow: _s1fP::I32 = I32[Sp + 0]; // CmmAssign _s1eq::F64 = F64[_s1fP::I32 + 3]; // CmmAssign I32[Sp + 0] = c1jh; // CmmStore _s1ep::I32 = I32[Sp + 4]; // CmmAssign foreign call "ccall" arg hints: [PtrHint,] result hints: [] call_fn_blob(...) returns to c1jh args: ([_s1ep::I32, _s1eq::F64]) ress: ([_s1ev::F64]) with update frame 4; // CmmForeignCall c1jh: // emitReturn: Sequel: Assign _s1ev::F64 = F64[Sp + 4]; // CmmAssign _s1ev::F64 = _s1ev::F64; // CmmAssign F64[Sp + 4] = _s1ev::F64; // CmmStore Sp = Sp + 4; // CmmAssign goto u1Ak; // CmmBranch u1Ak: goto c1jm; // CmmBranch c1jm: Hp = Hp + 12; // CmmAssign if (Hp > HpLim) goto c1jn; else goto c1jl; // CmmCondBranch c1jn: HpAlloc = 12; // CmmAssign // outOfLine here _s1ev::F64 = F64[Sp + 0]; // CmmAssign F64[Sp - 4] = _s1ev::F64; // CmmStore I32[Sp + 4] = c1iT; // CmmStore Sp = Sp - 4; // CmmAssign call stg_gc_d1(...) returns to Just c1iT (12) (12) with update frame 4; // CmmCall c1iT: _s1ev::F64 = F64[Sp + 0]; // CmmAssign F64[Sp + 4] = _s1ev::F64; // CmmStore Sp = Sp + 12; // CmmAssign goto u1Ah; // CmmBranch u1Ah: Sp = Sp - 8; // CmmAssign goto c1jm; // CmmBranch c1jl: // outOfLine should follow: // allocDynClosure I32[Hp - 8] = GHC.Types.D#_con_info; // CmmStore _s1ev::F64 = F64[Sp + 0]; // CmmAssign F64[Hp - 4] = _s1ev::F64; // CmmStore _c1iZ::I32 = Hp - 8; // CmmAssign // emitReturn: Sequel: Return R1 = _c1iZ::I32 + 1; // CmmAssign Sp = Sp + 16; // CmmAssign call (I32[Sp + 0])(...) returns to Nothing (4) (0) with update frame 4; // CmmCall } post dead assignment elimination {offset c1j0: _s1el::I32 = I32[(old + 8)]; // CmmAssign I32[(slot<_s1el::I32> + 4)] = _s1el::I32; // CmmStore _s1ei::I32 = I32[(old + 12)]; // CmmAssign if (Sp - <highSp> < SpLim) goto c1j7; else goto c1j3; // CmmCondBranch c1j7: // outOfLine here R1 = call_fn_blob_rk2_closure; // CmmAssign call (stg_gc_fun)(...) returns to Nothing (12) (0) with update frame 12; // CmmCall c1j3: // outOfLine should follow: if (_s1ei::I32 & 3 != 0) goto c1j9; else goto c1j8; // CmmCondBranch c1j9: // emitReturn: Sequel: Assign _s1fO::I32 = _s1ei::I32; // CmmAssign I32[(slot<_s1fO::I32> + 4)] = _s1fO::I32; // CmmStore goto u1Ai; // CmmBranch u1Ai: goto c1jc; // CmmBranch c1j8: // emitCall: Sequel: Assign R1 = _s1ei::I32; // CmmAssign I32[(young<c1iw> + 4)] = c1iw; // CmmStore call (I32[_s1ei::I32])(...) returns to Just c1iw (4) (4) with update frame 4; // CmmCall c1iw: _s1fO::I32 = R1; // CmmAssign I32[(slot<_s1fO::I32> + 4)] = _s1fO::I32; // CmmStore goto u1Af; // CmmBranch u1Af: goto c1jc; // CmmBranch c1jc: // outOfLine should follow: _s1fO::I32 = I32[(slot<_s1fO::I32> + 4)]; // CmmAssign _s1ep::I32 = I32[_s1fO::I32 + 3]; // CmmAssign I32[(slot<_s1ep::I32> + 4)] = _s1ep::I32; // CmmStore _s1el::I32 = I32[(slot<_s1el::I32> + 4)]; // CmmAssign if (_s1el::I32 & 3 != 0) goto c1jf; else goto c1je; // CmmCondBranch c1jf: // emitReturn: Sequel: Assign _s1el::I32 = I32[(slot<_s1el::I32> + 4)]; // CmmAssign _s1fP::I32 = _s1el::I32; // CmmAssign I32[(slot<_s1fP::I32> + 4)] = _s1fP::I32; // CmmStore goto u1Aj; // CmmBranch u1Aj: goto c1jj; // CmmBranch c1je: // emitCall: Sequel: Assign _s1el::I32 = I32[(slot<_s1el::I32> + 4)]; // CmmAssign R1 = _s1el::I32; // CmmAssign I32[(young<c1iG> + 4)] = c1iG; // CmmStore _s1el::I32 = I32[(slot<_s1el::I32> + 4)]; // CmmAssign call (I32[_s1el::I32])(...) returns to Just c1iG (4) (4) with update frame 4; // CmmCall c1iG: _s1fP::I32 = R1; // CmmAssign I32[(slot<_s1fP::I32> + 4)] = _s1fP::I32; // CmmStore goto u1Ag; // CmmBranch u1Ag: goto c1jj; // CmmBranch c1jj: // outOfLine should follow: _s1fP::I32 = I32[(slot<_s1fP::I32> + 4)]; // CmmAssign _s1eq::F64 = F64[_s1fP::I32 + 3]; // CmmAssign I32[(young<c1jh> + 4)] = c1jh; // CmmStore _s1ep::I32 = I32[(slot<_s1ep::I32> + 4)]; // CmmAssign foreign call "ccall" arg hints: [PtrHint,] result hints: [] call_fn_blob(...) returns to c1jh args: ([_s1ep::I32, _s1eq::F64]) ress: ([_s1ev::F64]) with update frame 4; // CmmForeignCall c1jh: // emitReturn: Sequel: Assign _s1ev::F64 = F64[(slot<_s1ev::F64> + 8)]; // CmmAssign _s1ev::F64 = _s1ev::F64; // CmmAssign F64[(slot<_s1ev::F64> + 8)] = _s1ev::F64; // CmmStore goto u1Ak; // CmmBranch u1Ak: goto c1jm; // CmmBranch c1jm: Hp = Hp + 12; // CmmAssign if (Hp > HpLim) goto c1jn; else goto c1jl; // CmmCondBranch c1jn: HpAlloc = 12; // CmmAssign // outOfLine here _s1ev::F64 = F64[(slot<_s1ev::F64> + 8)]; // CmmAssign F64[(young<c1iT> + 12)] = _s1ev::F64; // CmmStore I32[(young<c1iT> + 4)] = c1iT; // CmmStore call stg_gc_d1(...) returns to Just c1iT (12) (12) with update frame 4; // CmmCall c1iT: _s1ev::F64 = F64[(young<c1iT> + 12)]; // CmmAssign F64[(slot<_s1ev::F64> + 8)] = _s1ev::F64; // CmmStore goto u1Ah; // CmmBranch u1Ah: goto c1jm; // CmmBranch c1jl: // outOfLine should follow: // allocDynClosure I32[Hp - 8] = GHC.Types.D#_con_info; // CmmStore _s1ev::F64 = F64[(slot<_s1ev::F64> + 8)]; // CmmAssign F64[Hp - 4] = _s1ev::F64; // CmmStore _c1iZ::I32 = Hp - 8; // CmmAssign // emitReturn: Sequel: Return R1 = _c1iZ::I32 + 1; // CmmAssign call (I32[(old + 4)])(...) returns to Nothing (4) (0) with update frame 4; // CmmCall } _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users