On Fri, Oct 11, 2024 at 8:33 PM Hongtao Liu <crazy...@gmail.com> wrote: > > On Fri, Oct 11, 2024 at 8:22 PM Richard Biener <rguent...@suse.de> wrote: > > > > The following helps the x86 backend by canonicalizing FMAs to have > > any negation done to one of the commutative multiplication operands > > be done to a register (and not a memory operand). Likewise to > > put a register operand first and a memory operand second; > > swap_commutative_operands_p seems to treat REG_P and MEM_P the > > same but comments indicate "complex expressiosn should be first". > > > > In particular this does (fma MEM REG REG) -> (fma REG MEM REG) and > > (fma (neg MEM) REG REG) -> (fma (neg REG) MEM REG) which are the > > reasons for the testsuite regressions in gcc.target/i386/cond_op_fma*.c > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > > > I'm not quite sure this is the correct approach - simplify-rtx > > doesn't seem to do "only canonicalization" but the existing FMA > > case looks odd in that context. > > > > Should the target simply reject cases with wrong "canonicalization" > > or does it need to cope with all variants in the patterns that fail > > matching during combine without the change? > Let me try the backend fix first. The backend fix requires at least 8 more patterns, so I think RTL canonicalization would be better. Please go ahead with the patch. > > > > Thanks, > > Richard. > > > > PR target/117072 > > * simplify-rtx.cc (simplify_context::simplify_ternary_operation): > > Adjust FMA canonicalization. > > --- > > gcc/simplify-rtx.cc | 15 +++++++++++++-- > > 1 file changed, 13 insertions(+), 2 deletions(-) > > > > diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc > > index e8e60404ef6..8b4fa0d7aa4 100644 > > --- a/gcc/simplify-rtx.cc > > +++ b/gcc/simplify-rtx.cc > > @@ -6830,10 +6830,21 @@ simplify_context::simplify_ternary_operation > > (rtx_code code, machine_mode mode, > > op0 = tem, op1 = XEXP (op1, 0), any_change = true; > > } > > > > - /* Canonicalize the two multiplication operands. */ > > + /* Canonicalize the two multiplication operands. A negation > > + should go first and if possible the negation should be > > + to a register. */ > > /* a * -b + c => -b * a + c. */ > > - if (swap_commutative_operands_p (op0, op1)) > > + if (swap_commutative_operands_p (op0, op1) > > + || (REG_P (op1) && !REG_P (op0) && GET_CODE (op0) != NEG)) > > std::swap (op0, op1), any_change = true; > > + else if (GET_CODE (op0) == NEG && !REG_P (XEXP (op0, 0)) > > + && REG_P (op1)) > > + { > > + 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); > > -- > > 2.43.0 > > > > -- > BR, > Hongtao
-- BR, Hongtao