Brendan Younger
2008-Jul-29 15:59 UTC
[LLVMdev] Vector types as function arguments and interfacing with C
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. Brendan Younger
Duncan Sands
2008-Jul-29 16:41 UTC
[LLVMdev] Vector types as function arguments and interfacing with C
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. Ciao, Duncan.
Brendan Younger
2008-Jul-29 17:25 UTC
[LLVMdev] Vector types as function arguments and interfacing with C
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
Maybe Matching Threads
- [LLVMdev] Vector types as function arguments and interfacing with C
- [LLVMdev] Vector types as function arguments and interfacing with C
- [LLVMdev] [cfe-dev] Odd PPC inline asm constraint
- [LLVMdev] [cfe-dev] Odd PPC inline asm constraint
- [LLVMdev] [cfe-dev] Odd PPC inline asm constraint