[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