aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-reassoc.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-02-29 15:30:50 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-02-29 15:30:50 +0000
commitce40915e90234dda80325aa0b8b51bb1a5017b3b (patch)
tree6644240717a7baeb5b894890488f4a0be1eb9fde /gcc/tree-ssa-reassoc.c
parent4232ebbbc9c2d188214485cd8e951648c45323e7 (diff)
downloadgcc-ce40915e90234dda80325aa0b8b51bb1a5017b3b.zip
gcc-ce40915e90234dda80325aa0b8b51bb1a5017b3b.tar.gz
gcc-ce40915e90234dda80325aa0b8b51bb1a5017b3b.tar.bz2
re PR target/69994 (test case gfortran.dg/reassoc_6.f fails starting with r233669)
2016-02-29 Richard Biener <rguenther@suse.de> PR tree-optimization/69994 * tree-ssa-reassoc.c (gimple_nop_conversion_p): New function. (get_unary_op): Look through nop conversions. (ops_equal_values_p): New function, look for equality diregarding nop conversions. (eliminate_plus_minus_pair): Use ops_equal_values_p (repropagate_negates): Do not use get_unary_op here. From-SVN: r233816
Diffstat (limited to 'gcc/tree-ssa-reassoc.c')
-rw-r--r--gcc/tree-ssa-reassoc.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 17eb64f..4c54707 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -605,6 +605,21 @@ is_reassociable_op (gimple *stmt, enum tree_code code, struct loop *loop)
}
+/* Return true if STMT is a nop-conversion. */
+
+static bool
+gimple_nop_conversion_p (gimple *stmt)
+{
+ if (gassign *ass = dyn_cast <gassign *> (stmt))
+ {
+ if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (ass))
+ && tree_nop_conversion_p (TREE_TYPE (gimple_assign_lhs (ass)),
+ TREE_TYPE (gimple_assign_rhs1 (ass))))
+ return true;
+ }
+ return false;
+}
+
/* Given NAME, if NAME is defined by a unary operation OPCODE, return the
operand of the negate operation. Otherwise, return NULL. */
@@ -613,6 +628,11 @@ get_unary_op (tree name, enum tree_code opcode)
{
gimple *stmt = SSA_NAME_DEF_STMT (name);
+ /* Look through nop conversions (sign changes). */
+ if (gimple_nop_conversion_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
+
if (!is_gimple_assign (stmt))
return NULL_TREE;
@@ -621,6 +641,40 @@ get_unary_op (tree name, enum tree_code opcode)
return NULL_TREE;
}
+/* Return true if OP1 and OP2 have the same value if casted to either type. */
+
+static bool
+ops_equal_values_p (tree op1, tree op2)
+{
+ if (op1 == op2)
+ return true;
+
+ if (TREE_CODE (op1) == SSA_NAME)
+ {
+ gimple *stmt = SSA_NAME_DEF_STMT (op1);
+ if (gimple_nop_conversion_p (stmt))
+ {
+ op1 = gimple_assign_rhs1 (stmt);
+ if (op1 == op2)
+ return true;
+ }
+ }
+
+ if (TREE_CODE (op2) == SSA_NAME)
+ {
+ gimple *stmt = SSA_NAME_DEF_STMT (op2);
+ if (gimple_nop_conversion_p (stmt))
+ {
+ op2 = gimple_assign_rhs1 (stmt);
+ if (op1 == op2)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
/* If CURR and LAST are a pair of ops that OPCODE allows us to
eliminate through equivalences, do so, remove them from OPS, and
return true. Otherwise, return false. */
@@ -731,9 +785,9 @@ eliminate_plus_minus_pair (enum tree_code opcode,
&& oe->rank >= curr->rank - 1 ;
i++)
{
- if (oe->op == negateop)
+ if (negateop
+ && ops_equal_values_p (oe->op, negateop))
{
-
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Equivalence: ");
@@ -750,7 +804,8 @@ eliminate_plus_minus_pair (enum tree_code opcode,
return true;
}
- else if (oe->op == notop)
+ else if (notop
+ && ops_equal_values_p (oe->op, notop))
{
tree op_type = TREE_TYPE (oe->op);
@@ -772,9 +827,10 @@ eliminate_plus_minus_pair (enum tree_code opcode,
}
}
- /* CURR->OP is a negate expr in a plus expr: save it for later
- inspection in repropagate_negates(). */
- if (negateop != NULL_TREE)
+ /* If CURR->OP is a negate expr without nop conversion in a plus expr:
+ save it for later inspection in repropagate_negates(). */
+ if (negateop != NULL_TREE
+ && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (curr->op)) == NEGATE_EXPR)
plus_negates.safe_push (curr->op);
return false;
@@ -4211,7 +4267,7 @@ repropagate_negates (void)
if (gimple_assign_rhs2 (user) == negate)
{
tree rhs1 = gimple_assign_rhs1 (user);
- tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
+ tree rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (negate));
gimple_stmt_iterator gsi = gsi_for_stmt (user);
gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
update_stmt (user);