Err.  I think the way you implement that in reassoc is ad-hoc and not
related to reassoc at all.

In fact what reassoc is missing is to handle

  -y * z * (-w) * x -> y * x * w * x

thus optimize negates as if they were additional * -1 entries in a
multiplication chain.  And
then optimize a single remaining * -1 in the result chain to a negate.

Then match.pd handles x + (-y) -> x - y (independent of -frounding-math btw).

So no, this isn't ok as-is, IMHO you want to expand the multiplication ops chain
pulling in the * -1 ops (if single-use, of course).


I agree. Here is the updated patch along what you suggested. Does this look better ?

Thanks,
Kugan
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 17eb64f..bbb5ffb 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -4674,6 +4674,41 @@ attempt_builtin_powi (gimple *stmt, vec<operand_entry *> 
*ops)
   return result;
 }
 
+/* Factor out NEGATE_EXPR from the multiplication operands.  */
+static void
+factor_out_negate_expr (gimple_stmt_iterator *gsi,
+                       gimple *stmt, vec<operand_entry *> *ops)
+{
+  operand_entry *oe;
+  unsigned int i;
+  int neg_count = 0;
+
+  FOR_EACH_VEC_ELT (*ops, i, oe)
+    {
+      if (TREE_CODE (oe->op) != SSA_NAME
+         || !has_single_use (oe->op))
+       continue;
+      gimple *def_stmt = SSA_NAME_DEF_STMT (oe->op);
+      if (!is_gimple_assign (def_stmt)
+         || gimple_assign_rhs_code (def_stmt) != NEGATE_EXPR)
+       continue;
+      oe->op = gimple_assign_rhs1 (def_stmt);
+      neg_count ++;
+    }
+
+  if (neg_count % 2)
+    {
+      tree lhs = gimple_assign_lhs (stmt);
+      tree tmp = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "reassocneg");
+      gimple_set_lhs (stmt, tmp);
+      gassign *neg_stmt = gimple_build_assign (lhs, NEGATE_EXPR,
+                                              tmp);
+      gimple_set_location (neg_stmt, gimple_location (stmt));
+      gimple_set_uid (neg_stmt, gimple_uid (stmt));
+      gsi_insert_after (gsi, neg_stmt, GSI_SAME_STMT);
+    }
+}
+
 /* Attempt to optimize
    CST1 * copysign (CST2, y) -> copysign (CST1 * CST2, y) if CST1 > 0, or
    CST1 * copysign (CST2, y) -> -copysign (CST1 * CST2, y) if CST1 < 0.  */
@@ -4917,6 +4952,12 @@ reassociate_bb (basic_block bb)
              if (rhs_code == MULT_EXPR)
                attempt_builtin_copysign (&ops);
 
+             if (rhs_code == MULT_EXPR)
+               {
+                 factor_out_negate_expr (&gsi, stmt, &ops);
+                 ops.qsort (sort_by_operand_rank);
+               }
+
              if (reassoc_insert_powi_p
                  && rhs_code == MULT_EXPR
                  && flag_unsafe_math_optimizations)

Reply via email to