tree-optimization/96370 - make reassoc expr rewrite more robust
authorRichard Biener <rguenther@suse.de>
Thu, 30 Jul 2020 08:24:42 +0000 (10:24 +0200)
committerRichard Biener <rguenther@suse.de>
Thu, 30 Jul 2020 09:36:20 +0000 (11:36 +0200)
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.

2020-07-30  Richard Biener  <rguenther@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 [new file with mode: 0644]
gcc/tree-ssa-reassoc.c

diff --git a/gcc/testsuite/gcc.dg/pr96370.c b/gcc/testsuite/gcc.dg/pr96370.c
new file mode 100644 (file)
index 0000000..b939b21
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile { target dfp } } */
+/* { dg-options "-O2 -ffast-math" } */
+
+void c(_Decimal128);
+void a(_Decimal128 b)
+{
+  c(-b * b);
+}
index d06b693ec768b0de86370b034819dd00671b363a..266cff376e5be1aad7095483b83591e2c3fca31c 100644 (file)
@@ -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);