https://gcc.gnu.org/g:075aadae398431b23d34dfc7204e297b8676dd59

commit r16-7241-g075aadae398431b23d34dfc7204e297b8676dd59
Author: Tamar Christina <[email protected]>
Date:   Mon Feb 2 11:03:53 2026 +0000

    middle-end: use destination type when folding addent [PR123897]
    
    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 them to 
be the
    same.  Using the type of the final expression is thus incorrect and any
    intermediate operations need to happen in the type of the expression being
    folded.
    
    gcc/ChangeLog:
    
            PR tree-optimization/123897
            * tree-ssa-math-opts.cc (convert_mult_to_fma_1): Use type of 
variable
            being folded.
    
    gcc/testsuite/ChangeLog:
    
            PR tree-optimization/123897
            * gcc.target/aarch64/sve/pr123897.c: New test.

Diff:
---
 gcc/testsuite/gcc.target/aarch64/sve/pr123897.c | 16 ++++++++++++++++
 gcc/tree-ssa-math-opts.cc                       |  5 ++---
 2 files changed, 18 insertions(+), 3 deletions(-)

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 000000000000..d74efabb7f89
--- /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 1b642e915fba..74dc94c96265 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);

Reply via email to