This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, go] Passing Complex64 and Complex128 values via reflect.Call (using libffi) introduces ABI mismatch


On Fri, Mar 1, 2013 at 9:34 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Fri, Mar 1, 2013 at 3:43 PM, Ian Lance Taylor <iant@google.com> wrote:
>> On Fri, Mar 1, 2013 at 4:57 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>>>
>>> Due to the fact that libFFI does not handle C99 _Complex arguments
>>> correctly [1], libgo passes Complex64 and Complex128 arguments via a
>>> temporary structure. However, passing parts of complex number in a
>>> structure is not the same as passing true C99 _Complex value, so this
>>> workaround introduces ABI mismatch between caller and callee. This
>>> mismatch results in wrong passed values of complex types.
>>>
>>> Fortunately all x86 ABIs tolerate this mismatch, but other targets
>>> (i.e. alpha) don't have this privilege.
>>
>> Is there a PR open against libffi?
>>
>> Do we have any idea which targets pass complex in a manner different
>> than a struct of two float/doubles?  Your patch assumes that only x86
>> targets work, but I would expect that many targets work that way.
>
> $ grep -R "define TARGET_SPLIT_COMPLEX_ARG" config
> config/rs6000/rs6000.c:#define TARGET_SPLIT_COMPLEX_ARG
> hook_bool_const_tree_true
> config/xtensa/xtensa.c:#define TARGET_SPLIT_COMPLEX_ARG
> hook_bool_const_tree_true
> config/alpha/alpha.c:#define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
>
> We can probably define Complex64 type as "struct { float re, im; }"
> and Complex128 as "struct { double re, im; }" for these targets. What
> do you think about this approach?

The odd thing is that those are exactly the targets I would expect to
work with the current code.  I don't see why those should be the
targets that fail.

Right now the reflect.Call implementation is passing Go complex64 and
complex128 types as though they were implemented as struct { float32;
float32 } and struct { float64; float64 } respectively.  The code
assumes that a function that takes a complex64 argument can be called
as though it took a struct argument instead.  Apparently that does not
work on Alpha.  So the case that fails is when the calling convention
for a complex number differs from the calling convention for passing a
struct.

In the Alpha calling convention, how is a complex number passed?  How
is a struct of two floats/doubles passed?

I think your suggestion of implementing complex as a struct would be
somewhat painful to implement, because it would require generating
complicated code for all complex arithmetic.

I'm not strongly opposed to your original patch, I just think it
overreaches in assuming that only x86 works.  What if we flip it
around and assume that only Alpha falis?

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]