Commit 5d418483 by Marc Glisse Committed by Marc Glisse

tree-ssa-forwprop.c (simplify_bitwise_binary, [...]): Generalize to complex and vector.

2013-06-13  Marc Glisse  <marc.glisse@inria.fr>

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.

From-SVN: r200059
parent 491f54a7
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> 2013-06-13 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define. * config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define.
......
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> 2013-06-12 Michael Meissner <meissner@linux.vnet.ibm.com>
Pat Haugen <pthaugen@us.ibm.com> Pat Haugen <pthaugen@us.ibm.com>
Peter Bergner <bergner@vnet.ibm.com> Peter Bergner <bergner@vnet.ibm.com>
......
/* { 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" } } */
...@@ -1978,8 +1978,8 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi) ...@@ -1978,8 +1978,8 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
/* (a | CST1) & CST2 -> (a & CST2) | (CST1 & CST2). */ /* (a | CST1) & CST2 -> (a & CST2) | (CST1 & CST2). */
if (code == BIT_AND_EXPR if (code == BIT_AND_EXPR
&& def1_code == BIT_IOR_EXPR && def1_code == BIT_IOR_EXPR
&& TREE_CODE (arg2) == INTEGER_CST && CONSTANT_CLASS_P (arg2)
&& TREE_CODE (def1_arg2) == INTEGER_CST) && CONSTANT_CLASS_P (def1_arg2))
{ {
tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2), tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2),
arg2, def1_arg2); arg2, def1_arg2);
...@@ -2009,8 +2009,8 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi) ...@@ -2009,8 +2009,8 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
|| code == BIT_IOR_EXPR || code == BIT_IOR_EXPR
|| code == BIT_XOR_EXPR) || code == BIT_XOR_EXPR)
&& def1_code == code && def1_code == code
&& TREE_CODE (arg2) == INTEGER_CST && CONSTANT_CLASS_P (arg2)
&& TREE_CODE (def1_arg2) == INTEGER_CST) && CONSTANT_CLASS_P (def1_arg2))
{ {
tree cst = fold_build2 (code, TREE_TYPE (arg2), tree cst = fold_build2 (code, TREE_TYPE (arg2),
arg2, def1_arg2); arg2, def1_arg2);
...@@ -2022,7 +2022,6 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi) ...@@ -2022,7 +2022,6 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi)
/* Canonicalize X ^ ~0 to ~X. */ /* Canonicalize X ^ ~0 to ~X. */
if (code == BIT_XOR_EXPR if (code == BIT_XOR_EXPR
&& TREE_CODE (arg2) == INTEGER_CST
&& integer_all_onesp (arg2)) && integer_all_onesp (arg2))
{ {
gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE); gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE);
...@@ -2433,7 +2432,7 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2433,7 +2432,7 @@ associate_plusminus (gimple_stmt_iterator *gsi)
(A +- B) - A -> +- B (A +- B) - A -> +- B
(A +- B) -+ B -> A (A +- B) -+ B -> A
(CST +- A) +- CST -> CST +- A (CST +- A) +- CST -> CST +- A
(A + CST) +- CST -> A + CST (A +- CST) +- CST -> A +- CST
~A + A -> -1 ~A + A -> -1
~A + 1 -> -A ~A + 1 -> -A
A - (A +- B) -> -+ B A - (A +- B) -> -+ B
...@@ -2479,8 +2478,8 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2479,8 +2478,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
gcc_assert (gsi_stmt (*gsi) == stmt); gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true); gimple_set_modified (stmt, true);
} }
else if (TREE_CODE (rhs2) == INTEGER_CST else if (CONSTANT_CLASS_P (rhs2)
&& TREE_CODE (def_rhs1) == INTEGER_CST) && CONSTANT_CLASS_P (def_rhs1))
{ {
/* (CST +- A) +- CST -> CST +- A. */ /* (CST +- A) +- CST -> CST +- A. */
tree cst = fold_binary (code, TREE_TYPE (rhs1), tree cst = fold_binary (code, TREE_TYPE (rhs1),
...@@ -2496,16 +2495,17 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2496,16 +2495,17 @@ associate_plusminus (gimple_stmt_iterator *gsi)
gimple_set_modified (stmt, true); gimple_set_modified (stmt, true);
} }
} }
else if (TREE_CODE (rhs2) == INTEGER_CST else if (CONSTANT_CLASS_P (rhs2)
&& TREE_CODE (def_rhs2) == INTEGER_CST && CONSTANT_CLASS_P (def_rhs2))
&& def_code == PLUS_EXPR)
{ {
/* (A + CST) +- CST -> A + CST. */ /* (A +- CST) +- CST -> A +- CST. */
tree cst = fold_binary (code, TREE_TYPE (rhs1), enum tree_code mix = (code == def_code)
? PLUS_EXPR : MINUS_EXPR;
tree cst = fold_binary (mix, TREE_TYPE (rhs1),
def_rhs2, rhs2); def_rhs2, rhs2);
if (cst && !TREE_OVERFLOW (cst)) if (cst && !TREE_OVERFLOW (cst))
{ {
code = PLUS_EXPR; code = def_code;
gimple_assign_set_rhs_code (stmt, code); gimple_assign_set_rhs_code (stmt, code);
rhs1 = def_rhs1; rhs1 = def_rhs1;
gimple_assign_set_rhs1 (stmt, rhs1); gimple_assign_set_rhs1 (stmt, rhs1);
...@@ -2515,23 +2515,24 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2515,23 +2515,24 @@ associate_plusminus (gimple_stmt_iterator *gsi)
} }
} }
} }
else if (def_code == BIT_NOT_EXPR else if (def_code == BIT_NOT_EXPR && code == PLUS_EXPR)
&& INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
{ {
tree def_rhs1 = gimple_assign_rhs1 (def_stmt); tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
if (code == PLUS_EXPR if (operand_equal_p (def_rhs1, rhs2, 0))
&& operand_equal_p (def_rhs1, rhs2, 0))
{ {
/* ~A + A -> -1. */ /* ~A + A -> -1. */
code = INTEGER_CST; rhs1 = build_all_ones_cst (TREE_TYPE (rhs2));
rhs1 = build_int_cst_type (TREE_TYPE (rhs2), -1);
rhs2 = NULL_TREE; rhs2 = NULL_TREE;
code = TREE_CODE (rhs1);
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt); gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true); gimple_set_modified (stmt, true);
} }
else if (code == PLUS_EXPR else if ((TREE_CODE (TREE_TYPE (rhs2)) != COMPLEX_TYPE
&& integer_onep (rhs1)) && integer_onep (rhs2))
|| (TREE_CODE (rhs2) == COMPLEX_CST
&& integer_onep (TREE_REALPART (rhs2))
&& integer_onep (TREE_IMAGPART (rhs2))))
{ {
/* ~A + 1 -> -A. */ /* ~A + 1 -> -A. */
code = NEGATE_EXPR; code = NEGATE_EXPR;
...@@ -2580,8 +2581,8 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2580,8 +2581,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
gcc_assert (gsi_stmt (*gsi) == stmt); gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true); gimple_set_modified (stmt, true);
} }
else if (TREE_CODE (rhs1) == INTEGER_CST else if (CONSTANT_CLASS_P (rhs1)
&& TREE_CODE (def_rhs1) == INTEGER_CST) && CONSTANT_CLASS_P (def_rhs1))
{ {
/* CST +- (CST +- A) -> CST +- A. */ /* CST +- (CST +- A) -> CST +- A. */
tree cst = fold_binary (code, TREE_TYPE (rhs2), tree cst = fold_binary (code, TREE_TYPE (rhs2),
...@@ -2597,8 +2598,8 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2597,8 +2598,8 @@ associate_plusminus (gimple_stmt_iterator *gsi)
gimple_set_modified (stmt, true); gimple_set_modified (stmt, true);
} }
} }
else if (TREE_CODE (rhs1) == INTEGER_CST else if (CONSTANT_CLASS_P (rhs1)
&& TREE_CODE (def_rhs2) == INTEGER_CST) && CONSTANT_CLASS_P (def_rhs2))
{ {
/* CST +- (A +- CST) -> CST +- A. */ /* CST +- (A +- CST) -> CST +- A. */
tree cst = fold_binary (def_code == code tree cst = fold_binary (def_code == code
...@@ -2615,17 +2616,16 @@ associate_plusminus (gimple_stmt_iterator *gsi) ...@@ -2615,17 +2616,16 @@ associate_plusminus (gimple_stmt_iterator *gsi)
} }
} }
} }
else if (def_code == BIT_NOT_EXPR else if (def_code == BIT_NOT_EXPR)
&& INTEGRAL_TYPE_P (TREE_TYPE (rhs2)))
{ {
tree def_rhs1 = gimple_assign_rhs1 (def_stmt); tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
if (code == PLUS_EXPR if (code == PLUS_EXPR
&& operand_equal_p (def_rhs1, rhs1, 0)) && operand_equal_p (def_rhs1, rhs1, 0))
{ {
/* A + ~A -> -1. */ /* A + ~A -> -1. */
code = INTEGER_CST; rhs1 = build_all_ones_cst (TREE_TYPE (rhs1));
rhs1 = build_int_cst_type (TREE_TYPE (rhs1), -1);
rhs2 = NULL_TREE; rhs2 = NULL_TREE;
code = TREE_CODE (rhs1);
gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE); gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
gcc_assert (gsi_stmt (*gsi) == stmt); gcc_assert (gsi_stmt (*gsi) == stmt);
gimple_set_modified (stmt, true); gimple_set_modified (stmt, true);
......
...@@ -1643,6 +1643,21 @@ build_one_cst (tree type) ...@@ -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 /* Return a constant of arithmetic type TYPE which is the
opposite of the multiplicative identity of the set TYPE. */ opposite of the multiplicative identity of the set TYPE. */
......
...@@ -4768,6 +4768,7 @@ extern tree build_real_from_int_cst (tree, const_tree); ...@@ -4768,6 +4768,7 @@ extern tree build_real_from_int_cst (tree, const_tree);
extern tree build_complex (tree, tree, tree); extern tree build_complex (tree, tree, tree);
extern tree build_one_cst (tree); extern tree build_one_cst (tree);
extern tree build_minus_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_zero_cst (tree);
extern tree build_string (int, const char *); extern tree build_string (int, const char *);
extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL); extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment