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]);
+}
+