(fold, case BIT_IOR_EXPR): Convert the IOR of a pair of shifts into a
authorRichard Kenner <kenner@gcc.gnu.org>
Mon, 28 Dec 1992 11:07:05 +0000 (06:07 -0500)
committerRichard Kenner <kenner@gcc.gnu.org>
Mon, 28 Dec 1992 11:07:05 +0000 (06:07 -0500)
rotate when it is equivalent.

From-SVN: r2970

gcc/fold-const.c

index f7c2b8a73f19e8768c5c5ad55f1d48146c908a1c..2ff043f98cc67c8dbcb3c79bfce6174b774d0ea8 100644 (file)
@@ -3496,6 +3496,28 @@ fold (expr)
       t1 = distribute_bit_expr (code, type, arg0, arg1);
       if (t1 != NULL_TREE)
        return t1;
+
+      /* (a << C1) | (a >> C2) if A is unsigned and C1+C2 is the size of A
+        is a rotate of A by C1 bits.  */
+
+      if ((TREE_CODE (arg0) == RSHIFT_EXPR
+          || TREE_CODE (arg0) == LSHIFT_EXPR)
+         && (TREE_CODE (arg1) == RSHIFT_EXPR
+             || TREE_CODE (arg1) == LSHIFT_EXPR)
+         && TREE_CODE (arg0) != TREE_CODE (arg1)
+         && operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1,0), 0)
+         && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0)))
+         && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
+         && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
+         && TREE_INT_CST_HIGH (TREE_OPERAND (arg0, 1)) == 0
+         && TREE_INT_CST_HIGH (TREE_OPERAND (arg1, 1)) == 0
+         && ((TREE_INT_CST_LOW (TREE_OPERAND (arg0, 1))
+              + TREE_INT_CST_LOW (TREE_OPERAND (arg1, 1)))
+             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)))))
+       return build (LROTATE_EXPR, type, TREE_OPERAND (arg0, 0),
+                     TREE_CODE (arg0) == LSHIFT_EXPR
+                     ? TREE_OPERAND (arg0, 1) : TREE_OPERAND (arg1, 1));
+
       goto associate;
 
     case BIT_XOR_EXPR: