gimple.c (canonicalize_cond_expr_cond): Handle cast from boolean-type.
authorKai Tietz <ktietz@redhat.com>
Tue, 2 Aug 2011 14:55:47 +0000 (16:55 +0200)
committerKai Tietz <ktietz@gcc.gnu.org>
Tue, 2 Aug 2011 14:55:47 +0000 (16:55 +0200)
* gimple.c (canonicalize_cond_expr_cond): Handle cast from
boolean-type.
(ssa_forward_propagate_and_combine): Interprete result of
forward_propagate_comparison.
* gcc/gimple-fold.c (fold_gimple_assign): Add canonicalization for
boolean-typed operands for comparisons.

* gcc.dg/tree-ssa/forwprop-15.c: New testcase.

From-SVN: r177170

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index f525c95441a5797e07beba7f84725725dcfdd18c..7493d2313b237f6424c3afa2f1031dcf3b243a86 100644 (file)
@@ -1,3 +1,12 @@
+2011-08-02  Kai Tietz  <ktietz@redhat.com>
+
+       * gimple.c (canonicalize_cond_expr_cond): Handle cast from
+       boolean-type.
+       (ssa_forward_propagate_and_combine): Interprete result of
+       forward_propagate_comparison.
+       * gcc/gimple-fold.c (fold_gimple_assign): Add canonicalization for
+       boolean-typed operands for comparisons.
+
 2011-08-02  Georg-Johann Lay  <avr@gjlay.de>
        
        * config/avr/libgcc.S: Gather related function in the
index cc89b2fd4fb661dad909eb3ba66f1ef7b760823c..cd988b9c1dbe0f4eeefdb1a7a155a5f42a3682f8 100644 (file)
@@ -814,6 +814,47 @@ fold_gimple_assign (gimple_stmt_iterator *si)
                                             gimple_assign_rhs1 (stmt),
                                             gimple_assign_rhs2 (stmt));
        }
+      /* Try to canonicalize for boolean-typed X the comparisons
+        X == 0, X == 1, X != 0, and X != 1.  */
+      else if (gimple_assign_rhs_code (stmt) == EQ_EXPR
+               || gimple_assign_rhs_code (stmt) == NE_EXPR)
+        {
+         tree lhs = gimple_assign_lhs (stmt);
+         tree op1 = gimple_assign_rhs1 (stmt);
+         tree op2 = gimple_assign_rhs2 (stmt);
+         tree type = TREE_TYPE (op1);
+
+         /* Check whether the comparison operands are of the same boolean
+            type as the result type is.
+            Check that second operand is an integer-constant with value
+            one or zero.  */
+         if (TREE_CODE (op2) == INTEGER_CST
+             && (integer_zerop (op2) || integer_onep (op2))
+             && useless_type_conversion_p (TREE_TYPE (lhs), type))
+           {
+             enum tree_code cmp_code = gimple_assign_rhs_code (stmt);
+             bool is_logical_not = false;
+
+             /* X == 0 and X != 1 is a logical-not.of X
+                X == 1 and X != 0 is X  */
+             if ((cmp_code == EQ_EXPR && integer_zerop (op2))
+                 || (cmp_code == NE_EXPR && integer_onep (op2)))
+               is_logical_not = true;
+
+             if (is_logical_not == false)
+               result = op1;
+             /* Only for one-bit precision typed X the transformation
+                !X -> ~X is valied.  */
+             else if (TYPE_PRECISION (type) == 1)
+               result = build1_loc (gimple_location (stmt), BIT_NOT_EXPR,
+                                    type, op1);
+             /* Otherwise we use !X -> X ^ 1.  */
+             else
+               result = build2_loc (gimple_location (stmt), BIT_XOR_EXPR,
+                                    type, op1, build_int_cst (type, 1));
+            
+           }
+       }
 
       if (!result)
         result = fold_binary_loc (loc, subcode,
index e3095d7e261916cc8c00a30ae068878634bb6b17..af23c6a3fc987867911bdd0f3883664141ca0d7e 100644 (file)
@@ -3160,7 +3160,9 @@ 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_p (TREE_CODE (TREE_OPERAND (t, 0)))
+          || TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0)))
+            == BOOLEAN_TYPE))
     t = TREE_OPERAND (t, 0);
 
   /* For !x use x == 0.  */
index 4ff8a1010d4fced8dc9dcd59d8692544f4bfbdb3..103bf569b86ddff130a1a7e82f9b167d2dadc13a 100644 (file)
@@ -1,3 +1,7 @@
+2011-08-02  Kai Tietz  <ktietz@redhat.com>
+
+       * gcc.dg/tree-ssa/forwprop-15.c: New testcase.
+
 2011-08-01  Jason Merrill  <jason@redhat.com>
 
        PR c++/49932
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-15.c
new file mode 100644 (file)
index 0000000..43c6351
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" }  */
+
+_Bool
+foo (_Bool a, _Bool b, _Bool c
+{
+  _Bool r1 = a == 0 & b != 0;
+  _Bool r2 = b != 0 & c == 0;
+  return (r1 == 0 & r2 == 0);
+}
+
+/* { dg-final { scan-tree-dump-times " == " 0 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times " != " 0 "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
index 7cf420ff496afc67fce3a57c0af5ca0bacde9461..2a56b79a42308b92f708a454d752693affcc26dd 100644 (file)
@@ -468,7 +468,9 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
   if (tmp)
     {
       gimple_assign_set_rhs_from_tree (gsi, tmp);
+      fold_stmt_inplace (stmt);
       update_stmt (stmt);
+
       if (TREE_CODE (rhs1) == SSA_NAME)
        cfg_changed |= remove_prop_source_from_use (rhs1);
       if (TREE_CODE (rhs2) == SSA_NAME)
@@ -2407,7 +2409,8 @@ ssa_forward_propagate_and_combine (void)
            }
          else if (TREE_CODE_CLASS (code) == tcc_comparison)
            {
-             forward_propagate_comparison (stmt);
+             if (forward_propagate_comparison (stmt))
+               cfg_changed = true;
              gsi_next (&gsi);
            }
          else