https://gcc.gnu.org/g:bd67b5a8c90194f7499981bbbc247fd45f8de6b9

commit r16-7353-gbd67b5a8c90194f7499981bbbc247fd45f8de6b9
Author: Robin Dapp <[email protected]>
Date:   Tue Feb 3 21:24:33 2026 +0100

    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 <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 <[email protected]>

Diff:
---
 .../gcc.target/riscv/rvv/autovec/pr123940.c        | 25 ++++++++++++++++++++++
 gcc/tree-ssa-math-opts.cc                          |  5 +++++
 2 files changed, 30 insertions(+)

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 000000000000..329e598f0683
--- /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 e3f88f236285..1655b68cb9c6 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:

Reply via email to