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.