aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr40921.c26
-rw-r--r--gcc/tree-ssa-reassoc.c98
4 files changed, 110 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7a95414..7bdecf0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-22 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ 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 <senthil_kumar.selvaraj@atmel.com>
* config/avr/avr.c (avr_expand_prologue): Add INCOMING_FRAME_SP_OFFSET
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a409b88..3ee60b1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-05-22 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/40921
+ * gcc.dg/tree-ssa/pr40921.c: New test.
+
2016-05-20 Pitchumani Sivanupandi <pitchumani.s@atmel.com>
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 0000000..3a5a23a
--- /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 3c718e9..798931f 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<operand_entry *> *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<operand_entry *> *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<operand_entry *> *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<operand_entry *> *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);
+ }
}
}
}