[GHC] #11792: Optimised unsafe FFI call can get wrong argument
GHC
ghc-devs at haskell.org
Tue May 24 21:54:44 UTC 2016
#11792: Optimised unsafe FFI call can get wrong argument
-------------------------------------+-------------------------------------
Reporter: Szunti | Owner:
Type: bug | Status: new
Priority: high | Milestone:
Component: Compiler | Version: 7.10.3
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):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by osa1):
I spent some time debugging this. Here are codes for FFI function
arguments
(before register allocation):
{{{
first arg: [ xorl %edi,%edi]
second arg: [ xorl %esi,%esi]
third arg: [ movl $7457,%edx]
fourth arg: [ movl $255,%vI_n4I8, movq 7(%rbx),%vI_n4Ia,
imulq %vI_s4pW,%vI_n4Ia, movl %vI_n4Ia,%eax,
xorq %rdx,%rdx,
divq %vI_n4I8, movq %rax,%vI_n4Ib, shlq $8,%vI_n4Ib,
movl %vI_n4Ib,%vI_n4Ic, movl $255,%vI_n4Id,
movq 24(%rbp),%vI_n4If, imulq %vI_s4pW,%vI_n4If,
movl %vI_n4If,%eax, xorq %rdx,%rdx, divq
%vI_n4Id,
movq %rax,%vI_n4Ih, addq %vI_n4Ic,%vI_n4Ih,
movl %vI_n4Ih,%vI_n4Ii, shlq $8,%vI_n4Ii,
movl %vI_n4Ii,%vI_n4Ij, movl $255,%vI_n4Ik,
movq 16(%rbp),%vI_n4Im, imulq %vI_s4pW,%vI_n4Im,
movl %vI_n4Im,%eax, xorq %rdx,%rdx, divq
%vI_n4Ik,
movq %rax,%vI_n4Io, addq %vI_n4Ij,%vI_n4Io,
movl %vI_n4Io,%vI_n4Ip, shlq $8,%vI_n4Ip,
movl %vI_n4Ip,%vI_n4Iq, leaq
255(%vI_n4Iq),%vI_n4Ir,
movl %vI_n4Ir,%ecx]
}}}
These look correct to me. Since the code mostly uses virtual registers
`%edx`
isn't overridden at this point. So I think the problem may be in register
allocation. I don't know how register allocation in GHC is working, but I
looked at liveness information output, and it shows this for the `call
third_arg` instruction:
{{{
call third_arg
# born: %r8 %r9 %r10 %r11 %r16 %r17 %r18 %r19 %r20 %r21 %r24 %r25
%r26 %r27 %r28 %r29 %r30 %r31 %r32 %r33 %r34 %r35 %r36 %r37 %r38 %r39
# w_dying: %r2 %r3 %r4 %r5 %r8 %r9 %r10 %r11 %r16 %r17 %r18 %r19 %r20
%r21 %r24 %r25 %r26 %r27 %r28 %r29 %r30 %r31 %r32 %r33 %r34 %r35 %r36 %r37
%r38 %r39
}}}
I don't quite understand what's happening here (what are all those
registers??), but I'd expect this instruction to "read" (or "use") `%edx`.
So
`%edx` would have to stay live between `third arg` and this call
instruction,
and so register allocation would have to generate some spill instructions
when
allocating registers for fourth argument if available registers are not
enough.
At least this is how my compiler is doing it.
I may have another look tomorrow.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11792#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list