From: Robin Dapp Date: Tue, 3 Feb 2026 20:24:33 +0000 (+0100) Subject: math-opts: Only build FMA when use is in addends. [PR123940] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd67b5a8c90194f7499981bbbc247fd45f8de6b9;p=thirdparty%2Fgcc.git 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 [(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 [(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. Signed-off-by: Robin Dapp --- 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: