From 5d418483049e504219c1f4bcebfa942863a8f75f Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Thu, 13 Jun 2013 10:21:01 +0200 Subject: [PATCH] tree-ssa-forwprop.c (simplify_bitwise_binary, [...]): Generalize to complex and vector. 2013-06-13 Marc Glisse 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 --- gcc/ChangeLog | 7 +++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c | 40 ++++++++++++++ gcc/tree-ssa-forwprop.c | 60 ++++++++++----------- gcc/tree.c | 15 ++++++ gcc/tree.h | 1 + 6 files changed, 97 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 21d85fa48f0..19e1b4cd8cb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2013-06-13 Marc Glisse + + * 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 * config/rs6000/rs6000.h (LONG_DOUBLE_LARGE_FIRST): Define. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3e1fbdbed85..e3dd654deca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-06-13 Marc Glisse + + * gcc.dg/tree-ssa/forwprop-27.c: New testcase. + 2013-06-12 Michael Meissner Pat Haugen Peter Bergner 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 index 00000000000..9e1b0763b44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-27.c @@ -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" } } */ + diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 6043d318d71..c6a7eafbad5 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -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); diff --git a/gcc/tree.c b/gcc/tree.c index 6c71025b6b4..2c93c0e7c21 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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. */ diff --git a/gcc/tree.h b/gcc/tree.h index 1d2b252dec0..860d002d3a5 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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);