2013-06-13 Marc Glisse <marc.glisse@inria.fr>
authorglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Jun 2013 08:21:01 +0000 (08:21 +0000)
committerglisse <glisse@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 13 Jun 2013 08:21:01 +0000 (08:21 +0000)
gcc/
* tree-ssa-forwprop.c (simplify_bitwise_binary, associate_plusminus):
Generalize to complex and vector.
* tree.c (build_all_ones_cst): New function.
* tree.h (build_all_ones_cst): Declare it.

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200059 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 21d85fa..19e1b4c 100644 (file)
@@ -1,3 +1,10 @@
+2013-06-13  Marc Glisse  <marc.glisse@inria.fr>
+
+       * tree-ssa-forwprop.c (simplify_bitwise_binary, associate_plusminus):
+       Generalize to complex and vector.
+       * tree.c (build_all_ones_cst): New function.
+       * tree.h (build_all_ones_cst): Declare it.
+
 2013-06-13  Alan Modra  <amodra@gmail.com>
 
        * config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define.
index 3e1fbdb..e3dd654 100644 (file)
@@ -1,3 +1,7 @@
+2013-06-13  Marc Glisse  <marc.glisse@inria.fr>
+
+       * gcc.dg/tree-ssa/forwprop-27.c: New testcase.
+
 2013-06-12  Michael Meissner  <meissner@linux.vnet.ibm.com>
            Pat Haugen <pthaugen@us.ibm.com>
            Peter Bergner <bergner@vnet.ibm.com>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c
new file mode 100644 (file)
index 0000000..9e1b076
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1" } */
+
+typedef int V __attribute__((vector_size(2*sizeof(int))));
+typedef __complex__ int C;
+
+void f (V *v1, V *v2){
+  V w1 = *v1;
+  V x1 = ~w1;
+  *v1 = x1 + 1;
+  V w2 = *v2;
+  V x2 = ~w2;
+  *v2 = x2 + w2;
+}
+
+void g (V *v1, V *v2){
+  V c1 = { 5, -10 };
+  V c2 = { 32, 13 };
+  *v1 = (*v1|c1)&c2;
+  *v2 = (*v2^c1)^c2;
+}
+
+void h (C *v1, C *v2){
+  C w = *v2;
+  C x = *v1 - w;
+  *v1 = x + w;
+}
+
+void i (V *v1, V *v2){
+  V c1 = { 5, -10 };
+  V c2 = { 32, 13 };
+  *v1 = (*v1-c1)+c2;
+  *v2 = (c1-*v2)+c2;
+}
+
+/* { dg-final { scan-tree-dump-not "\\\+" "forwprop1"} } */
+/* { dg-final { scan-tree-dump "{ 0, 4 }" "forwprop1"} } */
+/* { dg-final { scan-tree-dump "{ 37, -5 }" "forwprop1"} } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
+
index 6043d31..c6a7eaf 100644 (file)
@@ -1978,8 +1978,8 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
   /* (a | CST1) & CST2  ->  (a & CST2) | (CST1 & CST2).  */
   if (code == BIT_AND_EXPR
       && def1_code == BIT_IOR_EXPR
-      && TREE_CODE (arg2) == INTEGER_CST
-      && TREE_CODE (def1_arg2) == INTEGER_CST)
+      && CONSTANT_CLASS_P (arg2)
+      && CONSTANT_CLASS_P (def1_arg2))
     {
       tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2),
                              arg2, def1_arg2);
@@ -2009,8 +2009,8 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
        || code == BIT_IOR_EXPR
        || code == BIT_XOR_EXPR)
       && def1_code == code 
-      && TREE_CODE (arg2) == INTEGER_CST
-      && TREE_CODE (def1_arg2) == INTEGER_CST)
+      && CONSTANT_CLASS_P (arg2)
+      && CONSTANT_CLASS_P (def1_arg2))
     {
       tree cst = fold_build2 (code, TREE_TYPE (arg2),
                              arg2, def1_arg2);
@@ -2022,7 +2022,6 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
 
   /* Canonicalize X ^ ~0 to ~X.  */
   if (code == BIT_XOR_EXPR
-      && TREE_CODE (arg2) == INTEGER_CST
       && integer_all_onesp (arg2))
     {
       gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE);
@@ -2433,7 +2432,7 @@ associate_plusminus (gimple_stmt_iterator *gsi)
        (A +- B) - A       ->  +- B
        (A +- B) -+ B      ->  A
        (CST +- A) +- CST  ->  CST +- A
-       (A + CST) +- CST   ->  A + CST
+       (A +- CST) +- CST  ->  A +- CST
        ~A + A             ->  -1
        ~A + 1             ->  -A 
        A - (A +- B)       ->  -+ B
@@ -2479,8 +2478,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
                  gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
-             else if (TREE_CODE (rhs2) == INTEGER_CST
-                      && TREE_CODE (def_rhs1) == INTEGER_CST)
+             else if (CONSTANT_CLASS_P (rhs2)
+                      && CONSTANT_CLASS_P (def_rhs1))
                {
                  /* (CST +- A) +- CST -> CST +- A.  */
                  tree cst = fold_binary (code, TREE_TYPE (rhs1),
@@ -2496,16 +2495,17 @@ associate_plusminus (gimple_stmt_iterator *gsi)
                      gimple_set_modified (stmt, true);
                    }
                }
-             else if (TREE_CODE (rhs2) == INTEGER_CST
-                      && TREE_CODE (def_rhs2) == INTEGER_CST
-                      && def_code == PLUS_EXPR)
+             else if (CONSTANT_CLASS_P (rhs2)
+                      && CONSTANT_CLASS_P (def_rhs2))
                {
-                 /* (A + CST) +- CST -> A + CST.  */
-                 tree cst = fold_binary (code, TREE_TYPE (rhs1),
+                 /* (A +- CST) +- CST -> A +- CST.  */
+                 enum tree_code mix = (code == def_code)
+                                      ? PLUS_EXPR : MINUS_EXPR;
+                 tree cst = fold_binary (mix, TREE_TYPE (rhs1),
                                          def_rhs2, rhs2);
                  if (cst && !TREE_OVERFLOW (cst))
                    {
-                     code = PLUS_EXPR;
+                     code = def_code;
                      gimple_assign_set_rhs_code (stmt, code);
                      rhs1 = def_rhs1;
                      gimple_assign_set_rhs1 (stmt, rhs1);
@@ -2515,23 +2515,24 @@ associate_plusminus (gimple_stmt_iterator *gsi)
                    }
                }
            }
-         else if (def_code == BIT_NOT_EXPR
-                  && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
+         else if (def_code == BIT_NOT_EXPR && code == PLUS_EXPR)
            {
              tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
-             if (code == PLUS_EXPR
-                 && operand_equal_p (def_rhs1, rhs2, 0))
+             if (operand_equal_p (def_rhs1, rhs2, 0))
                {
                  /* ~A + A -> -1.  */
-                 code = INTEGER_CST;
-                 rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1);
+                 rhs1 = build_all_ones_cst (TREE_TYPE (rhs2));
                  rhs2 = NULL_TREE;
+                 code = TREE_CODE (rhs1);
                  gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
                  gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
-             else if (code == PLUS_EXPR
-                      && integer_onep (rhs1))
+             else if ((TREE_CODE (TREE_TYPE (rhs2)) != COMPLEX_TYPE
+                       && integer_onep (rhs2))
+                      || (TREE_CODE (rhs2) == COMPLEX_CST
+                          && integer_onep (TREE_REALPART (rhs2))
+                          && integer_onep (TREE_IMAGPART (rhs2))))
                {
                  /* ~A + 1 -> -A.  */
                  code = NEGATE_EXPR;
@@ -2580,8 +2581,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
                  gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
                }
-             else if (TREE_CODE (rhs1) == INTEGER_CST
-                      && TREE_CODE (def_rhs1) == INTEGER_CST)
+             else if (CONSTANT_CLASS_P (rhs1)
+                      && CONSTANT_CLASS_P (def_rhs1))
                {
                  /* CST +- (CST +- A) -> CST +- A.  */
                  tree cst = fold_binary (code, TREE_TYPE (rhs2),
@@ -2597,8 +2598,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
                      gimple_set_modified (stmt, true);
                    }
                }
-             else if (TREE_CODE (rhs1) == INTEGER_CST
-                      && TREE_CODE (def_rhs2) == INTEGER_CST)
+             else if (CONSTANT_CLASS_P (rhs1)
+                      && CONSTANT_CLASS_P (def_rhs2))
                {
                  /* CST +- (A +- CST) -> CST +- A.  */
                  tree cst = fold_binary (def_code == code
@@ -2615,17 +2616,16 @@ associate_plusminus (gimple_stmt_iterator *gsi)
                    }
                }
            }
-         else if (def_code == BIT_NOT_EXPR
-                  && INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
+         else if (def_code == BIT_NOT_EXPR)
            {
              tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
              if (code == PLUS_EXPR
                  && operand_equal_p (def_rhs1, rhs1, 0))
                {
                  /* A + ~A -> -1.  */
-                 code = INTEGER_CST;
-                 rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1);
+                 rhs1 = build_all_ones_cst (TREE_TYPE (rhs1));
                  rhs2 = NULL_TREE;
+                 code = TREE_CODE (rhs1);
                  gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
                  gcc_assert (gsi_stmt (*gsi) == stmt);
                  gimple_set_modified (stmt, true);
index 6c71025..2c93c0e 100644 (file)
@@ -1643,6 +1643,21 @@ build_one_cst (tree type)
     }
 }
 
+/* Return an integer of type TYPE containing all 1's in as much precision as
+   it contains, or a complex or vector whose subparts are such integers.  */
+
+tree
+build_all_ones_cst (tree type)
+{
+  if (TREE_CODE (type) == COMPLEX_TYPE)
+    {
+      tree scalar = build_all_ones_cst (TREE_TYPE (type));
+      return build_complex (type, scalar, scalar);
+    }
+  else
+    return build_minus_one_cst (type);
+}
+
 /* Return a constant of arithmetic type TYPE which is the
    opposite of the multiplicative identity of the set TYPE.  */
 
index 1d2b252..860d002 100644 (file)
@@ -4768,6 +4768,7 @@ extern tree build_real_from_int_cst (tree, const_tree);
 extern tree build_complex (tree, tree, tree);
 extern tree build_one_cst (tree);
 extern tree build_minus_one_cst (tree);
+extern tree build_all_ones_cst (tree);
 extern tree build_zero_cst (tree);
 extern tree build_string (int, const char *);
 extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);