[PATCH] Fix PR69983
Richard Biener
rguenther@suse.de
Mon Feb 29 15:26:00 GMT 2016
This fixes fallout of my SCEV correctness change where reassoc no longer
sees the ~A + A simplification opportunity due to casts that are in the
way.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
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.
Index: gcc/tree-ssa-reassoc.c
===================================================================
*** gcc/tree-ssa-reassoc.c (revision 233803)
--- gcc/tree-ssa-reassoc.c (working copy)
*************** is_reassociable_op (gimple *stmt, enum t
*** 605,610 ****
--- 605,625 ----
}
+ /* 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. */
*************** get_unary_op (tree name, enum tree_code
*** 613,618 ****
--- 628,638 ----
{
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;
*************** get_unary_op (tree name, enum tree_code
*** 621,626 ****
--- 641,680 ----
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. */
*************** eliminate_plus_minus_pair (enum tree_cod
*** 731,739 ****
&& oe->rank >= curr->rank - 1 ;
i++)
{
! if (oe->op == negateop)
{
-
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Equivalence: ");
--- 785,793 ----
&& oe->rank >= curr->rank - 1 ;
i++)
{
! if (negateop
! && ops_equal_values_p (oe->op, negateop))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Equivalence: ");
*************** eliminate_plus_minus_pair (enum tree_cod
*** 750,756 ****
return true;
}
! else if (oe->op == notop)
{
tree op_type = TREE_TYPE (oe->op);
--- 804,811 ----
return true;
}
! else if (notop
! && ops_equal_values_p (oe->op, notop))
{
tree op_type = TREE_TYPE (oe->op);
*************** eliminate_plus_minus_pair (enum tree_cod
*** 772,780 ****
}
}
! /* CURR->OP is a negate expr in a plus expr: save it for later
! inspection in repropagate_negates(). */
! if (negateop != NULL_TREE)
plus_negates.safe_push (curr->op);
return false;
--- 827,836 ----
}
}
! /* 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;
*************** repropagate_negates (void)
*** 4211,4217 ****
if (gimple_assign_rhs2 (user) == negate)
{
tree rhs1 = gimple_assign_rhs1 (user);
! tree rhs2 = get_unary_op (negate, NEGATE_EXPR);
gimple_stmt_iterator gsi = gsi_for_stmt (user);
gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, rhs1, rhs2);
update_stmt (user);
--- 4267,4273 ----
if (gimple_assign_rhs2 (user) == negate)
{
tree rhs1 = gimple_assign_rhs1 (user);
! 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);
More information about the Gcc-patches
mailing list