https://gcc.gnu.org/g:dc301f9b3da5d0a367a0a6be394eba318d3f5b92

commit r17-4590-gdc301f9b3da5d0a367a0a6be394eba318d3f5b92
Author: Matthias Kretz <[email protected]>
Date:   Tue Sep 22 11:59:06 2026 +0200

    x86: Vectorize roundeven
    
    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]>

Diff:
---
 gcc/config/i386/sse.md                             |  9 ++++++++
 gcc/testsuite/gcc.target/i386/avx-roundeven.c      |  6 ++++++
 gcc/testsuite/gcc.target/i386/avx512f-roundeven.c  |  6 ++++++
 .../gcc.target/i386/avx512fp16-roundeven.c         | 13 ++++++++++++
 gcc/testsuite/gcc.target/i386/sse4_1-roundeven.c   | 24 ++++++++++++++++++++++
 5 files changed, 58 insertions(+)

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 6b57c3019b26..0ce82789dc6c 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -27081,6 +27081,15 @@
    (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 000000000000..bf279fa69281
--- /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 000000000000..425faf611065
--- /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 000000000000..da74a4b33790
--- /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 000000000000..9eeaa9ff19f9
--- /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