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);
