[PATCH][committed] aarch64: name the SVE FRINTN pattern after the roundeven optab

<[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Kyrylo Tkachov <[email protected]>

The SVE unary floating-point patterns are named from the "optab" attribute of
the unspec they implement, and UNSPEC_COND_FRINTN was mapped to "frintn"
rather than to the standard name.  FRINTN is round-to-nearest-ties-to-even,
which is exactly roundeven, and the Advanced SIMD side already spells it that
way, so the only effect of the mismatch was that roundeven had no SVE
implementation and every such loop was vectorised with Advanced SIMD:

  double *d, *a;  for (i) d[i] = __builtin_roundeven (a[i]);

  before				after

  frintn	v31.2d			frintn	z31.d, p7/m, z31.d

The renaming also applies to the cond_ and aarch64_pred_ forms of the same
pattern, neither of which is a standard name and neither of which is
referred to by name anywhere.

Bootstrapped and tested on aarch64-none-linux-gnu.
Pushing to trunk.
Thanks,
Kyrill

gcc/ChangeLog:

	* config/aarch64/iterators.md (optab): Map UNSPEC_COND_FRINTN to
	roundeven.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/sve/roundeven_1.c: New test.
	* gcc.target/aarch64/sve/roundeven_2.c: New test.

Signed-off-by: Kyrylo Tkachov <[email protected]>
---
 gcc/config/aarch64/iterators.md               |  2 +-
 .../gcc.target/aarch64/sve/roundeven_1.c      | 28 +++++++++
 .../gcc.target/aarch64/sve/roundeven_2.c      | 60 +++++++++++++++++++
 3 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/roundeven_1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/roundeven_2.c

diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index e7ae93d1896..12e65c0f230 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -4571,7 +4571,7 @@
 			(UNSPEC_COND_FRINTA "round")
 			(UNSPEC_COND_FRINTI "nearbyint")
 			(UNSPEC_COND_FRINTM "floor")
-			(UNSPEC_COND_FRINTN "frintn")
+			(UNSPEC_COND_FRINTN "roundeven")
 			(UNSPEC_COND_FRINTP "ceil")
 			(UNSPEC_COND_FRINTX "rint")
 			(UNSPEC_COND_FRINTZ "btrunc")
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/roundeven_1.c b/gcc/testsuite/gcc.target/aarch64/sve/roundeven_1.c
new file mode 100644
index 00000000000..1348ae8fb13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/roundeven_1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=armv8.2-a+sve+fp16 -msve-vector-bits=scalable" } */
+
+void
+rev (double *__restrict d, double *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundeven (a[i]);
+}
+
+void
+revf (float *__restrict d, float *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundevenf (a[i]);
+}
+
+void
+revh (_Float16 *__restrict d, _Float16 *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundevenf16 (a[i]);
+}
+
+/* { dg-final { scan-assembler-times {\tfrintn\tz[0-9]+\.d, p[0-9]+/m, z[0-9]+\.d} 1 } } */
+/* { dg-final { scan-assembler-times {\tfrintn\tz[0-9]+\.s, p[0-9]+/m, z[0-9]+\.s} 1 } } */
+/* { dg-final { scan-assembler-times {\tfrintn\tz[0-9]+\.h, p[0-9]+/m, z[0-9]+\.h} 3 } } */
+/* { dg-final { scan-assembler-not {\tfrintn\tv[0-9]+\.} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/roundeven_2.c b/gcc/testsuite/gcc.target/aarch64/sve/roundeven_2.c
new file mode 100644
index 00000000000..a2a3364fb6e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/roundeven_2.c
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+/* { dg-require-effective-target aarch64_sve_hw } */
+/* { dg-additional-options "-march=armv8-a+sve" } */
+
+#define N 137
+static double a[N], d[N], e[N];
+static float fa[N], fd[N], fe[N];
+
+__attribute__((noipa)) void
+rev (double *__restrict d, double *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundeven (a[i]);
+}
+
+__attribute__((noipa, optimize ("O0"))) void
+rev_ref (double *__restrict d, double *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundeven (a[i]);
+}
+
+__attribute__((noipa)) void
+revf (float *__restrict d, float *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundevenf (a[i]);
+}
+
+__attribute__((noipa, optimize ("O0"))) void
+revf_ref (float *__restrict d, float *__restrict a, int n)
+{
+  for (int i = 0; i < n; i++)
+    d[i] = __builtin_roundevenf (a[i]);
+}
+
+int
+main (void)
+{
+  for (int i = 0; i < N; i++)
+    {
+      a[i] = (i - 68) * 0.5 + (i & 3) * 0.25;
+      fa[i] = (float) a[i];
+    }
+
+  rev (d, a, N);
+  rev_ref (e, a, N);
+  for (int i = 0; i < N; i++)
+    if (d[i] != e[i])
+      __builtin_abort ();
+
+  revf (fd, fa, N);
+  revf_ref (fe, fa, N);
+  for (int i = 0; i < N; i++)
+    if (fd[i] != fe[i])
+      __builtin_abort ();
+
+  return 0;
+}
-- 
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.