Hello,

This patch adds support to fold_truth_andor for one-bit precision
typed bitwise-binary and bitwise-not expressions.

ChangeLog

2011-07-13  Kai Tietz  <kti...@redhat.com>

        * fold-const.c (fold_truth_andor): Add
        support for one-bit bitwise operations.

Bootstrapped and regression tested with prior patches of this series
for x86_64-pc-linux-gnu.
Ok for apply?

Regards,
Kai

Index: gcc/gcc/fold-const.c
===================================================================
--- gcc.orig/gcc/fold-const.c   2011-07-13 08:19:22.000000000 +0200
+++ gcc/gcc/fold-const.c        2011-07-13 08:59:14.261620200 +0200
@@ -8248,6 +8248,12 @@ fold_truth_andor (location_t loc, enum t
   if (!optimize)
     return NULL_TREE;

+  /* If code is BIT_AND_EXPR or BIT_IOR_EXPR, type precision has to be
+     one.  Otherwise return NULL_TREE.  */
+  if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
+      && (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1))
+    return NULL_TREE;
+
   /* Check for things like (A || B) && (A || C).  We can convert this
      to A || (B && C).  Note that either operator can be any of the four
      truth and/or operations and the transformation will still be
@@ -8258,7 +8264,9 @@ fold_truth_andor (location_t loc, enum t
       && (TREE_CODE (arg0) == TRUTH_ANDIF_EXPR
          || TREE_CODE (arg0) == TRUTH_ORIF_EXPR
          || TREE_CODE (arg0) == TRUTH_AND_EXPR
-         || TREE_CODE (arg0) == TRUTH_OR_EXPR)
+         || TREE_CODE (arg0) == TRUTH_OR_EXPR
+         || TREE_CODE (arg0) == BIT_AND_EXPR
+         || TREE_CODE (arg0) == BIT_IOR_EXPR)
       && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg0, 1)))
     {
       tree a00 = TREE_OPERAND (arg0, 0);
@@ -8266,9 +8274,13 @@ fold_truth_andor (location_t loc, enum t
       tree a10 = TREE_OPERAND (arg1, 0);
       tree a11 = TREE_OPERAND (arg1, 1);
       int commutative = ((TREE_CODE (arg0) == TRUTH_OR_EXPR
-                         || TREE_CODE (arg0) == TRUTH_AND_EXPR)
+                         || TREE_CODE (arg0) == TRUTH_AND_EXPR
+                         || TREE_CODE (arg0) == BIT_IOR_EXPR
+                         || TREE_CODE (arg0) == BIT_AND_EXPR)
                         && (code == TRUTH_AND_EXPR
-                            || code == TRUTH_OR_EXPR));
+                            || code == TRUTH_OR_EXPR
+                            || code == BIT_AND_EXPR
+                            || code == BIT_IOR_EXPR));

       if (operand_equal_p (a00, a10, 0))
        return fold_build2_loc (loc, TREE_CODE (arg0), type, a00,
@@ -9484,21 +9496,29 @@ fold_binary_loc (location_t loc,

   if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
        || code == EQ_EXPR || code == NE_EXPR)
-      && ((truth_value_p (TREE_CODE (arg0))
-          && (truth_value_p (TREE_CODE (arg1))
+      && ((truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
+          && (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1))
               || (TREE_CODE (arg1) == BIT_AND_EXPR
                   && integer_onep (TREE_OPERAND (arg1, 1)))))
-         || (truth_value_p (TREE_CODE (arg1))
-             && (truth_value_p (TREE_CODE (arg0))
+         || (truth_value_type_p (TREE_CODE (arg1), TREE_TYPE (arg1))
+             && (truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
                  || (TREE_CODE (arg0) == BIT_AND_EXPR
                      && integer_onep (TREE_OPERAND (arg0, 1)))))))
     {
-      tem = fold_build2_loc (loc, code == BIT_AND_EXPR ? TRUTH_AND_EXPR
-                        : code == BIT_IOR_EXPR ? TRUTH_OR_EXPR
-                        : TRUTH_XOR_EXPR,
-                        boolean_type_node,
-                        fold_convert_loc (loc, boolean_type_node, arg0),
-                        fold_convert_loc (loc, boolean_type_node, arg1));
+      enum tree_code ncode;
+
+      /* Do we operate on a non-boolified tree?  */
+      if (!INTEGRAL_TYPE_P (type) || TYPE_PRECISION (type) != 1)
+        ncode = code == BIT_AND_EXPR ? TRUTH_AND_EXPR
+                                    : (code == BIT_IOR_EXPR
+                                       ? TRUTH_OR_EXPR : TRUTH_XOR_EXPR);
+      else
+        ncode = (code == BIT_AND_EXPR || code == BIT_IOR_EXPR) ? code
+                                                              : BIT_XOR_EXPR;
+      tem = fold_build2_loc (loc, ncode,
+                          boolean_type_node,
+                          fold_convert_loc (loc, boolean_type_node, arg0),
+                          fold_convert_loc (loc, boolean_type_node, arg1));

       if (code == EQ_EXPR)
        tem = invert_truthvalue_loc (loc, tem);

Reply via email to