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