2018-11-07 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / g++.dg / torture / pr40924.C
blob9140da3ba3bc72765ad83302a77c79cbe0149104
1 // PR rtl-optimization/40924
2 // { dg-do run }
4 extern "C" void abort (void);
6 #define MAY_ALIAS __attribute__((__may_alias__))
8 typedef struct { float v[2]; } floata;
9 typedef struct { int v[2]; } inta;
11 typedef unsigned int uint MAY_ALIAS;
12 typedef signed int sint MAY_ALIAS;
13 typedef float flt MAY_ALIAS;
15 static inline unsigned short
16 less_than (inta a, inta b)
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;
26 static inline inta
27 multiply (inta b, inta c)
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;
36 static inline floata
37 gather (inta indexes, const void *baseAddr)
39   floata r;
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;
48 static inline inta
49 add (const inta &b, const inta &c)
51   inta result;
52   sint *r = (sint *) &result;
54   for (int i=0; i < 2; i++)
55     r[i] = b.v[i] + c.v[i];
56   return result;
59 struct uintv
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); }
77 struct floatv
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   }
101 main ()
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     }