]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end: use destination type when folding addent [PR123897]
authorTamar Christina <tamar.christina@arm.com>
Mon, 2 Feb 2026 11:03:53 +0000 (11:03 +0000)
committerTamar Christina <tamar.christina@arm.com>
Mon, 2 Feb 2026 11:03:53 +0000 (11:03 +0000)
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.

gcc/testsuite/gcc.target/aarch64/sve/pr123897.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.cc

diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr123897.c b/gcc/testsuite/gcc.target/aarch64/sve/pr123897.c
new file mode 100644 (file)
index 0000000..d74efab
--- /dev/null
@@ -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" } } */
index 1b642e915fba378079d6f4bb0da25d8c77858153..74dc94c96265547c1bce2b3b24950a7671e43396 100644 (file)
@@ -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);