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.