Patchwork [tree-optimization] : 5 of 6 Improve reassoc for bitwise operations

login
register
mail settings
Submitter Kai Tietz
Date Oct. 7, 2011, 4:39 p.m.
Message ID <CAEwic4a1ToZsTgcMotbRC=L8NDr5X0KJGx9xRUKhemZvFTe0JA@mail.gmail.com>
Download mbox | patch
Permalink /patch/118351/
State New
Headers show

Comments

Kai Tietz - Oct. 7, 2011, 4:39 p.m.
Hello,

This patch adds to the break-up code the conversion for X ==/!= ~0 to
~X ==/!= 0.

ChangeLog

2011-10-07  Kai Tietz  <ktietz@redhat.com>

	* tree-ssa-reassoc.c (break_up_bitwise_combined_stmt): Add
	handling for X !=/== 0 transformation to ~X !=/== 0.

2011-10-07  Kai Tietz  <ktietz@redhat.com>

	* gcc.dg/tree-ssa/reassoc-cmpior-4.c: New file.
	* gcc.dg/tree-ssa/reassoc-cmpior-5.c: New file.
	* gcc.dg/tree-ssa/reassoc-cmpior-6.c: New file.

Bootstrapped and regression-tested for all languages plus Ada and
Obj-C++ on x86_64-pc-linux-gnu.
Ok for apply?

Regards,
Kai

Patch

Index: gcc/gcc/tree-ssa-reassoc.c
===================================================================
--- gcc.orig/gcc/tree-ssa-reassoc.c
+++ gcc/gcc/tree-ssa-reassoc.c
@@ -795,8 +795,8 @@  expand_cmp_ior (tree op, tree type, enum


 /* Break up STMT if it is a combined statement made out of
-   bitwise operations.  Handle expansion of ~(A op B), and
-   (A | B) !=/== 0.  */
+   bitwise operations.  Handle expansion for ~(A op B),
+   for (A | B) !=/== 0, and transform X ==/!= ~0 to ~X ==/!= 0.  */

 static bool
 break_up_bitwise_combined_stmt (gimple stmt)
@@ -821,6 +821,28 @@  break_up_bitwise_combined_stmt (gimple s
       || TREE_CODE (op1) != SSA_NAME)
     return false;

+  /* Transform X !=/== ~0 -> ~X !=/== 0.  */
+  if ((code == EQ_EXPR || code == NE_EXPR)
+      && INTEGRAL_TYPE_P (TREE_TYPE (op1))
+      && TREE_CODE (op2) == INTEGER_CST
+      && integer_all_onesp (op2))
+    {
+      op1_def = SSA_NAME_DEF_STMT (op1);
+      if (!op1_def
+	  || !is_gimple_assign (op1_def)
+	  || !has_single_use (op1))
+	op1_def = NULL;
+      op1 = expand_not_bitwise_binary (TREE_TYPE (op1), op1, op1_def);
+      op2 = build_zero_cst (TREE_TYPE (op1));
+
+      gsi = gsi_for_stmt (stmt);
+      gimple_assign_set_rhs_with_ops (&gsi, code, op1, op2);
+      update_stmt (gsi_stmt (gsi));
+      remove_stmt_chain (old_op1);
+      remove_stmt_chain (old_op2);
+      return true;
+    }
+
   /* If left-hand operand isn't a gimple-assign, or isn't single-used,
      the we can't do anything.  */
   op1_def = SSA_NAME_DEF_STMT (op1);
@@ -3216,6 +3238,8 @@  can_reassociate_p (tree op)

    Break up (X | Y) != 0 into (X != 0) | (Y != 0).

+   Break up X ==/!= ~0 to ~X ==/!= 0.
+
    En passant, clear the GIMPLE visited flag on every statement.  */

 static void
Index: gcc/gcc/testsuite/gcc.dg/tree-ssa/reassoc-cmpior-4.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/reassoc-cmpior-4.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */
+
+int foo (int a, int b, int c, int d)
+{
+  int r1 = ~(a | b | c) == -1;
+  int r2 = (~(a | d | c) != -1) | (b == 0);
+  return ((~r1 == -1) | (~r2 != -1));
+}
+
+/* { dg-final { scan-tree-dump-times "return 1" 1 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
Index: gcc/gcc/testsuite/gcc.dg/tree-ssa/reassoc-cmpior-5.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/reassoc-cmpior-5.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */
+
+int foo (int a, int b, int c, int d)
+{
+  int r1 = a != 0 & c != 0 & b != 0;
+  int r2 = a == 0 | b != 0 | d == 0;
+  return ((~r1 == -1) | (~r2 != -1));
+}
+
+/* { dg-final { scan-tree-dump-times "return 1" 1 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
Index: gcc/gcc/testsuite/gcc.dg/tree-ssa/reassoc-cmpior-6.c
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/gcc.dg/tree-ssa/reassoc-cmpior-6.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */
+
+int foo (int a, int b, int c, int d)
+{
+  int r1 = a != 0 & c != 0 & b != 0;
+  int r2 = a == 0 | b != 0 | d == 0;
+  return ((~r1 != -1) & (~r2 == -1));
+}
+
+/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+