On Mon, 2 Feb 2026, Tamar Christina wrote:

> Previously the types of the 3 operands would always be the same when you get 
> to
> convert_mult_to_fma_1.  However now they can differ untill we fold the to be 
> the
> same.  Using the type of the final expression is this incorrect and any
> intermediate operations need to happen in the type of the expression being
> folded.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64 and no issues.
> 
> Ok for master?

OK.

> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
>       PR tree-optimization/123897
>       * tree-ssa-math-opts.cc (convert_mult_to_fma_1): Use type of variable
>       being folder.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR tree-optimization/123897
>       * gcc.target/aarch64/sve/pr123897.c: New test.
> 
> ---
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr123897.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/pr123897.c
> new file mode 100644
> index 
> 0000000000000000000000000000000000000000..d74efabb7f89320ff2d9a651bdcd20e9be061d38
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/pr123897.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-O2 -march=armv9-a -msve-vector-bits=256 
> -fdump-tree-widening_mul" } */
> +
> +typedef __attribute__((__vector_size__(sizeof(int)*8))) signed int v8i;
> +typedef __attribute__((__vector_size__(sizeof(int)*8))) unsigned int v8u;
> +void f(v8i *a,v8i *b,v8u *c)
> +{
> +  *c = (v8u)(*a * *b) - *c;
> +}
> +
> +void g(v8i *a,v8i *b,v8u *c)
> +{
> +  *c = *c - (v8u)(*a * *b);
> +}
> +
> +/* { dg-final { scan-tree-dump-times "\.FMA" 2 "widening_mul" } } */
> diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
> index 
> 4b50a96ad3aa19857c5b8436ee8d6d3080d3c9ed..b1fa38a832af889972913553d75305a9420b7b53
>  100644
> --- a/gcc/tree-ssa-math-opts.cc
> +++ b/gcc/tree-ssa-math-opts.cc
> @@ -3105,7 +3105,6 @@ convert_plusminus_to_widen (gimple_stmt_iterator *gsi, 
> gimple *stmt,
>  static void
>  convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
>  {
> -  tree type = TREE_TYPE (mul_result);
>    gimple *use_stmt;
>    imm_use_iterator imm_iter;
>    gcall *fma_stmt;
> @@ -3167,14 +3166,14 @@ convert_mult_to_fma_1 (tree mul_result, tree op1, 
> tree op2)
>       {
>         if (ops[0] == result)
>           /* a * b - c -> a * b + (-c)  */
> -         addop = gimple_build (&seq, NEGATE_EXPR, type, addop);
> +         addop = gimple_build (&seq, NEGATE_EXPR, TREE_TYPE (addop), addop);
>         else
>           /* a - b * c -> (-b) * c + a */
>           negate_p = !negate_p;
>       }
>  
>        if (negate_p)
> -     mulop1 = gimple_build (&seq, NEGATE_EXPR, type, mulop1);
> +     mulop1 = gimple_build (&seq, NEGATE_EXPR, TREE_TYPE (mulop1), mulop1);
>  
>        if (seq)
>       gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
> 
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to