tree-ssa-forwprop.c (simplify_bitwise_binary): Simplify (A & B) OP0 (C & B) to (A...
authorAndrew Pinski <apinski@cavium.com>
Mon, 23 Apr 2012 19:37:59 +0000 (19:37 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Mon, 23 Apr 2012 19:37:59 +0000 (12:37 -0700)
2012-04-23  Andrew Pinski  <apinski@cavium.com>

* tree-ssa-forwprop.c (simplify_bitwise_binary): Simplify (A & B) OP0
(C & B) to (A OP0) & B.

2012-04-23  Andrew Pinski  <apinski@cavium.com>

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

From-SVN: r186721

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

index 6f40fa1b645c39849f4f21699d4bf706ded9d91c..e62b04eed7b40792efd3d732045dbef7d980921f 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-23  Andrew Pinski  <apinski@cavium.com>
+
+       * tree-ssa-forwprop.c (simplify_bitwise_binary): Simplify (A & B) OP0
+       (C & B) to (A OP0) & B.
+
 2012-04-23  Martin Jambor  <mjambor@suse.cz>
 
        * expr.c (expand_expr_real_1): Remove setting parent's alias set for
index 426d8fc64af4dedcea9bbc00ff7d2885bfd6841d..36fdbb5ad6dd0cac79beb160a3847095f0de300b 100644 (file)
@@ -1,3 +1,7 @@
+2012-04-23  Andrew Pinski  <apinski@cavium.com>
+
+       * gcc.dg/tree-ssa/forwprop-17.c: New testcase.
+
 2012-04-23  Bill Schmidt  <wschmidt@linux.ibm.com>
 
        PR regression/53076
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-17.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-17.c
new file mode 100644 (file)
index 0000000..a85d0eb
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int foo (int xx, int xy)
+{
+  xx &=1;
+  xy &=1;
+  return xx ^ xy;
+}
+
+/* { dg-final { scan-tree-dump-times " & 1" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 965f44150e613a86df82700f11b93700eab7c81a..349272dae02541b567dbe6c785684481de876a33 100644 (file)
@@ -1886,6 +1886,54 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
       return true;
     }
 
+
+   /* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */
+   if (def1_code == def2_code
+       && def1_code == BIT_AND_EXPR
+       && operand_equal_for_phi_arg_p (gimple_assign_rhs2 (def1),
+                                      gimple_assign_rhs2 (def2)))
+    {
+      tree b = gimple_assign_rhs2 (def1);
+      tree a = def1_arg1;
+      tree c = def2_arg1;
+      tree inner = fold_build2 (code, TREE_TYPE (arg2), a, c);
+      /* If A OP0 C (this usually means C is the same as A) is 0
+        then fold it down correctly. */
+      if (integer_zerop (inner))
+       {
+         gimple_assign_set_rhs_from_tree (gsi, inner);
+         update_stmt (stmt);
+         return true;
+       }
+      /* If A OP0 C (this usually means C is the same as A) is a ssa_name
+        then fold it down correctly. */
+      else if (TREE_CODE (inner) == SSA_NAME)
+       {
+         tree outer = fold_build2 (def1_code, TREE_TYPE (inner),
+                                   inner, b);
+         gimple_assign_set_rhs_from_tree (gsi, outer);
+         update_stmt (stmt);
+         return true;
+       }
+      else
+       {
+         gimple newop;
+         tree tem;
+         tem = create_tmp_reg (TREE_TYPE (arg2), NULL);
+         newop = gimple_build_assign_with_ops (code, tem, a, c);
+         tem = make_ssa_name (tem, newop);
+         gimple_assign_set_lhs (newop, tem);
+         gimple_set_location (newop, gimple_location (stmt));
+         /* Make sure to re-process the new stmt as it's walking upwards.  */
+         gsi_insert_before (gsi, newop, GSI_NEW_STMT);
+         gimple_assign_set_rhs1 (stmt, tem);
+         gimple_assign_set_rhs2 (stmt, b);
+         gimple_assign_set_rhs_code (stmt, def1_code);
+         update_stmt (stmt);
+         return true;
+       }
+    }
+
   /* (a | CST1) & CST2  ->  (a & CST2) | (CST1 & CST2).  */
   if (code == BIT_AND_EXPR
       && def1_code == BIT_IOR_EXPR