In the face of the more complex tricks in reassoc with respect to negate processing it can happen that the expression rewrite is fooled to recurse on a leaf and pick up a bogus expression code. The following patch makes the expression rewrite more robust in providing the expression code to it directly since it is the same for all operations in a chain.
Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to master. 2020-07-30 Richard Biener <rguent...@suse.de> PR tree-optimization/96370 * tree-ssa-reassoc.c (rewrite_expr_tree): Add operation code parameter and use it instead of picking it up from the stmt that is being rewritten. (reassociate_bb): Pass down the operation code. * gcc.dg/pr96370.c: New testcase. --- gcc/testsuite/gcc.dg/pr96370.c | 8 ++++++++ gcc/tree-ssa-reassoc.c | 10 +++++----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr96370.c diff --git a/gcc/testsuite/gcc.dg/pr96370.c b/gcc/testsuite/gcc.dg/pr96370.c new file mode 100644 index 00000000000..b939b2141d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr96370.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target dfp } } */ +/* { dg-options "-O2 -ffast-math" } */ + +void c(_Decimal128); +void a(_Decimal128 b) +{ + c(-b * b); +} diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index d06b693ec76..266cff376e5 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -4913,7 +4913,7 @@ insert_stmt_before_use (gimple *stmt, gimple *stmt_to_insert) recursive invocations. */ static tree -rewrite_expr_tree (gimple *stmt, unsigned int opindex, +rewrite_expr_tree (gimple *stmt, enum tree_code rhs_code, unsigned int opindex, vec<operand_entry *> ops, bool changed, bool next_changed) { tree rhs1 = gimple_assign_rhs1 (stmt); @@ -4960,7 +4960,7 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex, = find_insert_point (stmt, oe1->op, oe2->op); lhs = make_ssa_name (TREE_TYPE (lhs)); stmt - = gimple_build_assign (lhs, gimple_assign_rhs_code (stmt), + = gimple_build_assign (lhs, rhs_code, oe1->op, oe2->op); gimple_set_uid (stmt, uid); gimple_set_visited (stmt, true); @@ -5004,7 +5004,7 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex, /* Recurse on the LHS of the binary operator, which is guaranteed to be the non-leaf side. */ tree new_rhs1 - = rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), opindex + 1, ops, + = rewrite_expr_tree (SSA_NAME_DEF_STMT (rhs1), rhs_code, opindex + 1, ops, changed || oe->op != rhs2 || next_changed, false); @@ -5030,7 +5030,7 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex, gimple *insert_point = find_insert_point (stmt, new_rhs1, oe->op); lhs = make_ssa_name (TREE_TYPE (lhs)); - stmt = gimple_build_assign (lhs, gimple_assign_rhs_code (stmt), + stmt = gimple_build_assign (lhs, rhs_code, new_rhs1, oe->op); gimple_set_uid (stmt, uid); gimple_set_visited (stmt, true); @@ -6477,7 +6477,7 @@ reassociate_bb (basic_block bb) if (len >= 3) swap_ops_for_binary_stmt (ops, len - 3, stmt); - new_lhs = rewrite_expr_tree (stmt, 0, ops, + new_lhs = rewrite_expr_tree (stmt, rhs_code, 0, ops, powi_result != NULL || negate_result, len != orig_len); -- 2.26.2