[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