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

Reply via email to