Hello,

I split my old patch into 8 speparate pieces for easier review.  These patches
are a prerequist for enabling boolification of comparisons in gimplifier and
the necessary type-cast preserving in gimple from/to boolean-type.

This patch adds support to fold_truth_not_expr 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_not_expr): Add
        support for one-bit bitwise operations.

Bootstrapped and regression tested 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 07:48:29.000000000 +0200
+++ gcc/gcc/fold-const.c        2011-07-13 08:59:36.865620200 +0200
@@ -3074,20 +3074,36 @@ fold_truth_not_expr (location_t loc, tre
     case INTEGER_CST:
       return constant_boolean_node (integer_zerop (arg), type);

+    case BIT_AND_EXPR:
+      if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1)
+        return NULL_TREE;
+      if (integer_onep (TREE_OPERAND (arg, 1)))
+       return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0));
+      /* fall through */
     case TRUTH_AND_EXPR:
       loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
       loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
-      return build2_loc (loc, TRUTH_OR_EXPR, type,
+      return build2_loc (loc, (code == BIT_AND_EXPR ? BIT_IOR_EXPR
+                                                   : TRUTH_OR_EXPR), type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));

+    case BIT_IOR_EXPR:
+      if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1)
+        return NULL_TREE;
+      /* fall through.  */
     case TRUTH_OR_EXPR:
       loc1 = expr_location_or (TREE_OPERAND (arg, 0), loc);
       loc2 = expr_location_or (TREE_OPERAND (arg, 1), loc);
-      return build2_loc (loc, TRUTH_AND_EXPR, type,
+      return build2_loc (loc, (code == BIT_IOR_EXPR ? BIT_AND_EXPR
+                                                   : TRUTH_AND_EXPR), type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));

+    case BIT_XOR_EXPR:
+      if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1)
+        return NULL_TREE;
+      /* fall through.  */
     case TRUTH_XOR_EXPR:
       /* Here we can invert either operand.  We invert the first operand
         unless the second operand is a TRUTH_NOT_EXPR in which case our
@@ -3095,10 +3111,14 @@ fold_truth_not_expr (location_t loc, tre
         negation of the second operand.  */

       if (TREE_CODE (TREE_OPERAND (arg, 1)) == TRUTH_NOT_EXPR)
-       return build2_loc (loc, TRUTH_XOR_EXPR, type, TREE_OPERAND (arg, 0),
+       return build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
+                          TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
+      else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BIT_NOT_EXPR
+              && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 1))) == 1)
+       return build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
                           TREE_OPERAND (TREE_OPERAND (arg, 1), 0));
       else
-       return build2_loc (loc, TRUTH_XOR_EXPR, type,
+       return build2_loc (loc, code, type,
                           invert_truthvalue_loc (loc, TREE_OPERAND (arg, 0)),
                           TREE_OPERAND (arg, 1));

@@ -3116,6 +3136,10 @@ fold_truth_not_expr (location_t loc, tre
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)),
                         invert_truthvalue_loc (loc2, TREE_OPERAND (arg, 1)));

+    case BIT_NOT_EXPR:
+      if (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg, 0))) != 1)
+        return NULL_TREE;
+      /* fall through */
     case TRUTH_NOT_EXPR:
       return TREE_OPERAND (arg, 0);

@@ -3158,11 +3182,6 @@ fold_truth_not_expr (location_t loc, tre
       return build1_loc (loc, TREE_CODE (arg), type,
                         invert_truthvalue_loc (loc1, TREE_OPERAND (arg, 0)));

-    case BIT_AND_EXPR:
-      if (!integer_onep (TREE_OPERAND (arg, 1)))
-       return NULL_TREE;
-      return build2_loc (loc, EQ_EXPR, type, arg, build_int_cst (type, 0));
-
     case SAVE_EXPR:
       return build1_loc (loc, TRUTH_NOT_EXPR, type, arg);

Reply via email to