1// { dg-do compile { target i?86-*-* x86_64-*-* } }
2// { dg-options "-O3 -fwhole-program -msse2" }
3
4typedef long unsigned int __darwin_size_t;
5typedef __darwin_size_t size_t;
6
7typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
8typedef float __v4sf __attribute__ ((__vector_size__ (16)));
9extern inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_mul_ps (__m128 __A, __m128 __B) {
10    return (__m128) __builtin_ia32_mulps ((__v4sf)__A, (__v4sf)__B);
11}
12extern inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_set1_ps (float __F) {
13    return __extension__ (__m128)(__v4sf){
14	__F, __F, __F, __F };
15}
16extern inline __m128 __attribute__((__gnu_inline__, __always_inline__, __artificial__)) _mm_setr_ps (float __Z, float __Y, float __X, float __W) {
17}
18typedef float real;
19template <typename T, int N> struct vectorX {
20};
21template<> struct vectorX<float, 3> {
22    union {
23	__m128 s;
24	struct {
25	};
26    };
27    vectorX(__m128 s) : s(s) {
28    }
29
30}
31__attribute__((aligned));
32template<> struct vectorX<float, 4> {
33    typedef float T;
34    typedef vectorX<float, 4> V;
35    union {
36	__m128 s;
37	struct {
38	    T r, g, b, a;
39	};
40    };
41    vectorX(T a_, T b, T c, T d = 1) : s(_mm_setr_ps(a_,b,c,d)) {
42    }
43    vectorX(__m128 s) : s(s) {
44    }
45    vectorX(const V &t) : s(t.s) {
46    }
47    V &operator *=(const T t) {
48	s = _mm_mul_ps(s, _mm_set1_ps(t));
49	return *this;
50    }
51    inline V operator *(const T t) const __attribute__((always_inline)) {
52	return V(*this) *= t;
53    };
54}
55__attribute__((aligned));
56typedef vectorX<real, 3> color3;
57typedef vectorX<real, 4> color4;
58typedef color3 color;
59static inline color4 c3to4(color c) {
60    color4 res(c.s);
61    res.a=1;
62    return res;
63}
64static inline color c4to3(color4 c) {
65    return color(c.s);
66}
67static inline color4 to_premultiplied(color c, real a) {
68    color4 res = c3to4(c);
69    return res * a;
70}
71static inline color4 to_premultiplied(color4 cs) {
72    return to_premultiplied(c4to3(cs), cs.a);
73}
74struct texture {
75};
76struct flat_texture : public texture {
77    color4 c;
78    flat_texture(const color4 &c) : c(to_premultiplied(c)) {
79    }
80};
81struct checkerboard_texture : public texture {
82    color4 even, odd;
83    checkerboard_texture(const color4 &even, const color4 &odd) : even(to_premultiplied(even)), odd(to_premultiplied(odd)) {
84    }
85};
86struct texture_placement {
87    texture *tex;
88};
89struct surface {
90    texture_placement textures[16];
91    size_t texcount;
92};
93struct primitive {
94    surface mat;
95};
96static void set_color(primitive *p, color4 c) {
97    p->mat.textures[0].tex = new flat_texture(c);
98}
99static primitive **checkerboard_scene(int *pi) {
100    primitive **prims = new primitive*[6];
101    set_color(prims[0], color4(.7,.7,.7));
102    prims[1]->mat.textures[prims[1]->mat.texcount++].tex = new checkerboard_texture(color4(1,.1,.1),color4(.1,.15,1));
103    set_color(prims[2], color4(.7,.9,.7));
104}
105int main (int argc, char * const argv[]) {
106    int primi;
107    primitive **prims = checkerboard_scene(&primi);
108}
109