ext_vector_type cg-gen crash on x86-64 and some questions on the ABI

I have some code that simplified is:

///////////////////////////////
#include <math.h>
#include <stdint.h>

#if __has_feature(attribute_ext_vector_type)
typedef float __attribute__((ext_vector_type (3))) float3;
typedef int32_t __attribute__((ext_vector_type (3))) int3;
typedef union float3_u {
   float3 v;
   float a[3];
} float3_u;
#endif

struct lwcoord {
   float3 offs;
   int3 seg;
};
static float3
vf3_set(float x, float y, float z)
{
   float3_u uc = {.a = {x,y,z}};
   return uc.v;
}
static int3
vi3_set(int32_t a, int32_t b, int32_t c)
{
   union {
     int3 v;
     struct {
       int32_t x, y, z;
     } s;
   } u;

   u.s.x = a;
   u.s.y = b;
   u.s.z = c;

   return u.v;
}

typedef struct lwcoord lwcoord;

void
lwc_set(lwcoord *coord, float x, float y, float z)
{
   coord->offs = vf3_set(x, y, z);
   coord->seg = vi3_set(0, 0, 0); // Remove this and it compiles
}

///////////////////////////////

Compiling this for x86-64 results in the following crash (using the clang version distributed with Snow Leopard).

1. <eof> parser at end of file
2. Code generation
3. Running pass 'X86 DAG->DAG Instruction Selection' on function '@lwc_set'

It compiles fine with x86 (32 bit).

It also seems to be fine if you remove the vi3_set line, but not if you remove the vf3_set line.

Now some questions on the semantics of the ext_vector_type, since it is not that well documented in the clang extensions page.

1. What is the ABI for an ext_vector_type? Will the vectors be passed in SSE registers if they are passed as function arguments, or will they be passed by address?
2. Sizeof (float3) returns 12 and not 16 as I would have guessed for alignment reasons, why is this the case? Assuming you want to use SSE for computing with the vectors, they must be aligned IIRC.

Regards,
Mattias

I have some code that simplified is:

This seems to work with clang mainline, at least with 'clang t.c -c -O -m64'

Now some questions on the semantics of the ext_vector_type, since it is
not that well documented in the clang extensions page.

1. What is the ABI for an ext_vector_type? Will the vectors be passed in
SSE registers if they are passed as function arguments, or will they be
passed by address?

vectors that correspond to SSE types (e.g. 4 x float) should be passed and returned in sse registers.

2. Sizeof (float3) returns 12 and not 16 as I would have guessed for
alignment reasons, why is this the case? Assuming you want to use SSE
for computing with the vectors, they must be aligned IIRC.

That is really bad, please file a bug. We don't really maintain a stable ABI for non-native vector types, so we can fix this.

-Chris

Chris Lattner wrote:

I have some code that simplified is:

This seems to work with clang mainline, at least with 'clang t.c -c -O -m64'

OK, great. I will update my clang to trunk.

2. Sizeof (float3) returns 12 and not 16 as I would have guessed for
alignment reasons, why is this the case? Assuming you want to use SSE
for computing with the vectors, they must be aligned IIRC.

That is really bad, please file a bug. We don't really maintain a stable ABI for non-native vector types, so we can fix this.

Done, filed as bug #5265.

Regards,
Mattias