On Wed, Jun 18, 2014 at 05:23:13PM +0200, Marek Polacek wrote:
> On Wed, Jun 18, 2014 at 12:55:01PM +0800, Thomas Preud'homme wrote:
> > @@ -1646,20 +1648,23 @@ do_shift_rotate (enum tree_code code,
> >        n->n <<= count;
> >        break;
> >      case RSHIFT_EXPR:
> > +      /* Arithmetic shift of signed type: result is dependent on the 
> > value.  */
> > +      if (!TYPE_UNSIGNED (n->type) && (n->n & (0xff << (bitsize - 8))))
> > +   return false;
> 
> Looks like here an undefined behavior happens:
> tree-ssa-math-opts.c:1672:53: runtime error: shift exponent 56 is too
> large for 32-bit type 'int'

Seems there are actually two spots with this, not just one.

Completely untested fix:

2014-06-18  Jakub Jelinek  <ja...@redhat.com>

        * tree-ssa-math-opts.c (do_shift_rotate, find_bswap_or_nop_1): Cast
        0xff to uint64_t before shifting it up.

--- gcc/tree-ssa-math-opts.c    2014-06-13 08:08:42.354136356 +0200
+++ gcc/tree-ssa-math-opts.c    2014-06-18 19:50:59.486916201 +0200
@@ -1669,7 +1669,8 @@ do_shift_rotate (enum tree_code code,
       break;
     case RSHIFT_EXPR:
       /* Arithmetic shift of signed type: result is dependent on the value.  */
-      if (!TYPE_UNSIGNED (n->type) && (n->n & (0xff << (bitsize - 8))))
+      if (!TYPE_UNSIGNED (n->type)
+         && (n->n & ((uint64_t) 0xff << (bitsize - 8))))
        return false;
       n->n >>= count;
       break;
@@ -1903,7 +1904,7 @@ find_bswap_or_nop_1 (gimple stmt, struct
            old_type_size = TYPE_PRECISION (n->type);
            if (!TYPE_UNSIGNED (n->type)
                && type_size > old_type_size
-               && n->n & (0xff << (old_type_size - 8)))
+               && n->n & ((uint64_t) 0xff << (old_type_size - 8)))
              return NULL_TREE;
 
            if (type_size / BITS_PER_UNIT < (int)(sizeof (int64_t)))


        Jakub

Reply via email to