]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
math-opts: Only build FMA when use is in addends. [PR123940]
authorRobin Dapp <rdapp@oss.qualcomm.com>
Tue, 3 Feb 2026 20:24:33 +0000 (21:24 +0100)
committerRobin Dapp <rdapp@oss.qualcomm.com>
Fri, 6 Feb 2026 08:18:37 +0000 (09:18 +0100)
When looking for an FMA opportunity we can find a multiplication use in an
else operand:

  vect_pretmp_50.23_121 = MEM <vector(2) charD.2> [(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 <vector(2) charD.2> [(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 <rdapp@oss.qualcomm.com>
gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123940.c [new file with mode: 0644]
gcc/tree-ssa-math-opts.cc

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 (file)
index 0000000..329e598
--- /dev/null
@@ -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" } } */
index e3f88f23628563665912539fd0f8f0e78f441db6..1655b68cb9c6b216626c390fc3475e11e27479c0 100644 (file)
@@ -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: