Hello,

This patch adds new truth_value_type_p function, which has in contrast
to truth_value_p the ability to detect also bitwise-operation with boolean
characteristics.  This patch has to be applied first for this series, but
it requires the other patches as prerequist of this series.

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

        (fold_ternary_loc): Use truth_value_type_p instead
        of truth_value_p.
        * gimple.c (canonicalize_cond_expr_cond): Likewise.
        * gimplify.c (gimple_boolify): Likewise.
        * tree-ssa-structalias.c (find_func_aliases): Likewise.
        * tree-ssa-forwprop.c (truth_valued_ssa_name): Likewise.
        * tree.h (truth_value_type_p): New function.
        (truth_value_p): Implemented as macro via truth_value_type_p.

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

Regards,
Kai

Index: gcc-head/gcc/fold-const.c
===================================================================
--- gcc-head.orig/gcc/fold-const.c
+++ gcc-head/gcc/fold-const.c
@@ -13416,7 +13581,7 @@ fold_ternary_loc (location_t loc, enum t

       /* If the second operand is simpler than the third, swap them
         since that produces better jump optimization results.  */
-      if (truth_value_p (TREE_CODE (arg0))
+      if (truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0))
          && tree_swap_operands_p (op1, op2, false))
        {
          location_t loc0 = expr_location_or (arg0, loc);
@@ -13442,7 +13607,7 @@ fold_ternary_loc (location_t loc, enum t
         over COND_EXPR in cases such as floating point comparisons.  */
       if (integer_zerop (op1)
          && integer_onep (op2)
-         && truth_value_p (TREE_CODE (arg0)))
+         && truth_value_type_p (TREE_CODE (arg0), TREE_TYPE (arg0)))
        return pedantic_non_lvalue_loc (loc,
                                    fold_convert_loc (loc, type,
                                              invert_truthvalue_loc (loc,
Index: gcc-head/gcc/gimple.c
===================================================================
--- gcc-head.orig/gcc/gimple.c
+++ gcc-head/gcc/gimple.c
@@ -3160,7 +3160,8 @@ canonicalize_cond_expr_cond (tree t)
 {
   /* Strip conversions around boolean operations.  */
   if (CONVERT_EXPR_P (t)
-      && truth_value_p (TREE_CODE (TREE_OPERAND (t, 0))))
+      && truth_value_type_p (TREE_CODE (TREE_OPERAND (t, 0)),
+                            TREE_TYPE (TREE_OPERAND (t, 0))))
     t = TREE_OPERAND (t, 0);

   /* For !x use x == 0.  */
Index: gcc-head/gcc/gimplify.c
===================================================================
--- gcc-head.orig/gcc/gimplify.c
+++ gcc-head/gcc/gimplify.c
@@ -2837,7 +2837,7 @@ gimple_boolify (tree expr)
              if (TREE_CODE (arg) == NOP_EXPR
                  && TREE_TYPE (arg) == TREE_TYPE (call))
                arg = TREE_OPERAND (arg, 0);
-             if (truth_value_p (TREE_CODE (arg)))
+             if (truth_value_type_p (TREE_CODE (arg), TREE_TYPE (arg)))
                {
                  arg = gimple_boolify (arg);
                  CALL_EXPR_ARG (call, 0)
Index: gcc-head/gcc/tree-ssa-structalias.c
===================================================================
--- gcc-head.orig/gcc/tree-ssa-structalias.c
+++ gcc-head/gcc/tree-ssa-structalias.c
@@ -4416,7 +4416,8 @@ find_func_aliases (gimple origt)
                         && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
                   || gimple_assign_single_p (t))
            get_constraint_for_rhs (rhsop, &rhsc);
-         else if (truth_value_p (code))
+         else if (truth_value_type_p (code,
+                                      TREE_TYPE (lhsop)))
            /* Truth value results are not pointer (parts).  Or at least
               very very unreasonable obfuscation of a part.  */
            ;
Index: gcc-head/gcc/tree.h
===================================================================
--- gcc-head.orig/gcc/tree.h
+++ gcc-head/gcc/tree.h
@@ -5307,13 +5307,22 @@ extern tree combine_comparisons (locatio
 extern void debug_fold_checksum (const_tree);

 /* Return nonzero if CODE is a tree code that represents a truth value.  */
+#define truth_value_p(CODE)  truth_value_type_p ((CODE), NULL_TREE)
+
+/* Return nonzero if CODE is a tree code that represents a truth value.
+   If TYPE is an integral type, unsigned, and has precision of one, then
+   additionally return for bitwise-binary and bitwise-invert nonzero.  */
 static inline bool
-truth_value_p (enum tree_code code)
+truth_value_type_p (enum tree_code code, tree type)
 {
   return (TREE_CODE_CLASS (code) == tcc_comparison
          || code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
          || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
-         || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
+         || code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR
+         || ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
+              || code == BIT_XOR_EXPR || code == BIT_NOT_EXPR)
+             && type && INTEGRAL_TYPE_P (type)
+             && TYPE_PRECISION (type) == 1 && TYPE_UNSIGNED (type)));
 }


Index: gcc-head/gcc/tree-ssa-forwprop.c
===================================================================
--- gcc-head.orig/gcc/tree-ssa-forwprop.c
+++ gcc-head/gcc/tree-ssa-forwprop.c
@@ -1668,7 +1668,7 @@ truth_valued_ssa_name (tree name)
     return true;
   def = SSA_NAME_DEF_STMT (name);
   if (is_gimple_assign (def))
-    return truth_value_p (gimple_assign_rhs_code (def));
+    return truth_value_type_p (gimple_assign_rhs_code (def), type);
   return false;
 }

Reply via email to