Support for gcc vector attributes, SIMD builtins

Mike Farnsworth mike.farnsworth at gmail.com
Sat Feb 5 22:24:57 PST 2011


On 02/01/2011 10:38 AM, Iain Buclaw wrote:
> I haven't given it much thought on how internal representation could be, but I'd
> lean on using unions in D code for usage in the language. As its probably most
> portable.
> 
> For example, one of the older 'hello vectors' I know of:
> 
> import std.c.stdio;
> 
> pragma(set_attribute, __v4sf, vector_size(16));
> typedef float __v4sf;
> 
> union f4vector
> {
>     __v4sf v;
>     float[4] f;
> }
> 
> int main()
> {
>     f4vector a, b, c;
> 
>     a.f = [1, 2, 3, 4];
>     b.f = [5, 6, 7, 8];
> 
>     c.v = a.v + b.v;
>     printf("%f, %f, %f, %f\n", c.f[0], c.f[1], c.f[2], c.f[3]);
> 
>     return 0;
> }

I've been giving this a serious try, and while the above works, I can't
get any __builtin_... functions to actually work.  I've added support
for the VECTOR_TYPE tree code in gcc_type_to_d_type(tree) function (in
d_builtins2.cc):

        case VECTOR_TYPE:
        {
            tree baseType = TREE_TYPE(t);
            d = gcc_type_to_d_type(baseType, printstuff);
            if (d)
                return d;
            break;
        }

This allows it to succeed in interpreting the SSE-related builtins in
gcc_type_to_d_type(tree).  Note that all it does is grab the base vector
element type and convert that to a D type so as not to confuse the
frontend; this way it matches the typedef for __v4sf, so as long as we
use the union we won't lose data before we can pass it to a builtin.

I've verified (with a bunch of verbatim(...) calls) that the compiler
*is* pushing function declarations of things like __builtin_ia32_addps,
but I cannot for the life of me get my actual D code to see any of those
functions:

========
pragma(set_attribute, __v4sf, vector_size(16));
typedef float __v4sf;

union v4f
{
    __v4sf v;
    float[4] f;
}

import gcc.builtins;

pragma(set_attribute, _mm_add_ps, always_inline, artificial);

__v4sf _mm_add_ps(__v4sf __A, __v4sf __B)
{
    return __builtin_ia32_addps(__A, __B);
}
========

And I get:
../../Vectors.d:24: Error: undefined identifier __builtin_ia32_addps

If I explicitly prefix the call as
gcc.builtins.__builtin_ia32_addps(__A, __B)

I get:
../../Vectors.d:24: Error: undefined identifier module
builtins.__builtin_ia32_addps

Which doesn't make a whole lot of sense.

I thought there might be something wrong recognizing the argument types,
so I tried __isnanf and __isnan builtins as well, and...same failures.
I don't think any of the builtins besides the alias declarations are
working, honestly.  (__builtin_Clong, __builtin_Culong, etc do work, but
that's the only thing from gcc.builtins that I can access without errors).

Any hints?

-Mike


More information about the D.gnu mailing list