From: Richard Biener Date: Mon, 29 Feb 2016 15:30:50 +0000 (+0000) Subject: re PR target/69994 (test case gfortran.dg/reassoc_6.f fails starting with r233669) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ce40915e90234dda80325aa0b8b51bb1a5017b3b;p=gcc.git re PR target/69994 (test case gfortran.dg/reassoc_6.f fails starting with r233669) 2016-02-29 Richard Biener 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6578a392b54..9c7e14961a5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-02-29 Richard Biener + + 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. + 2016-02-29 Martin Liska * hsa-gen.c (gen_body_from_gimple): Dump only if TDF_DETAILS diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 17eb64f1aa7..4c547073905 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 (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);