in
r16-6508-g772b847d99d5e3 I made some typos
1. I forgot to negate the else value
2. one of the patterns was missing the mask.
This fixes it. The patterns moving the COND inwards are still useful because
they allow FMA forwarding as most micro-architectures don't forward FMA when
there's a random instruction like fneg in between.
Sorry for the mistakes. I added more tests to cover these now.
gcc/ChangeLog:
PR tree-optimization/126465
* match.pd: Fix FMS patterns.
gcc/testsuite/ChangeLog:
PR tree-optimization/126465
* gcc.target/aarch64/sve/cond_fma.c: New test.
* gcc.target/aarch64/sve/cond_fma_neg_addend.c: New test.
* gcc.target/aarch64/sve/cond_fms.c: New test.
* gcc.target/aarch64/sve/cond_fnma.c: New test.
* gcc.target/aarch64/sve/cond_fnms.c: New test.
(IFN_COND_FNMA @3 @0 @1 @2 @4))
(simplify
(fmas @3 @0 @1 (negate @2) @4)
- (IFN_COND_FMS @0 @1 @2 @4))
+ (IFN_COND_FMS @3 @0 @1 @2 @4))
(simplify
(fmas:c @3 (negate @0) @1 (negate @2) @4)
(IFN_COND_FNMS @3 @0 @1 @2 @4))
(simplify
(negate (fmas@3 @4 @0 @1 @2 @5))
(if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
- (IFN_COND_FNMS @4 @0 @1 @2 @5))))
+ (IFN_COND_FNMS @4 @0 @1 @2 (negate @5)))))
(simplify
(IFN_COND_FMS:c @3 (negate @0) @1 @2 @4)
(IFN_COND_FMS:c @3 (negate @0) @1 (negate @2) @4)
(IFN_COND_FNMA @3 @0 @1 @2 @4))
(simplify
- (negate (IFN_FMS@3 @4 @0 @1 @2 @5))
+ (negate (IFN_COND_FMS@3 @4 @0 @1 @2 @5))
(if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
- (IFN_COND_FNMA @4 @0 @1 @2 @5)))
+ (IFN_COND_FNMA @4 @0 @1 @2 (negate @5))))
(simplify
(IFN_COND_FNMA:c @3 (negate @0) @1 @2 @4)
(simplify
(negate (IFN_COND_FNMA@3 @4 @0 @1 @2 @5))
(if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
- (IFN_COND_FMS @4 @0 @1 @2 @5)))
+ (IFN_COND_FMS @4 @0 @1 @2 (negate @5))))
(simplify
(IFN_COND_FNMS:c @3 (negate @0) @1 @2 @4)
(simplify
(negate (IFN_COND_FNMS@3 @4 @0 @1 @2 @5))
(if (!HONOR_SIGN_DEPENDENT_ROUNDING (type) && single_use (@3))
- (IFN_COND_FMA @4 @0 @1 @2 @5))))
+ (IFN_COND_FMA @4 @0 @1 @2 (negate @5)))))
/* CLZ simplifications. */
(for clz (CLZ)
--- /dev/null
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+float a[256], b[256], c[256], d[256], r[256];
+
+__attribute__((noipa)) void
+f (int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ float t = d[i] > 0.f ? __builtin_fmaf (a[i], b[i], c[i]) : d[i];
+ r[i] = -t;
+ }
+}
+
+int
+main (void)
+{
+ for (int i = 0; i < 256; i++)
+ {
+ a[i] = 2.f;
+ b[i] = 3.f;
+ c[i] = 5.f;
+ d[i] = i & 1 ? 4.f : -7.f;
+ r[i] = 0.f;
+ }
+
+ f (256);
+ for (int i = 0; i < 256; i++)
+ {
+ float expected = d[i] > 0.f ? -11.f : 7.f;
+ if (r[i] != expected)
+ __builtin_abort ();
+ }
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+float a[256], b[256], c[256], d[256], r[256];
+
+__attribute__((noipa)) void
+f (int n)
+{
+ for (int i = 0; i < n; i++)
+ r[i] = d[i] > 0.f ? __builtin_fmaf (a[i], b[i], -c[i]) : d[i];
+}
+
+int
+main (void)
+{
+ for (int i = 0; i < 256; i++)
+ {
+ a[i] = 2.f;
+ b[i] = 3.f;
+ c[i] = 5.f;
+ d[i] = i & 1 ? 4.f : -7.f;
+ r[i] = 0.f;
+ }
+
+ f (256);
+ for (int i = 0; i < 256; i++)
+ {
+ float expected = d[i] > 0.f ? 1.f : -7.f;
+ if (r[i] != expected)
+ __builtin_abort ();
+ }
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+float a[256], b[256], c[256], d[256], r[256];
+
+__attribute__((noipa)) void
+f (int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ float t = d[i] > 0.f ? __builtin_fmaf (a[i], b[i], -c[i]) : d[i];
+ r[i] = -t;
+ }
+}
+
+int
+main (void)
+{
+ for (int i = 0; i < 256; i++)
+ {
+ a[i] = 2.f;
+ b[i] = 3.f;
+ c[i] = 5.f;
+ d[i] = i & 1 ? 4.f : -7.f;
+ r[i] = 0.f;
+ }
+
+ f (256);
+ for (int i = 0; i < 256; i++)
+ {
+ float expected = d[i] > 0.f ? -1.f : 7.f;
+ if (r[i] != expected)
+ __builtin_abort ();
+ }
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+float a[256], b[256], c[256], d[256], r[256];
+
+__attribute__((noipa)) void
+f (int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ float t = d[i] > 0.f ? __builtin_fmaf (-a[i], b[i], c[i]) : d[i];
+ r[i] = -t;
+ }
+}
+
+int
+main (void)
+{
+ for (int i = 0; i < 256; i++)
+ {
+ a[i] = 2.f;
+ b[i] = 3.f;
+ c[i] = 5.f;
+ d[i] = i & 1 ? 4.f : -7.f;
+ r[i] = 0.f;
+ }
+
+ f (256);
+ for (int i = 0; i < 256; i++)
+ {
+ float expected = d[i] > 0.f ? 1.f : 7.f;
+ if (r[i] != expected)
+ __builtin_abort ();
+ }
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+float a[256], b[256], c[256], d[256], r[256];
+
+__attribute__((noipa)) void
+f (int n)
+{
+ for (int i = 0; i < n; i++)
+ {
+ float t = d[i] > 0.f ? __builtin_fmaf (-a[i], b[i], -c[i]) : d[i];
+ r[i] = -t;
+ }
+}
+
+int
+main (void)
+{
+ for (int i = 0; i < 256; i++)
+ {
+ a[i] = 2.f;
+ b[i] = 3.f;
+ c[i] = 5.f;
+ d[i] = i & 1 ? 4.f : -7.f;
+ r[i] = 0.f;
+ }
+
+ f (256);
+ for (int i = 0; i < 256; i++)
+ {
+ float expected = d[i] > 0.f ? 11.f : 7.f;
+ if (r[i] != expected)
+ __builtin_abort ();
+ }
+
+ return 0;
+}