https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117072

--- Comment #6 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw, simplify-rtx does

      /* Canonicalize the two multiplication operands.  */
      /* a * -b + c  =>  -b * a + c.  */
      if (swap_commutative_operands_p (op0, op1))
        std::swap (op0, op1), any_change = true;

but it doesn't try to swap_commutative_operands_p on the negate argument
and the non-negated operand, aka -a * b -> -b * a.

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index e8e60404ef6..0c86c204529 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -6835,6 +6835,16 @@ simplify_context::simplify_ternary_operation (rtx_code
code, machine_mode mode,
       if (swap_commutative_operands_p (op0, op1))
        std::swap (op0, op1), any_change = true;

+      /* Canonicalize -a * b + c to -b * a + c if a is not a register
+        but b is.  */
+      if (GET_CODE (op0) == NEG && REG_P (op1) && !REG_P (XEXP (op0, 0)))
+       {
+         op0 = XEXP (op0, 0);
+         op1 = simplify_gen_unary (NEG, mode, op1, mode);
+         std::swap (op0, op1);
+         any_change = true;
+       }
+
       if (any_change)
        return gen_rtx_FMA (mode, op0, op1, op2);
       return NULL_RTX;

fixes part of the observed regressions,

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index e8e60404ef6..13cb2cc0f5c 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -6832,9 +6832,20 @@ simplify_context::simplify_ternary_operation (rtx_code
code, machine_mode mode,

       /* Canonicalize the two multiplication operands.  */
       /* a * -b + c  =>  -b * a + c.  */
-      if (swap_commutative_operands_p (op0, op1))
+      if (swap_commutative_operands_p (op0, op1)
+         || (REG_P (op1) && GET_CODE (op0) != NEG && !REG_P (op0)))
        std::swap (op0, op1), any_change = true;


fixes the rest.  I'm going to propose this.

Reply via email to