[GHC] #11792: Optimised unsafe FFI call can get wrong argument

GHC ghc-devs at haskell.org
Wed May 18 15:06:40 UTC 2016


#11792: Optimised unsafe FFI call can get wrong argument
-------------------------------------+-------------------------------------
        Reporter:  Szunti            |                Owner:
            Type:  bug               |               Status:  new
        Priority:  normal            |            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 hsyl20):

 For the record, the unsafe foreign call in Cmm after sink assignments:

 {{{#!C
 (_s3N3::I64) = call "ccall" arg hints:  [, , ,]  result hints:  []
 third_arg(0, 0, 7457,
 %MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(%MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(%MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(%MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(I64[Sp
 + 16] * _s3MA::I64)) / 255 +
 %MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(%MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(%MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(I64[Sp
 + 24] * _s3MA::I64)) / 255 +
 %MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(%MO_UU_Conv_W32_W64(%MO_UU_Conv_W64_W32(I64[R1
 + 7] * _s3MA::I64)) / 255 << 8)))) << 8)))) << 8)) + 255)));
 }}}

 Indeed edx doesn't seem to be in the clobber list when the code for the
 fourth argument is generated and we obtain:

 {{{#!asm
   405dc9:       ba 21 1d 00 00          mov    $0x1d21,%edx    ; 0x1d21 is
 the third arg
   405dce:       b9 ff 00 00 00          mov    $0xff,%ecx
   405dd3:       48 8b 5b 07             mov    0x7(%rbx),%rbx
   405dd7:       48 0f af d8             imul   %rax,%rbx
   405ddb:       48 89 c2                mov    %rax,%rdx       ; problem
   ...
   405e43:       e8 82 03 00 00          callq  4061ca <third_arg>
 }}}


 The following note in compiler/cmm/CmmNode.hs seems to be relevant:
 {{{#!hs
 {- Note [Register parameter passing]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 On certain architectures, some registers are utilized for parameter
 passing in the C calling convention.  For example, in x86-64 Linux
 convention, rdi, rsi, rdx and rcx (as well as r8 and r9) may be used for
 argument passing.  These are registers R3-R6, which our generated
 code may also be using; as a result, it's necessary to save these
 values before doing a foreign call.  This is done during initial
 code generation in callerSaveVolatileRegs in StgCmmUtils.hs.  However,
 one result of doing this is that the contents of these registers
 may mysteriously change if referenced inside the arguments.  This
 is dangerous, so you'll need to disable inlining much in the same
 way is done in cmm/CmmOpt.hs currently.  We should fix this!
 -}
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11792#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list