> 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