[LLVMdev] Vector types as function arguments and interfacing with C
Brendan Younger
brendan at brendanyounger.com
Tue Jul 29 10:25:53 PDT 2008
On Jul 29, 2008, at 12:41 PM, Duncan Sands wrote:
> Hi,
>
>> I want to be able to write a function like this
>>
>> define <2 x double> @add(<2 x double> %a, <2 x double> %b) nounwind {
>> %c = add <2 x double> %a, %b
>> ret <2 x double> %c
>> }
>>
>> and then call it from C code. What is the appropriate translation of
>> the <2 x double> vector type into C? I've tried packed structs and
>> "typedef double vec_double __attribute__ ((__vector_size__ (16)))"
>> but
>> in both cases, it seems that GCC passes these in as pointers rather
>> than in registers.
>
> try reading about the gcc vector extensions in the "C Extensions"
> chapter
> of the gcc docs.
I have tried GCC's vector extensions, however, it seems that GCC and
LLVM don't exactly agree on the ABI for these vector types. On x86,
they both pass the arguments in xmm0 and xmm1 and everything is
roses. However, on PPC, the following happens:
define <2 x double> @add(<2 x double> %a, <2 x double> %b) nounwind {
%result = add <2 x double> %a, %b
ret <2 x double> %result
}
compiles to (under the latest 2.4svn)
_add:
fadd f2, f2, f4
fadd f1, f1, f3
blr
which means that LLVM very sensibly passes the doubles in registers
f1, f2, f3, f4. However, on the C end, GCC compiles
typedef double interval_t __attribute__ ((__vector_size__(16)));
interval_t add(interval_t a, interval_t b) {
return a + b;
}
to the following (under gcc version 4.0.1 (Apple Inc. build 5484))
_add:
lfd f0,80(r1)
lfd f12,64(r1)
lfd f13,72(r1)
fadd f12,f12,f0
lfd f0,88(r1)
fadd f13,f13,f0
stfd f12,-32(r1)
stfd f13,-24(r1)
lwz r3,-32(r1)
lwz r4,-28(r1)
lwz r5,-24(r1)
lwz r6,-20(r1)
blr
which means that GCC is choosing to pass the doubles on the stack
instead of in registers and so I cannot mix the LLVM code with the GCC
code.
Now, I realize that __vector_size__ is a GCC extension and so they're
allowed to do whatever they want as far as ABIs are concerned, but is
there any plan to have GCC match LLVM's ABI or vice-versa?
And on a somewhat unrelated note, I have code that changes the
floating point rounding mode to round-to-negative-infinity. Does LLVM
reorder floating point computations or do any simplification which
might be invalid with that rounding mode rather than the default round-
to-nearest? I've looked at the various "opt" options and can't find
any that deal with floating point optimizations so I assume no.
Brendan Younger
More information about the llvm-dev
mailing list