On Thu, Feb 5, 2026 at 9:51 PM Robin Dapp <[email protected]> wrote:
>
> > It seems to be the fix is to check ops[] properly?  But maybe I
> > mis-understand the failure mode.
>
> Yes, that's sufficient.  The attached was actually my first try but
> then I started re-using code.
>
> Bootstrapped and regtested as before, aarch64 still running.

OK.

Thanks,
Richard.

> --
> Regards
>  Robin
>
> [PATCH v2] math-opts: Only build FMA when use is in addends. [PR123940]
>
> When looking for an FMA opportunity we can find a multiplication use in an
> else operand:
>
>   vect_pretmp_50.23_121 = MEM <vector(2) charD.2> [(charD.2 *)&dD.2916 + 14B];
>   vect__28.25_123 = vect_pretmp_50.23_121 * { 2, 2 };
>   vect_patt_99.26_124 = .COND_ADD ({ -1, -1 }, vect_pretmp_50.23_121, { 14, 
> 15 }, vect__28.25_123);
>
> and build it:
>   vect_pretmp_50.23_121 = MEM <vector(2) charD.2> [(charD.2 *)&dD.2916 + 14B];
>   vect_patt_99.26_124 = .FMA (vect_pretmp_50.23_121, { 2, 2 }, 
> vect_pretmp_50.23_121);
>
> This patch checks if the use is in one of the addends.
>
>         PR tree-optimization/123940
>
> gcc/ChangeLog:
>
>         * tree-ssa-math-opts.cc (convert_mult_to_fma): Check
>         multiplication result is an addend.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/rvv/autovec/pr123940.c: New test.
> ---
>  .../gcc.target/riscv/rvv/autovec/pr123940.c   | 25 +++++++++++++++++++
>  gcc/tree-ssa-math-opts.cc                     |  5 ++++
>  2 files changed, 30 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123940.c
>
> diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123940.c 
> b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123940.c
> new file mode 100644
> index 00000000000..329e598f068
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123940.c
> @@ -0,0 +1,25 @@
> +/* { dg-do run } */
> +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d -std=gnu99 
> -fdump-tree-widening_mul" } */
> +
> +long a;
> +long long b;
> +_Bool c[16];
> +char d[16];
> +char e = 0;
> +int f = 1;
> +
> +int main ()
> +{
> +  for (long i = 0; i < 16; ++i)
> +    c[i] = 40;
> +  for (int j = 0; j < 16; j++)
> +    {
> +      e = (c[j] ? j : d[j]) + d[j];
> +      a = f * c[j] ?: ~0;
> +    }
> +  b = (int) e;
> +  if (b != 15)
> +    __builtin_abort ();
> +}
> +
> +/* { dg-final { scan-tree-dump-not "FMA" "widening_mul" } } */
> diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
> index e3f88f23628..1655b68cb9c 100644
> --- a/gcc/tree-ssa-math-opts.cc
> +++ b/gcc/tree-ssa-math-opts.cc
> @@ -3481,6 +3481,7 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree 
> op2,
>           use_operand_p tmp_use_p;
>           if (single_imm_use (cast_lhs, &tmp_use_p, &tmp_use))
>             use_stmt = tmp_use;
> +         result = cast_lhs;
>         }
>
>        /* For now restrict this operations to single basic blocks.  In theory
> @@ -3535,6 +3536,10 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree 
> op2,
>                                               &else_value, &len, &bias))
>         return false;
>
> +      /* The multiplication result must be one of the addition operands.  */
> +      if (ops[0] != result && ops[1] != result)
> +       return false;
> +
>        switch (code)
>         {
>         case MINUS_EXPR:
> --
> 2.52.0
>

Reply via email to