1// PR rtl-optimization/40924
2// { dg-do run }
3
4extern "C" void abort (void);
5
6#define MAY_ALIAS __attribute__((__may_alias__))
7
8typedef struct { float v[2]; } floata;
9typedef struct { int v[2]; } inta;
10
11typedef unsigned int uint MAY_ALIAS;
12typedef signed int sint MAY_ALIAS;
13typedef float flt MAY_ALIAS;
14
15static inline unsigned short
16less_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
26static inline inta
27multiply (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
36static inline floata
37gather (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
48static inline inta
49add (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
59struct uintv
60{
61  inta data;
62  inline uintv () { data.v[0] = 0; data.v[1] = 1; }
63  inline uintv (unsigned int a)
64  {
65    for (int i=0; i < 2; i++)
66      *(uint *) &data.v[i] = a;
67  }
68  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
77struct floatv
78{
79  floata data;
80  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  }
86  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
100int
101main ()
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