Tested on x86-64-linux-gnu, OK for trunk?

---------------- 8< ----------------

From: Matthias Kretz <[email protected]>

Similar to nearbyint, floor, ceil, and trunc, use (v)roundp[sd] or
vrndscalep[hsd] to vectorize calls to roundeven.

gcc/ChangeLog:

        * config/i386/sse.md (roundeven<mode>2): New.

gcc/testsuite/ChangeLog:

        * gcc.target/i386/avx-roundeven.c: New test.
        * gcc.target/i386/avx512f-roundeven.c: New test.
        * gcc.target/i386/avx512fp16-roundeven.c: New test.
        * gcc.target/i386/sse4_1-roundeven.c: New test.

Signed-off-by: Matthias Kretz <[email protected]>
---
 gcc/config/i386/sse.md                        |  9 +++++++
 gcc/testsuite/gcc.target/i386/avx-roundeven.c |  6 +++++
 .../gcc.target/i386/avx512f-roundeven.c       |  6 +++++
 .../gcc.target/i386/avx512fp16-roundeven.c    | 13 ++++++++++
 .../gcc.target/i386/sse4_1-roundeven.c        | 24 +++++++++++++++++++
 5 files changed, 58 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/avx-roundeven.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-roundeven.c
 create mode 100644 gcc/testsuite/gcc.target/i386/avx512fp16-roundeven.c
 create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-roundeven.c


--
──────────────────────────────────────────────────────────────────────────
 Dr. Matthias Kretz                           https://mattkretz.github.io
 GSI Helmholtz Center for Heavy Ion Research               https://gsi.de
 std::simd
──────────────────────────────────────────────────────────────────────────
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index a02e061c35c..3d9785ecb4d 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -27081,6 +27081,15 @@ (define_insn "*sse4_1_round<ssescalarmodesuffix>"
    (set_attr "prefix" "orig,orig,vex,evex")
    (set_attr "mode" "<MODE>")])
 
+(define_expand "roundeven<mode>2"
+  [(set (match_operand:VFH 0 "register_operand")
+	(unspec:VFH
+	  [(match_operand:VFH 1 "vector_operand")
+	   (match_dup 2)]
+	  UNSPEC_ROUND))]
+  "TARGET_SSE4_1"
+  "operands[2] = GEN_INT (ROUND_ROUNDEVEN | ROUND_NO_EXC);")
+
 (define_expand "floor<mode>2"
   [(set (match_operand:VFH 0 "register_operand")
 	(unspec:VFH
diff --git a/gcc/testsuite/gcc.target/i386/avx-roundeven.c b/gcc/testsuite/gcc.target/i386/avx-roundeven.c
new file mode 100644
index 00000000000..bf279fa6928
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-roundeven.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -mavx -mno-avx2 -mprefer-vector-width=256 -masm=att -ftrapping-math" } */
+/* { dg-final { scan-assembler "vroundps\[ \t]\+\\\$8,\[^\n\r]*%y" } } */
+/* { dg-final { scan-assembler "vroundpd\[ \t]\+\\\$8,\[^\n\r]*%y" } } */
+
+#include "sse4_1-roundeven.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-roundeven.c b/gcc/testsuite/gcc.target/i386/avx512f-roundeven.c
new file mode 100644
index 00000000000..425faf61106
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-roundeven.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -mavx512f -mprefer-vector-width=512 -masm=att -ftrapping-math" } */
+/* { dg-final { scan-assembler "vrndscaleps\[ \t]\+\\\$8,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscalepd\[ \t]\+\\\$8,\[^\n\r]*%z" } } */
+
+#include "sse4_1-roundeven.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512fp16-roundeven.c b/gcc/testsuite/gcc.target/i386/avx512fp16-roundeven.c
new file mode 100644
index 00000000000..da74a4b3379
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512fp16-roundeven.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -mavx512fp16 -mprefer-vector-width=512 -masm=att -ftrapping-math" } */
+/* { dg-final { scan-assembler "vrndscaleph\[ \t]\+\\\$8,\[^\n\r]*%z" } } */
+
+_Float16 a[32], b[32];
+
+void
+test_roundevenf (void)
+{
+  int i;
+  for (i = 0; i < 32; ++i)
+    b[i] = __builtin_roundevenf (a[i]);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundeven.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundeven.c
new file mode 100644
index 00000000000..9eeaa9ff19f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundeven.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msse4.1 -mno-sse4.2 -masm=att" } */
+/* { dg-final { scan-assembler "roundps\[ \t]\+\\\$8," } } */
+/* { dg-final { scan-assembler "roundpd\[ \t]\+\\\$8," } } */
+
+float a[16], b[16];
+double c[8], d[8];
+
+void
+test_roundevenf (void)
+{
+  int i;
+  for (i = 0; i < 16; ++i)
+    b[i] = __builtin_roundevenf (a[i]);
+}
+
+void
+test_roundeven (void)
+{
+  int i;
+  for (i = 0; i < 8; ++i)
+    d[i] = __builtin_roundeven (c[i]);
+}
+

Reply via email to