From 8a85cee26eabf5cfec4e3d93b2516b84b1cca34f Mon Sep 17 00:00:00 2001 From: Kugan Vivekanandarajah Date: Sun, 22 May 2016 08:13:13 +0000 Subject: [PATCH] re PR tree-optimization/40921 (missed optimization: x + (-y * z * z) => x - y * z * z) gcc/testsuite/ChangeLog: 2016-05-22 Kugan Vivekanandarajah PR middle-end/40921 * gcc.dg/tree-ssa/pr40921.c: New test. gcc/ChangeLog: 2016-05-22 Kugan Vivekanandarajah PR middle-end/40921 * tree-ssa-reassoc.c (try_special_add_to_ops): New. (linearize_expr_tree): Call try_special_add_to_ops. (reassociate_bb): Convert MULT_EXPR by (-1) to NEGATE_EXPR. From-SVN: r236564 --- gcc/ChangeLog | 7 ++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/tree-ssa/pr40921.c | 26 +++++++ gcc/tree-ssa-reassoc.c | 98 ++++++++++++++++++------- 4 files changed, 110 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr40921.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a9541406b9..7bdecf0ca91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-05-22 Kugan Vivekanandarajah + + PR middle-end/40921 + * tree-ssa-reassoc.c (try_special_add_to_ops): New. + (linearize_expr_tree): Call try_special_add_to_ops. + (reassociate_bb): Convert MULT_EXPR by (-1) to NEGATE_EXPR. + 2016-05-21 Senthil Kumar Selvaraj * config/avr/avr.c (avr_expand_prologue): Add INCOMING_FRAME_SP_OFFSET diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a409b88e954..3ee60b1bf33 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-22 Kugan Vivekanandarajah + + PR middle-end/40921 + * gcc.dg/tree-ssa/pr40921.c: New test. + 2016-05-20 Pitchumani Sivanupandi PR target/71103 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c b/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c new file mode 100644 index 00000000000..3a5a23a5e54 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c @@ -0,0 +1,26 @@ + +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */ + +unsigned int foo (unsigned int x, unsigned int y, unsigned int z) +{ + return x + (-y * z * z); +} + +float bar (float x, float y, float z) +{ + return x + (-y * z * z); +} + +float bar2 (float x, float y, float z) +{ + return x + (-y * z * z * 5.0f); +} + +float bar3 (float x, float y, float z) +{ + return x + (-y * x * -z); +} + + +/* { dg-final { scan-tree-dump-times "_* = -y_" 0 "optimized" } } */ diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 3c718e9b204..798931fee7a 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -4329,6 +4329,45 @@ acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent) return true; } +/* Try to derive and add operand entry for OP to *OPS. Return false if + unsuccessful. */ + +static bool +try_special_add_to_ops (vec *ops, + enum tree_code code, + tree op, gimple* def_stmt) +{ + tree base = NULL_TREE; + HOST_WIDE_INT exponent = 0; + + if (TREE_CODE (op) != SSA_NAME) + return false; + + if (code == MULT_EXPR + && acceptable_pow_call (def_stmt, &base, &exponent)) + { + add_repeat_to_ops_vec (ops, base, exponent); + gimple_set_visited (def_stmt, true); + return true; + } + else if (code == MULT_EXPR + && is_gimple_assign (def_stmt) + && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR + && !HONOR_SNANS (TREE_TYPE (op)) + && (!HONOR_SIGNED_ZEROS (TREE_TYPE (op)) + || !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (op)))) + { + tree rhs1 = gimple_assign_rhs1 (def_stmt); + tree cst = build_minus_one_cst (TREE_TYPE (op)); + add_to_ops_vec (ops, rhs1); + add_to_ops_vec (ops, cst); + gimple_set_visited (def_stmt, true); + return true; + } + + return false; +} + /* Recursively linearize a binary expression that is the RHS of STMT. Place the operands of the expression tree in the vector named OPS. */ @@ -4343,8 +4382,6 @@ linearize_expr_tree (vec *ops, gimple *stmt, bool binrhsisreassoc = false; enum tree_code rhscode = gimple_assign_rhs_code (stmt); struct loop *loop = loop_containing_stmt (stmt); - tree base = NULL_TREE; - HOST_WIDE_INT exponent = 0; if (set_visited) gimple_set_visited (stmt, true); @@ -4380,24 +4417,10 @@ linearize_expr_tree (vec *ops, gimple *stmt, if (!binrhsisreassoc) { - if (rhscode == MULT_EXPR - && TREE_CODE (binrhs) == SSA_NAME - && acceptable_pow_call (binrhsdef, &base, &exponent)) - { - add_repeat_to_ops_vec (ops, base, exponent); - gimple_set_visited (binrhsdef, true); - } - else + if (!try_special_add_to_ops (ops, rhscode, binrhs, binrhsdef)) add_to_ops_vec (ops, binrhs); - if (rhscode == MULT_EXPR - && TREE_CODE (binlhs) == SSA_NAME - && acceptable_pow_call (binlhsdef, &base, &exponent)) - { - add_repeat_to_ops_vec (ops, base, exponent); - gimple_set_visited (binlhsdef, true); - } - else + if (!try_special_add_to_ops (ops, rhscode, binlhs, binlhsdef)) add_to_ops_vec (ops, binlhs); return; @@ -4437,14 +4460,7 @@ linearize_expr_tree (vec *ops, gimple *stmt, linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs), is_associative, set_visited); - if (rhscode == MULT_EXPR - && TREE_CODE (binrhs) == SSA_NAME - && acceptable_pow_call (SSA_NAME_DEF_STMT (binrhs), &base, &exponent)) - { - add_repeat_to_ops_vec (ops, base, exponent); - gimple_set_visited (SSA_NAME_DEF_STMT (binrhs), true); - } - else + if (!try_special_add_to_ops (ops, rhscode, binrhs, binrhsdef)) add_to_ops_vec (ops, binrhs); } @@ -5208,6 +5224,24 @@ reassociate_bb (basic_block bb) powi_result = attempt_builtin_powi (stmt, &ops); } + operand_entry *last; + bool negate_result = false; + if (ops.length () > 1 + && rhs_code == MULT_EXPR) + { + last = ops.last (); + if (((TREE_CODE (last->op) == INTEGER_CST + && integer_minus_onep (last->op)) + || real_minus_onep (last->op)) + && !HONOR_SNANS (TREE_TYPE (lhs)) + && (!HONOR_SIGNED_ZEROS (TREE_TYPE (lhs)) + || !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (lhs)))) + { + ops.pop (); + negate_result = true; + } + } + /* If the operand vector is now empty, all operands were consumed by the __builtin_powi optimization. */ if (ops.length () == 0) @@ -5270,6 +5304,18 @@ reassociate_bb (basic_block bb) gsi_insert_after (&gsi, mul_stmt, GSI_NEW_STMT); } } + + if (negate_result) + { + stmt = SSA_NAME_DEF_STMT (lhs); + tree tmp = make_ssa_name (TREE_TYPE (lhs)); + gimple_set_lhs (stmt, tmp); + gassign *neg_stmt = gimple_build_assign (lhs, NEGATE_EXPR, + tmp); + gimple_stmt_iterator gsi = gsi_for_stmt (stmt); + gsi_insert_after (&gsi, neg_stmt, GSI_NEW_STMT); + update_stmt (stmt); + } } } } -- 2.30.2