diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/torture/pr40924.C | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/torture/pr40924.C')
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr40924.C | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/torture/pr40924.C b/gcc/testsuite/g++.dg/torture/pr40924.C new file mode 100644 index 000000000..9140da3ba --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr40924.C @@ -0,0 +1,111 @@ +// PR rtl-optimization/40924 +// { dg-do run } + +extern "C" void abort (void); + +#define MAY_ALIAS __attribute__((__may_alias__)) + +typedef struct { float v[2]; } floata; +typedef struct { int v[2]; } inta; + +typedef unsigned int uint MAY_ALIAS; +typedef signed int sint MAY_ALIAS; +typedef float flt MAY_ALIAS; + +static inline unsigned short +less_than (inta a, inta b) +{ + unsigned short r = 0; + const uint *p1 = (const uint *) &a; + const uint *p2 = (const uint *) &b; + for (int i=0; i < 2; i++) + if (p1[i] < p2[i]) r |= (1 << i); + return r; +} + +static inline inta +multiply (inta b, inta c) +{ + inta r; + sint *p3 = (sint *) &c; + for (int i=0; i < 2; i++) + r.v[i] = (int) (b.v[i] * p3[i] & 0xFFFFFFFF); + return r; +} + +static inline floata +gather (inta indexes, const void *baseAddr) +{ + floata r; + + sint *idx = (sint *) &indexes; + flt *src = (flt *) baseAddr; + for (int i=0; i < 2; i++) + r.v[i] = *(src + idx[i]); + return r; +} + +static inline inta +add (const inta &b, const inta &c) +{ + inta result; + sint *r = (sint *) &result; + + for (int i=0; i < 2; i++) + r[i] = b.v[i] + c.v[i]; + return result; +} + +struct uintv +{ + inta data; + inline uintv () { data.v[0] = 0; data.v[1] = 1; } + inline uintv (unsigned int a) + { + for (int i=0; i < 2; i++) + *(uint *) &data.v[i] = a; + } + inline uintv (inta x) : data (x) {} + inline uintv operator* (const uintv &x) const + { return multiply (data, x.data); } + inline uintv operator+ (const uintv &x) const + { return uintv (add (data, x.data)); } + inline unsigned short operator< (const uintv &x) const + { return less_than (data, x.data); } +}; + +struct floatv +{ + floata data; + explicit inline floatv (const uintv &x) + { + uint *p2 = (uint *) &x.data; + for (int i=0; i < 2; i++) + data.v[i] = p2[i]; + } + inline floatv (const float *array, const uintv &indexes) + { + const uintv &offsets = indexes * uintv (1); + data = gather (offsets.data, array); + } + unsigned short operator== (const floatv &x) const + { + unsigned short r = 0; + for (int i=0; i < 2; i++) + if (data.v[i] == x.data.v[i]) r |= (1 << i); + return r; + } +}; + +int +main () +{ + const float array[2] = { 2, 3 }; + for (uintv i; (i < 2) == 3; i = i + 2) + { + const floatv ii (i + 2); + floatv a (array, i); + if ((a == ii) != 3) + abort (); + } +} |