1 // PR rtl-optimization/40924
2 // { dg-do run }
3
4 extern "C" void abort (void);
5
6 #define MAY_ALIAS __attribute__((__may_alias__))
7
8 typedef struct { float v[2]; } floata;
9 typedef struct { int v[2]; } inta;
10
11 typedef unsigned int uint MAY_ALIAS;
12 typedef signed int sint MAY_ALIAS;
13 typedef float flt MAY_ALIAS;
14
15 static inline unsigned short
less_than(inta a,inta b)16 less_than (inta a, inta b)
17 {
18 unsigned short r = 0;
19 const uint *p1 = (const uint *) &a;
20 const uint *p2 = (const uint *) &b;
21 for (int i=0; i < 2; i++)
22 if (p1[i] < p2[i]) r |= (1 << i);
23 return r;
24 }
25
26 static inline inta
multiply(inta b,inta c)27 multiply (inta b, inta c)
28 {
29 inta r;
30 sint *p3 = (sint *) &c;
31 for (int i=0; i < 2; i++)
32 r.v[i] = (int) (b.v[i] * p3[i] & 0xFFFFFFFF);
33 return r;
34 }
35
36 static inline floata
gather(inta indexes,const void * baseAddr)37 gather (inta indexes, const void *baseAddr)
38 {
39 floata r;
40
41 sint *idx = (sint *) &indexes;
42 flt *src = (flt *) baseAddr;
43 for (int i=0; i < 2; i++)
44 r.v[i] = *(src + idx[i]);
45 return r;
46 }
47
48 static inline inta
add(const inta & b,const inta & c)49 add (const inta &b, const inta &c)
50 {
51 inta result;
52 sint *r = (sint *) &result;
53
54 for (int i=0; i < 2; i++)
55 r[i] = b.v[i] + c.v[i];
56 return result;
57 }
58
59 struct uintv
60 {
61 inta data;
uintvuintv62 inline uintv () { data.v[0] = 0; data.v[1] = 1; }
uintvuintv63 inline uintv (unsigned int a)
64 {
65 for (int i=0; i < 2; i++)
66 *(uint *) &data.v[i] = a;
67 }
uintvuintv68 inline uintv (inta x) : data (x) {}
69 inline uintv operator* (const uintv &x) const
70 { return multiply (data, x.data); }
71 inline uintv operator+ (const uintv &x) const
72 { return uintv (add (data, x.data)); }
73 inline unsigned short operator< (const uintv &x) const
74 { return less_than (data, x.data); }
75 };
76
77 struct floatv
78 {
79 floata data;
floatvfloatv80 explicit inline floatv (const uintv &x)
81 {
82 uint *p2 = (uint *) &x.data;
83 for (int i=0; i < 2; i++)
84 data.v[i] = p2[i];
85 }
floatvfloatv86 inline floatv (const float *array, const uintv &indexes)
87 {
88 const uintv &offsets = indexes * uintv (1);
89 data = gather (offsets.data, array);
90 }
91 unsigned short operator== (const floatv &x) const
92 {
93 unsigned short r = 0;
94 for (int i=0; i < 2; i++)
95 if (data.v[i] == x.data.v[i]) r |= (1 << i);
96 return r;
97 }
98 };
99
100 int
main()101 main ()
102 {
103 const float array[2] = { 2, 3 };
104 for (uintv i; (i < 2) == 3; i = i + 2)
105 {
106 const floatv ii (i + 2);
107 floatv a (array, i);
108 if ((a == ii) != 3)
109 abort ();
110 }
111 }
112