On Fri, Jun 20, 2014 at 12:41 PM, Thomas Preud'homme <thomas.preudho...@arm.com> wrote: >> From: Richard Biener [mailto:richard.guent...@gmail.com] >> Sent: Tuesday, June 10, 2014 5:05 PM >> >> Backports are welcome - please post a patch. >> > > Sorry for the delay. Here you are: > > diff --git a/gcc/testsuite/gcc.c-torture/execute/pr61375.c > b/gcc/testsuite/gcc.c-torture/execute/pr61375.c > new file mode 100644 > index 0000000..d3b54a8 > --- /dev/null > +++ b/gcc/testsuite/gcc.c-torture/execute/pr61375.c > @@ -0,0 +1,35 @@ > +#ifdef __UINT64_TYPE__ > +typedef __UINT64_TYPE__ uint64_t; > +#else > +typedef unsigned long long uint64_t; > +#endif > + > +#ifndef __SIZEOF_INT128__ > +#define __int128 long long > +#endif > + > +/* Some version of bswap optimization would ICE when analyzing a mask > constant > + too big for an HOST_WIDE_INT (PR61375). */ > + > +__attribute__ ((noinline, noclone)) uint64_t > +uint128_central_bitsi_ior (unsigned __int128 in1, uint64_t in2) > +{ > + __int128 mask = (__int128)0xffff << 56; > + return ((in1 & mask) >> 56) | in2; > +} > + > +int > +main (int argc) > +{ > + __int128 in = 1; > +#ifdef __SIZEOF_INT128__ > + in <<= 64; > +#endif > + if (sizeof (uint64_t) * __CHAR_BIT__ != 64) > + return 0; > + if (sizeof (unsigned __int128) * __CHAR_BIT__ != 128) > + return 0; > + if (uint128_central_bitsi_ior (in, 2) != 0x102) > + __builtin_abort (); > + return 0; > +} > diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c > index 9ff857c..9d64205 100644 > --- a/gcc/tree-ssa-math-opts.c > +++ b/gcc/tree-ssa-math-opts.c > @@ -1741,6 +1741,8 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, > int limit) > if (n->size % BITS_PER_UNIT != 0) > return NULL_TREE; > n->size /= BITS_PER_UNIT; > + if (n->size > (int)sizeof (unsigned HOST_WIDEST_INT)) > + return NULL_TREE; > n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 : > (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201); > > @@ -1781,6 +1783,8 @@ find_bswap_1 (gimple stmt, struct symbolic_number *n, > int limit) > type_size = TYPE_PRECISION (gimple_expr_type (stmt)); > if (type_size % BITS_PER_UNIT != 0) > return NULL_TREE; > + if (type_size > (int)HOST_BITS_PER_WIDEST_INT) > + return NULL_TREE; > > if (type_size / BITS_PER_UNIT < (int)(sizeof (HOST_WIDEST_INT))) > { > > Ok for GCC 4.8 and GCC 4.9 branches?
Ok. Thanks, Richard. > Best regards, > > Thomas > >