On Thu, 9 May 2013, Jakub Jelinek wrote:

> Hi!
> 
> The bit_rotate: code in fold-const.c handles only a subset of rotates,
> and e.g. with C++ FE when sizeof isn't folded early fold_binary often
> even isn't called with something that could recognize the rotate pattern,
> even if bit_rotate: has been extended.  Furthermore, not all the rotate
> patterns need to be written in a single statement.
> 
> So, this patch adds a rotate pattern recognizer into forwprop, and handles
> several different patterns, the comment above the function shows which ones.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux.
> 
> On the Botan KASUMI distilled testcase (PR55278 #c6 at -O3) I get 6.3%
> speedup on Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz and 9.9% speedup on
> Quad-Core AMD Opteron(tm) Processor 8354.
> 
> Ok for trunk?
Ok.

Thanks,
Richard.

> 2013-05-09  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/45216
>       PR tree-optimization/57157
>       * tree-ssa-forwprop.c (simplify_rotate): New function.
>       (ssa_forward_propagate_and_combine): Call it.
> 
>       * c-c++-common/rotate-1.c: New test.
>       * c-c++-common/rotate-1a.c: New test.
>       * c-c++-common/rotate-2.c: New test.
>       * c-c++-common/rotate-2a.c: New test.
>       * c-c++-common/rotate-3.c: New test.
>       * c-c++-common/rotate-3a.c: New test.
>       * c-c++-common/rotate-4.c: New test.
>       * c-c++-common/rotate-4a.c: New test.
>       * gcc.target/i386/rotate-1.c: Accept rolb or rorb instruction.
> 
> --- gcc/tree-ssa-forwprop.c.jj        2013-04-22 08:06:41.000000000 +0200
> +++ gcc/tree-ssa-forwprop.c   2013-05-09 15:31:49.350000512 +0200
> @@ -2124,6 +2124,242 @@ simplify_bitwise_binary (gimple_stmt_ite
>  }
>  
>  
> +/* Recognize rotation patterns.  Return true if a transformation
> +   applied, otherwise return false.
> +
> +   We are looking for X with unsigned type T with bitsize B, OP being
> +   +, | or ^, some type T2 wider than T and
> +   (X << CNT1) OP (X >> CNT2)                                iff CNT1 + CNT2 
> == B
> +   ((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2))  iff CNT1 + CNT2 == B
> +   (X << Y) OP (X >> (B - Y))
> +   (X << (int) Y) OP (X >> (int) (B - Y))
> +   ((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
> +   ((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y)))
> +   (X << Y) OP (X >> ((-Y) & (B - 1)))
> +   (X << (int) Y) OP (X >> (int) ((-Y) & (B - 1)))
> +   ((T) ((T2) X << Y)) OP ((T) ((T2) X >> ((-Y) & (B - 1))))
> +   ((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
> +
> +   and transform these into:
> +   X r<< CNT1
> +   X r<< Y
> +
> +   Note, in the patterns with T2 type, the type of OP operands
> +   might be even a signed type, but should have precision B.  */
> +
> +static bool
> +simplify_rotate (gimple_stmt_iterator *gsi)
> +{
> +  gimple stmt = gsi_stmt (*gsi);
> +  tree arg[2], rtype, rotcnt = NULL_TREE;
> +  tree def_arg1[2], def_arg2[2];
> +  enum tree_code def_code[2];
> +  tree lhs;
> +  int i;
> +  bool swapped_p = false;
> +  gimple g;
> +
> +  arg[0] = gimple_assign_rhs1 (stmt);
> +  arg[1] = gimple_assign_rhs2 (stmt);
> +  rtype = TREE_TYPE (arg[0]);
> +
> +  /* Only create rotates in complete modes.  Other cases are not
> +     expanded properly.  */
> +  if (!INTEGRAL_TYPE_P (rtype)
> +      || TYPE_PRECISION (rtype) != GET_MODE_PRECISION (TYPE_MODE (rtype)))
> +    return false;
> +
> +  for (i = 0; i < 2; i++)
> +    defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
> +
> +  /* Look through narrowing conversions.  */
> +  if (CONVERT_EXPR_CODE_P (def_code[0])
> +      && CONVERT_EXPR_CODE_P (def_code[1])
> +      && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[0]))
> +      && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[1]))
> +      && TYPE_PRECISION (TREE_TYPE (def_arg1[0]))
> +      == TYPE_PRECISION (TREE_TYPE (def_arg1[1]))
> +      && TYPE_PRECISION (TREE_TYPE (def_arg1[0])) > TYPE_PRECISION (rtype)
> +      && has_single_use (arg[0])
> +      && has_single_use (arg[1]))
> +    {
> +      for (i = 0; i < 2; i++)
> +     {
> +       arg[i] = def_arg1[i];
> +       defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
> +     }
> +    }
> +
> +  /* One operand has to be LSHIFT_EXPR and one RSHIFT_EXPR.  */
> +  for (i = 0; i < 2; i++)
> +    if (def_code[i] != LSHIFT_EXPR && def_code[i] != RSHIFT_EXPR)
> +      return false;
> +    else if (!has_single_use (arg[i]))
> +      return false;
> +  if (def_code[0] == def_code[1])
> +    return false;
> +
> +  /* If we've looked through narrowing conversions before, look through
> +     widening conversions from unsigned type with the same precision
> +     as rtype here.  */
> +  if (TYPE_PRECISION (TREE_TYPE (def_arg1[0])) != TYPE_PRECISION (rtype))
> +    for (i = 0; i < 2; i++)
> +      {
> +     tree tem;
> +     enum tree_code code;
> +     defcodefor_name (def_arg1[i], &code, &tem, NULL);
> +     if (!CONVERT_EXPR_CODE_P (code)
> +         || !INTEGRAL_TYPE_P (TREE_TYPE (tem))
> +         || TYPE_PRECISION (TREE_TYPE (tem)) != TYPE_PRECISION (rtype))
> +       return false;
> +     def_arg1[i] = tem;
> +      }
> +  /* Both shifts have to use the same first operand.  */
> +  if (TREE_CODE (def_arg1[0]) != SSA_NAME || def_arg1[0] != def_arg1[1])
> +    return false;
> +  if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0])))
> +    return false;
> +
> +  /* CNT1 + CNT2 == B case above.  */
> +  if (host_integerp (def_arg2[0], 1)
> +      && host_integerp (def_arg2[1], 1)
> +      && (unsigned HOST_WIDE_INT) tree_low_cst (def_arg2[0], 1)
> +      + tree_low_cst (def_arg2[1], 1) == TYPE_PRECISION (rtype))
> +    rotcnt = def_arg2[0];
> +  else if (TREE_CODE (def_arg2[0]) != SSA_NAME
> +        || TREE_CODE (def_arg2[1]) != SSA_NAME)
> +    return false;
> +  else
> +    {
> +      tree cdef_arg1[2], cdef_arg2[2], def_arg2_alt[2];
> +      enum tree_code cdef_code[2];
> +      /* Look through conversion of the shift count argument.
> +      The C/C++ FE cast any shift count argument to integer_type_node.
> +      The only problem might be if the shift count type maximum value
> +      is equal or smaller than number of bits in rtype.  */
> +      for (i = 0; i < 2; i++)
> +     {
> +       def_arg2_alt[i] = def_arg2[i];
> +       defcodefor_name (def_arg2[i], &cdef_code[i],
> +                        &cdef_arg1[i], &cdef_arg2[i]);
> +       if (CONVERT_EXPR_CODE_P (cdef_code[i])
> +           && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
> +           && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
> +              > floor_log2 (TYPE_PRECISION (rtype))
> +           && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
> +              == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (cdef_arg1[i]))))
> +         {
> +           def_arg2_alt[i] = cdef_arg1[i];
> +           defcodefor_name (def_arg2_alt[i], &cdef_code[i],
> +                            &cdef_arg1[i], &cdef_arg2[i]);
> +         }
> +     }
> +      for (i = 0; i < 2; i++)
> +     /* Check for one shift count being Y and the other B - Y,
> +        with optional casts.  */
> +     if (cdef_code[i] == MINUS_EXPR
> +         && host_integerp (cdef_arg1[i], 0)
> +         && tree_low_cst (cdef_arg1[i], 0) == TYPE_PRECISION (rtype)
> +         && TREE_CODE (cdef_arg2[i]) == SSA_NAME)
> +       {
> +         tree tem;
> +         enum tree_code code;
> +
> +         if (cdef_arg2[i] == def_arg2[1 - i]
> +             || cdef_arg2[i] == def_arg2_alt[1 - i])
> +           {
> +             rotcnt = cdef_arg2[i];
> +             break;
> +           }
> +         defcodefor_name (cdef_arg2[i], &code, &tem, NULL);
> +         if (CONVERT_EXPR_CODE_P (code)
> +             && INTEGRAL_TYPE_P (TREE_TYPE (tem))
> +             && TYPE_PRECISION (TREE_TYPE (tem))
> +              > floor_log2 (TYPE_PRECISION (rtype))
> +             && TYPE_PRECISION (TREE_TYPE (tem))
> +              == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
> +             && (tem == def_arg2[1 - i]
> +                 || tem == def_arg2_alt[1 - i]))
> +           {
> +             rotcnt = tem;
> +             break;
> +           }
> +       }
> +     /* The above sequence isn't safe for Y being 0,
> +        because then one of the shifts triggers undefined behavior.
> +        This alternative is safe even for rotation count of 0.
> +        One shift count is Y and the other (-Y) & (B - 1).  */
> +     else if (cdef_code[i] == BIT_AND_EXPR
> +              && host_integerp (cdef_arg2[i], 0)
> +              && tree_low_cst (cdef_arg2[i], 0)
> +                 == TYPE_PRECISION (rtype) - 1
> +              && TREE_CODE (cdef_arg1[i]) == SSA_NAME)
> +       {
> +         tree tem;
> +         enum tree_code code;
> +
> +         defcodefor_name (cdef_arg1[i], &code, &tem, NULL);
> +         if (CONVERT_EXPR_CODE_P (code)
> +             && INTEGRAL_TYPE_P (TREE_TYPE (tem))
> +             && TYPE_PRECISION (TREE_TYPE (tem))
> +              > floor_log2 (TYPE_PRECISION (rtype))
> +             && TYPE_PRECISION (TREE_TYPE (tem))
> +              == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem))))
> +           defcodefor_name (tem, &code, &tem, NULL);
> +
> +         if (code == NEGATE_EXPR)
> +           {
> +             if (tem == def_arg2[1 - i] || tem == def_arg2_alt[1 - i])
> +               {
> +                 rotcnt = tem;
> +                 break;
> +               }
> +             defcodefor_name (tem, &code, &tem, NULL);
> +             if (CONVERT_EXPR_CODE_P (code)
> +                 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
> +                 && TYPE_PRECISION (TREE_TYPE (tem))
> +                    > floor_log2 (TYPE_PRECISION (rtype))
> +                 && TYPE_PRECISION (TREE_TYPE (tem))
> +                    == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
> +                 && (tem == def_arg2[1 - i]
> +                     || tem == def_arg2_alt[1 - i]))
> +               {
> +                 rotcnt = tem;
> +                 break;
> +               }
> +           }
> +       }
> +      if (rotcnt == NULL_TREE)
> +     return false;
> +      swapped_p = i != 1;
> +    }
> +
> +  if (!useless_type_conversion_p (TREE_TYPE (def_arg2[0]),
> +                               TREE_TYPE (rotcnt)))
> +    {
> +      g = gimple_build_assign_with_ops (NOP_EXPR,
> +                                     make_ssa_name (TREE_TYPE (def_arg2[0]),
> +                                                    NULL),
> +                                     rotcnt, NULL_TREE);
> +      gsi_insert_before (gsi, g, GSI_SAME_STMT);
> +      rotcnt = gimple_assign_lhs (g);
> +    }
> +  lhs = gimple_assign_lhs (stmt);
> +  if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
> +    lhs = make_ssa_name (TREE_TYPE (def_arg1[0]), NULL);
> +  g = gimple_build_assign_with_ops (((def_code[0] == LSHIFT_EXPR) ^ 
> swapped_p)
> +                                 ? LROTATE_EXPR : RROTATE_EXPR,
> +                                 lhs, def_arg1[0], rotcnt);
> +  if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
> +    {
> +      gsi_insert_before (gsi, g, GSI_SAME_STMT);
> +      g = gimple_build_assign_with_ops (NOP_EXPR, gimple_assign_lhs (stmt),
> +                                     lhs, NULL_TREE);
> +    }
> +  gsi_replace (gsi, g, false);
> +  return true;
> +}
> +
>  /* Perform re-associations of the plus or minus statement STMT that are
>     always permitted.  Returns true if the CFG was changed.  */
>  
> @@ -3114,6 +3350,11 @@ ssa_forward_propagate_and_combine (void)
>                     cfg_changed = true;
>                   changed = did_something != 0;
>                 }
> +             else if ((code == PLUS_EXPR
> +                       || code == BIT_IOR_EXPR
> +                       || code == BIT_XOR_EXPR)
> +                      && simplify_rotate (&gsi))
> +               changed = true;
>               else if (code == BIT_AND_EXPR
>                        || code == BIT_IOR_EXPR
>                        || code == BIT_XOR_EXPR)
> --- gcc/testsuite/c-c++-common/rotate-1.c.jj  2013-05-09 14:56:53.653727175 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-1.c     2013-05-09 15:16:02.768309163 
> +0200
> @@ -0,0 +1,389 @@
> +/* Check rotate pattern detection.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> +
> +unsigned int
> +f1 (unsigned int x, unsigned int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f2 (unsigned int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f3 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned int
> +f4 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x >> 1);
> +}
> +
> +unsigned short int
> +f5 (unsigned short int x, unsigned int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned short int
> +f6 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned char
> +f7 (unsigned char x, unsigned int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ - y));
> +}
> +
> +unsigned char
> +f8 (unsigned char x, unsigned long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ - y));
> +}
> +
> +unsigned int
> +f9 (unsigned int x, unsigned int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f10 (unsigned int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f11 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned int
> +f12 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x >> 1);
> +}
> +
> +unsigned short int
> +f13 (unsigned short int x, unsigned int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned short int
> +f14 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned char
> +f15 (unsigned char x, unsigned int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned char
> +f16 (unsigned char x, unsigned long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned int
> +f17 (unsigned int x, unsigned int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f18 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f19 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x << 1);
> +}
> +
> +unsigned int
> +f20 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned short int
> +f21 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
> +}
> +
> +unsigned short int
> +f22 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f23 (unsigned char x, unsigned int y)
> +{
> +  return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f24 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f25 (unsigned int x, unsigned int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f26 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f27 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x << 1);
> +}
> +
> +unsigned int
> +f28 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned short int
> +f29 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
> +}
> +
> +unsigned short int
> +f30 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f31 (unsigned char x, unsigned int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f32 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f33 (unsigned int x, unsigned int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f34 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f35 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned int
> +f36 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x << 1);
> +}
> +
> +unsigned short int
> +f37 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned short int
> +f38 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned char
> +f39 (unsigned char x, unsigned int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ - y));
> +}
> +
> +unsigned char
> +f40 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ - y));
> +}
> +
> +unsigned int
> +f41 (unsigned int x, unsigned int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f42 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f43 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned int
> +f44 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x << 1);
> +}
> +
> +unsigned short int
> +f45 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned short int
> +f46 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned char
> +f47 (unsigned char x, unsigned int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned char
> +f48 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned int
> +f49 (unsigned int x, unsigned int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f50 (unsigned int x, unsigned long int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f51 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x >> 1);
> +}
> +
> +unsigned int
> +f52 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned short int
> +f53 (unsigned short int x, unsigned int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned short int
> +f54 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f55 (unsigned char x, unsigned int y)
> +{
> +  return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f56 (unsigned char x, unsigned long int y)
> +{
> +  return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f57 (unsigned int x, unsigned int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f58 (unsigned int x, unsigned long int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f59 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x >> 1);
> +}
> +
> +unsigned int
> +f60 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned short int
> +f61 (unsigned short int x, unsigned int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
> +}
> +
> +unsigned short int
> +f62 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f63 (unsigned char x, unsigned int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f64 (unsigned char x, unsigned long int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
> +}
> --- gcc/testsuite/c-c++-common/rotate-1a.c.jj 2013-05-09 15:19:28.179164195 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-1a.c    2013-05-09 15:24:56.786327208 
> +0200
> @@ -0,0 +1,44 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -Wno-overflow" } */
> +
> +extern
> +#ifdef __cplusplus
> +"C"
> +#endif
> +void abort (void);
> +
> +#ifndef ROTATE_N
> +#define ROTATE_N "rotate-1.c"
> +#endif
> +
> +#include ROTATE_N
> +
> +unsigned int expected[] = {
> +0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
> +0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
> +0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
> +0x91a2b3c0, 0x91a2b3c0, 0x2468acf0, 0x91a2b3c, 0xb3c2, 0xb3c2, 0xc3, 0xc3,
> +0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf,
> +0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf,
> +0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf,
> +0x2468acf, 0x2468acf, 0x91a2b3c, 0x2468acf0, 0xacf, 0xacf, 0xf, 0xf };
> +
> +#define F(n) __typeof (f##n) f##n __attribute__((noinline, noclone));
> +#define D(n) F(n##0) F(n##1) F(n##2) F(n##3) F(n##4) F(n##5) F(n##6) F(n##7) 
> F(n##8) F(n##9)
> +#define ALL \
> +F(1) F(2) F(3) F(4) F(5) F(6) F(7) F(8) F(9) \
> +D(1) D(2) D(3) D(4) D(5) F(60) F(61) F(62) F(63) F(64)
> +ALL
> +
> +int
> +main ()
> +{
> +#if __CHAR_BIT__ != 8 || __SIZEOF_SHORT__ != 2 || __SIZEOF_INT__ != 4
> +  return 0;
> +#else
> +#undef F
> +#define F(n) if ((unsigned int) f##n (0x12345678U, 3) != expected[n - 1]) 
> abort ();
> +  ALL
> +  return 0;
> +#endif
> +}
> --- gcc/testsuite/c-c++-common/rotate-2.c.jj  2013-05-09 14:56:56.929709134 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-2.c     2013-05-09 15:16:10.429264887 
> +0200
> @@ -0,0 +1,389 @@
> +/* Check rotate pattern detection.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> +
> +unsigned int
> +f1 (unsigned int x, unsigned int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f2 (unsigned int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f3 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f4 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> 1);
> +}
> +
> +unsigned short int
> +f5 (unsigned short int x, unsigned int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned short int
> +f6 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned char
> +f7 (unsigned char x, unsigned int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned char
> +f8 (unsigned char x, unsigned long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned int
> +f9 (unsigned int x, unsigned int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f10 (unsigned int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f11 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f12 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> 
> 1);
> +}
> +
> +unsigned short int
> +f13 (unsigned short int x, unsigned int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned short int
> +f14 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned char
> +f15 (unsigned char x, unsigned int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned char
> +f16 (unsigned char x, unsigned long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned int
> +f17 (unsigned int x, unsigned int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned int
> +f18 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned int
> +f19 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << 1);
> +}
> +
> +unsigned int
> +f20 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned short int
> +f21 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned short int
> +f22 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned char
> +f23 (unsigned char x, unsigned int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned char
> +f24 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned int
> +f25 (unsigned int x, unsigned int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned int
> +f26 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned int
> +f27 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 
> 1);
> +}
> +
> +unsigned int
> +f28 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned short int
> +f29 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> << y);
> +}
> +
> +unsigned short int
> +f30 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> << y);
> +}
> +
> +unsigned char
> +f31 (unsigned char x, unsigned int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned char
> +f32 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned int
> +f33 (unsigned int x, unsigned int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f34 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f35 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f36 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << 1);
> +}
> +
> +unsigned short int
> +f37 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned short int
> +f38 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned char
> +f39 (unsigned char x, unsigned int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned char
> +f40 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned int
> +f41 (unsigned int x, unsigned int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f42 (unsigned int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f43 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f44 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << 
> 1);
> +}
> +
> +unsigned short int
> +f45 (unsigned short int x, unsigned int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned short int
> +f46 (unsigned short int x, unsigned long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned char
> +f47 (unsigned char x, unsigned int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned char
> +f48 (unsigned char x, unsigned long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned int
> +f49 (unsigned int x, unsigned int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned int
> +f50 (unsigned int x, unsigned long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned int
> +f51 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> 1);
> +}
> +
> +unsigned int
> +f52 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned short int
> +f53 (unsigned short int x, unsigned int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned short int
> +f54 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned char
> +f55 (unsigned char x, unsigned int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned char
> +f56 (unsigned char x, unsigned long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned int
> +f57 (unsigned int x, unsigned int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 
> y);
> +}
> +
> +unsigned int
> +f58 (unsigned int x, unsigned long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 
> y);
> +}
> +
> +unsigned int
> +f59 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 
> 1);
> +}
> +
> +unsigned int
> +f60 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned short int
> +f61 (unsigned short int x, unsigned int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> >> y);
> +}
> +
> +unsigned short int
> +f62 (unsigned short int x, unsigned long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> >> y);
> +}
> +
> +unsigned char
> +f63 (unsigned char x, unsigned int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> 
> y);
> +}
> +
> +unsigned char
> +f64 (unsigned char x, unsigned long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> 
> y);
> +}
> --- gcc/testsuite/c-c++-common/rotate-2a.c.jj 2013-05-09 15:19:31.617145493 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-2a.c    2013-05-09 15:23:06.388944450 
> +0200
> @@ -0,0 +1,6 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -Wno-overflow" } */
> +
> +#define ROTATE_N "rotate-2.c"
> +
> +#include "rotate-1a.c"
> --- gcc/testsuite/c-c++-common/rotate-3.c.jj  2013-05-09 15:01:15.894264414 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-3.c     2013-05-09 15:16:16.994225808 
> +0200
> @@ -0,0 +1,389 @@
> +/* Check rotate pattern detection.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> +
> +unsigned int
> +f1 (unsigned int x, int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f2 (unsigned int x, long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f3 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned int
> +f4 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x >> 1);
> +}
> +
> +unsigned short int
> +f5 (unsigned short int x, int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned short int
> +f6 (unsigned short int x, long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned char
> +f7 (unsigned char x, int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ - y));
> +}
> +
> +unsigned char
> +f8 (unsigned char x, long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ - y));
> +}
> +
> +unsigned int
> +f9 (unsigned int x, int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f10 (unsigned int x, long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f11 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned int
> +f12 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x >> 1);
> +}
> +
> +unsigned short int
> +f13 (unsigned short int x, int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned short int
> +f14 (unsigned short int x, long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned char
> +f15 (unsigned char x, int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned char
> +f16 (unsigned char x, long int y)
> +{
> +  return (x << y) | (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned int
> +f17 (unsigned int x, int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f18 (unsigned int x, long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f19 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x << 1);
> +}
> +
> +unsigned int
> +f20 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned short int
> +f21 (unsigned short int x, int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
> +}
> +
> +unsigned short int
> +f22 (unsigned short int x, long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f23 (unsigned char x, int y)
> +{
> +  return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f24 (unsigned char x, long int y)
> +{
> +  return (x >> (__CHAR_BIT__ - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f25 (unsigned int x, int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f26 (unsigned int x, long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f27 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x << 1);
> +}
> +
> +unsigned int
> +f28 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned short int
> +f29 (unsigned short int x, int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
> +}
> +
> +unsigned short int
> +f30 (unsigned short int x, long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f31 (unsigned char x, int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
> +}
> +
> +unsigned char
> +f32 (unsigned char x, long int y)
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x << y);
> +}
> +
> +unsigned int
> +f33 (unsigned int x, int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f34 (unsigned int x, long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y));
> +}
> +
> +unsigned int
> +f35 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned int
> +f36 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) | (x << 1);
> +}
> +
> +unsigned short int
> +f37 (unsigned short int x, int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned short int
> +f38 (unsigned short int x, long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y));
> +}
> +
> +unsigned char
> +f39 (unsigned char x, int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ - y));
> +}
> +
> +unsigned char
> +f40 (unsigned char x, long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ - y));
> +}
> +
> +unsigned int
> +f41 (unsigned int x, int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f42 (unsigned int x, long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - y));
> +}
> +
> +unsigned int
> +f43 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned int
> +f44 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1)) | (x << 1);
> +}
> +
> +unsigned short int
> +f45 (unsigned short int x, int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned short int
> +f46 (unsigned short int x, long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned short) - y));
> +}
> +
> +unsigned char
> +f47 (unsigned char x, int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned char
> +f48 (unsigned char x, long int y)
> +{
> +  return (x >> y) | (x << (__CHAR_BIT__ * sizeof (unsigned char) - y));
> +}
> +
> +unsigned int
> +f49 (unsigned int x, int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f50 (unsigned int x, long int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f51 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_INT__ - 1)) ^ (x >> 1);
> +}
> +
> +unsigned int
> +f52 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> (__CHAR_BIT__ * __SIZEOF_INT__ - 1));
> +}
> +
> +unsigned short int
> +f53 (unsigned short int x, int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned short int
> +f54 (unsigned short int x, long int y)
> +{
> +  return (x << (__CHAR_BIT__ * __SIZEOF_SHORT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f55 (unsigned char x, int y)
> +{
> +  return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f56 (unsigned char x, long int y)
> +{
> +  return (x << (__CHAR_BIT__ - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f57 (unsigned int x, int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f58 (unsigned int x, long int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - y)) ^ (x >> y);
> +}
> +
> +unsigned int
> +f59 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned int) - 1)) ^ (x >> 1);
> +}
> +
> +unsigned int
> +f60 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> (__CHAR_BIT__ * sizeof (unsigned int) - 1));
> +}
> +
> +unsigned short int
> +f61 (unsigned short int x, int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
> +}
> +
> +unsigned short int
> +f62 (unsigned short int x, long int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned short) - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f63 (unsigned char x, int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
> +}
> +
> +unsigned char
> +f64 (unsigned char x, long int y)
> +{
> +  return (x << (__CHAR_BIT__ * sizeof (unsigned char) - y)) ^ (x >> y);
> +}
> --- gcc/testsuite/c-c++-common/rotate-3a.c.jj 2013-05-09 15:23:20.079868427 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-3a.c    2013-05-09 15:23:31.910802207 
> +0200
> @@ -0,0 +1,6 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -Wno-overflow" } */
> +
> +#define ROTATE_N "rotate-4.c"
> +
> +#include "rotate-1a.c"
> --- gcc/testsuite/c-c++-common/rotate-4.c.jj  2013-05-09 15:01:40.210126009 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-4.c     2013-05-09 15:16:24.026187297 
> +0200
> @@ -0,0 +1,389 @@
> +/* Check rotate pattern detection.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized" } */
> +/* { dg-final { scan-tree-dump-times "r\[<>]\[<>]" 64 "optimized" } } */
> +/* { dg-final { cleanup-tree-dump "optimized" } } */
> +
> +unsigned int
> +f1 (unsigned int x, int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f2 (unsigned int x, long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f3 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f4 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x >> 1);
> +}
> +
> +unsigned short int
> +f5 (unsigned short int x, int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned short int
> +f6 (unsigned short int x, long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned char
> +f7 (unsigned char x, int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned char
> +f8 (unsigned char x, long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned int
> +f9 (unsigned int x, int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f10 (unsigned int x, long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f11 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) | (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f12 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x >> 
> 1);
> +}
> +
> +unsigned short int
> +f13 (unsigned short int x, int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned short int
> +f14 (unsigned short int x, long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned char
> +f15 (unsigned char x, int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned char
> +f16 (unsigned char x, long int y)
> +{
> +  return (x << y) | (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned int
> +f17 (unsigned int x, int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned int
> +f18 (unsigned int x, long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned int
> +f19 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x << 1);
> +}
> +
> +unsigned int
> +f20 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned short int
> +f21 (unsigned short int x, int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned short int
> +f22 (unsigned short int x, long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned char
> +f23 (unsigned char x, int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned char
> +f24 (unsigned char x, long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ - 1))) ^ (x << y);
> +}
> +
> +unsigned int
> +f25 (unsigned int x, int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned int
> +f26 (unsigned int x, long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned int
> +f27 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x << 
> 1);
> +}
> +
> +unsigned int
> +f28 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) ^ (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned short int
> +f29 (unsigned short int x, int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> << y);
> +}
> +
> +unsigned short int
> +f30 (unsigned short int x, long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> << y);
> +}
> +
> +unsigned char
> +f31 (unsigned char x, int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned char
> +f32 (unsigned char x, long int y)
> +{
> +  return (x >> ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x << 
> y);
> +}
> +
> +unsigned int
> +f33 (unsigned int x, int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f34 (unsigned int x, long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f35 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned int
> +f36 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) | (x << 1);
> +}
> +
> +unsigned short int
> +f37 (unsigned short int x, int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned short int
> +f38 (unsigned short int x, long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1)));
> +}
> +
> +unsigned char
> +f39 (unsigned char x, int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned char
> +f40 (unsigned char x, long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ - 1)));
> +}
> +
> +unsigned int
> +f41 (unsigned int x, int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f42 (unsigned int x, long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f43 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> 1) | (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned int
> +f44 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) | (x << 
> 1);
> +}
> +
> +unsigned short int
> +f45 (unsigned short int x, int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned short int
> +f46 (unsigned short int x, long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 
> 1)));
> +}
> +
> +unsigned char
> +f47 (unsigned char x, int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned char
> +f48 (unsigned char x, long int y)
> +{
> +  return (x >> y) | (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 
> 1)));
> +}
> +
> +unsigned int
> +f49 (unsigned int x, int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned int
> +f50 (unsigned int x, long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned int
> +f51 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1))) ^ (x >> 1);
> +}
> +
> +unsigned int
> +f52 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * __SIZEOF_INT__ - 1)));
> +}
> +
> +unsigned short int
> +f53 (unsigned short int x, int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned short int
> +f54 (unsigned short int x, long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * __SIZEOF_SHORT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned char
> +f55 (unsigned char x, int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned char
> +f56 (unsigned char x, long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ - 1))) ^ (x >> y);
> +}
> +
> +unsigned int
> +f57 (unsigned int x, int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 
> y);
> +}
> +
> +unsigned int
> +f58 (unsigned int x, long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 
> y);
> +}
> +
> +unsigned int
> +f59 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 1))) ^ (x >> 
> 1);
> +}
> +
> +unsigned int
> +f60 (unsigned int x, int y __attribute__((unused)))
> +{
> +  return (x << 1) ^ (x >> ((-1) & (__CHAR_BIT__ * sizeof (unsigned int) - 
> 1)));
> +}
> +
> +unsigned short int
> +f61 (unsigned short int x, int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> >> y);
> +}
> +
> +unsigned short int
> +f62 (unsigned short int x, long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned short) - 1))) ^ (x 
> >> y);
> +}
> +
> +unsigned char
> +f63 (unsigned char x, int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> 
> y);
> +}
> +
> +unsigned char
> +f64 (unsigned char x, long int y)
> +{
> +  return (x << ((-y) & (__CHAR_BIT__ * sizeof (unsigned char) - 1))) ^ (x >> 
> y);
> +}
> --- gcc/testsuite/c-c++-common/rotate-4a.c.jj 2013-05-09 15:23:20.079868427 
> +0200
> +++ gcc/testsuite/c-c++-common/rotate-4a.c    2013-05-09 15:23:24.775841083 
> +0200
> @@ -0,0 +1,6 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2 -Wno-overflow" } */
> +
> +#define ROTATE_N "rotate-4.c"
> +
> +#include "rotate-1a.c"
> --- gcc/testsuite/gcc.target/i386/rotate-1.c.jj       2008-09-05 
> 12:54:23.000000000 +0200
> +++ gcc/testsuite/gcc.target/i386/rotate-1.c  2013-05-09 20:32:42.038756873 
> +0200
> @@ -13,4 +13,4 @@ main (void)
>    return c;
>  }
>  
> -/* { dg-final { scan-assembler "rolb" } } */
> +/* { dg-final { scan-assembler "ro\[lr]b" } } */
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

Reply via email to