[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