diff mbox

Implement (a & B) OP0 (c & B) into (a OP0 c) & B simplifying into forwprop

Message ID CA+=Sn1kE1kn3emRseJ=E4ftT02WvpgSkopoJSjAL0Tg9zZx=aQ@mail.gmail.com
State New
Headers show

Commit Message

Andrew Pinski April 21, 2012, 2:26 a.m. UTC
Hi,
  I noticed a missed simple optimization on the tree level where the
and expression could be commoned out.
This patch implements the optimization in tree-ssa-forwprop.c.   I
thought it would be good to get it in even before my tree combiner
work gets in (which I am still working on but recently ran into a git
merging issue which I am still trying to resolve).

OK?  Bootstrapped and tested on x86_64-linux-gnu with no regressions.

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

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

Comments

Richard Biener April 23, 2012, 9:39 a.m. UTC | #1
On Sat, Apr 21, 2012 at 4:26 AM, Andrew Pinski <pinskia@gmail.com> wrote:
> Hi,
>  I noticed a missed simple optimization on the tree level where the
> and expression could be commoned out.
> This patch implements the optimization in tree-ssa-forwprop.c.   I
> thought it would be good to get it in even before my tree combiner
> work gets in (which I am still working on but recently ran into a git
> merging issue which I am still trying to resolve).
>
> OK?  Bootstrapped and tested on x86_64-linux-gnu with no regressions.

Ok.

Thanks,
Richard.

> ChangeLog:
> * tree-ssa-forwprop.c (simplify_bitwise_binary): Simplify (A & B) OP0
> (C & B) to (A OP0) & B.
>
> testsuite/ChangeLog:
> * gcc.dg/tree-ssa/forwprop-17.c: New testcase.
diff mbox

Patch

Index: testsuite/gcc.dg/tree-ssa/forwprop-17.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/forwprop-17.c	(revision 0)
+++ testsuite/gcc.dg/tree-ssa/forwprop-17.c	(revision 0)
@@ -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: tree-ssa-forwprop.c
===================================================================
--- tree-ssa-forwprop.c	(revision 186645)
+++ tree-ssa-forwprop.c	(working copy)
@@ -1886,6 +1886,54 @@  simplify_bitwise_binary (gimple_stmt_ite
       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