]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
middle-end: fix COND_FMS foldings [PR126465]
authorTamar Christina <tamar.christina@arm.com>
Wed, 29 Jul 2026 13:16:52 +0000 (14:16 +0100)
committerTamar Christina <tamar.christina@arm.com>
Wed, 29 Jul 2026 13:17:41 +0000 (14:17 +0100)
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.

gcc/match.pd
gcc/testsuite/gcc.target/aarch64/sve/cond_fma.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/cond_fma_neg_addend.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/cond_fms.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/cond_fnma.c [new file with mode: 0644]
gcc/testsuite/gcc.target/aarch64/sve/cond_fnms.c [new file with mode: 0644]

index 6f2d96c034b4603aaff82455ef66e38876c94176..ff5d012f7fd6dc5457acbf9062c2557886a6ec74 100644 (file)
@@ -10334,14 +10334,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (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)
@@ -10353,9 +10353,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (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)
@@ -10369,7 +10369,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (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)
@@ -10383,7 +10383,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (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)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fma.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fma.c
new file mode 100644 (file)
index 0000000..e4bc381
--- /dev/null
@@ -0,0 +1,37 @@
+/* { 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;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fma_neg_addend.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fma_neg_addend.c
new file mode 100644 (file)
index 0000000..e2c9dd1
--- /dev/null
@@ -0,0 +1,34 @@
+/* { 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;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fms.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fms.c
new file mode 100644 (file)
index 0000000..e383d8e
--- /dev/null
@@ -0,0 +1,37 @@
+/* { 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;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fnma.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fnma.c
new file mode 100644 (file)
index 0000000..dcee73c
--- /dev/null
@@ -0,0 +1,37 @@
+/* { 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;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fnms.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fnms.c
new file mode 100644 (file)
index 0000000..c2951bc
--- /dev/null
@@ -0,0 +1,37 @@
+/* { 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;
+}