On Fri, Mar 1, 2013 at 9:34 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Fri, Mar 1, 2013 at 3:43 PM, Ian Lance Taylor <i...@google.com> wrote: >> On Fri, Mar 1, 2013 at 4:57 AM, Uros Bizjak <ubiz...@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