> It seems to be the fix is to check ops[] properly?  But maybe I
> mis-understand the failure mode.

Yes, that's sufficient.  The attached was actually my first try but
then I started re-using code.

Bootstrapped and regtested as before, aarch64 still running.

-- 
Regards
 Robin

[PATCH v2] 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.
---
 .../gcc.target/riscv/rvv/autovec/pr123940.c   | 25 +++++++++++++++++++
 gcc/tree-ssa-math-opts.cc                     |  5 ++++
 2 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/pr123940.c

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:
-- 
2.52.0

Reply via email to