Tested on x86_64-linux-gnu. OK for trunk? I assume we we don't backport these
kind of changes, right?
(Patch is attached because my mail client wanted to modify the inline patch.)
------------------- 8< ------------------
From: Matthias Kretz <[email protected]>
floor, ceil, and trunc are compiled to vrounds[sd] and vrndscales[sdh]
with flag_trapping_math. The packed instructions were only allowed with
!flag_trapping_math, even though there is no observable difference from
executing vroundss 4 times or vroundps once.
According to ISO 60559, "these operations shall not signal any exception
except for signaling NaN input". Consequently, the vector instructions
with ROUND_NO_EXC are doing exactly that.
The 'round' function still requires !flag_trapping_math because it uses
a floating-point add, which can signal inexact (at least).
gcc/ChangeLog:
PR target/127055
* config/i386/sse.md (floor<mode>2): Drop !flag_trapping_math.
(lfloor<mode><sseintvecmodelower>2): Likewise.
(ceil<mode>2): Likewise.
(lceil<mode><sseintvecmodelower>2): Likewise.
(btrunc<mode>2): Likewise.
gcc/testsuite/ChangeLog:
* gcc.target/i386/avx-pr127055.c: New test.
* gcc.target/i386/avx512f-pr127055.c: New test.
* gcc.target/i386/avx512fp16-pr127055.c: New test.
* gcc.target/i386/sse4_1-pr127055.c: New test.
Signed-off-by: Matthias Kretz <[email protected]>
---
gcc/config/i386/sse.md | 14 ++---
gcc/testsuite/gcc.target/i386/avx-pr127055.c | 11 ++++
.../gcc.target/i386/avx512f-pr127055.c | 11 ++++
.../gcc.target/i386/avx512fp16-pr127055.c | 32 ++++++++++
.../gcc.target/i386/sse4_1-pr127055.c | 61 +++++++++++++++++++
5 files changed, 122 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/avx-pr127055.c
create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-pr127055.c
create mode 100644 gcc/testsuite/gcc.target/i386/avx512fp16-pr127055.c
create mode 100644 gcc/testsuite/gcc.target/i386/sse4_1-pr127055.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 326d22a6d89..796c9d1d1cb 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -26893,13 +26893,13 @@ (define_expand "floor<mode>2"
[(match_operand:VFH 1 "vector_operand")
(match_dup 2)]
UNSPEC_ROUND))]
- "TARGET_SSE4_1 && !flag_trapping_math"
+ "TARGET_SSE4_1"
"operands[2] = GEN_INT (ROUND_FLOOR | ROUND_NO_EXC);")
(define_expand "lfloor<mode><sseintvecmodelower>2"
[(match_operand:<sseintvecmode> 0 "register_operand")
(match_operand:VHF_AVX512VL 1 "nonimmediate_operand")]
- "TARGET_AVX512FP16 && !flag_trapping_math"
+ "TARGET_AVX512FP16"
{
rtx tmp = gen_reg_rtx (<MODE>mode);
emit_insn (gen_floor<mode>2 (tmp, operands[1]));
@@ -26910,7 +26910,7 @@ (define_expand "lfloor<mode><sseintvecmodelower>2"
(define_expand "lfloor<mode><sseintvecmodelower>2"
[(match_operand:<sseintvecmode> 0 "register_operand")
(match_operand:VF1_VF2_AVX512DQ 1 "register_operand")]
- "TARGET_SSE4_1 && !flag_trapping_math"
+ "TARGET_SSE4_1"
{
rtx tmp = gen_reg_rtx (<MODE>mode);
emit_insn (gen_floor<mode>2 (tmp, operands[1]));
@@ -26924,13 +26924,13 @@ (define_expand "ceil<mode>2"
[(match_operand:VFH 1 "vector_operand")
(match_dup 2)]
UNSPEC_ROUND))]
- "TARGET_SSE4_1 && !flag_trapping_math"
+ "TARGET_SSE4_1"
"operands[2] = GEN_INT (ROUND_CEIL | ROUND_NO_EXC);")
(define_expand "lceil<mode><sseintvecmodelower>2"
[(match_operand:<sseintvecmode> 0 "register_operand")
(match_operand:VHF_AVX512VL 1 "register_operand")]
- "TARGET_AVX512FP16 && !flag_trapping_math"
+ "TARGET_AVX512FP16"
{
rtx tmp = gen_reg_rtx (<MODE>mode);
emit_insn (gen_ceil<mode>2 (tmp, operands[1]));
@@ -26941,7 +26941,7 @@ (define_expand "lceil<mode><sseintvecmodelower>2"
(define_expand "lceil<mode><sseintvecmodelower>2"
[(match_operand:<sseintvecmode> 0 "register_operand")
(match_operand:VF1_VF2_AVX512DQ 1 "register_operand")]
- "TARGET_SSE4_1 && !flag_trapping_math"
+ "TARGET_SSE4_1"
{
rtx tmp = gen_reg_rtx (<MODE>mode);
emit_insn (gen_ceil<mode>2 (tmp, operands[1]));
@@ -26955,7 +26955,7 @@ (define_expand "btrunc<mode>2"
[(match_operand:VFH 1 "vector_operand")
(match_dup 2)]
UNSPEC_ROUND))]
- "TARGET_SSE4_1 && !flag_trapping_math"
+ "TARGET_SSE4_1"
"operands[2] = GEN_INT (ROUND_TRUNC | ROUND_NO_EXC);")
(define_expand "round<mode>2"
diff --git a/gcc/testsuite/gcc.target/i386/avx-pr127055.c b/gcc/testsuite/gcc.target/i386/avx-pr127055.c
new file mode 100644
index 00000000000..2f401808212
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-pr127055.c
@@ -0,0 +1,11 @@
+/* PR target/127055 */
+/* { 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]\+\\\$11,\[^\n\r]*%y" } } */
+/* { dg-final { scan-assembler "vroundps\[ \t]\+\\\$10,\[^\n\r]*%y" } } */
+/* { dg-final { scan-assembler "vroundps\[ \t]\+\\\$9,\[^\n\r]*%y" } } */
+/* { dg-final { scan-assembler "vroundpd\[ \t]\+\\\$11,\[^\n\r]*%y" } } */
+/* { dg-final { scan-assembler "vroundpd\[ \t]\+\\\$10,\[^\n\r]*%y" } } */
+/* { dg-final { scan-assembler "vroundpd\[ \t]\+\\\$9,\[^\n\r]*%y" } } */
+
+#include "sse4_1-pr127055.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr127055.c b/gcc/testsuite/gcc.target/i386/avx512f-pr127055.c
new file mode 100644
index 00000000000..8e37e337896
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-pr127055.c
@@ -0,0 +1,11 @@
+/* PR target/127055 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -mavx512f -mprefer-vector-width=512 -masm=att -ftrapping-math" } */
+/* { dg-final { scan-assembler "vrndscaleps\[ \t]\+\\\$11,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscaleps\[ \t]\+\\\$10,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscaleps\[ \t]\+\\\$9,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscalepd\[ \t]\+\\\$11,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscalepd\[ \t]\+\\\$10,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscalepd\[ \t]\+\\\$9,\[^\n\r]*%z" } } */
+
+#include "sse4_1-pr127055.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512fp16-pr127055.c b/gcc/testsuite/gcc.target/i386/avx512fp16-pr127055.c
new file mode 100644
index 00000000000..80b35d0d3e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512fp16-pr127055.c
@@ -0,0 +1,32 @@
+/* PR target/127055 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -mavx512fp16 -mprefer-vector-width=512 -masm=att -ftrapping-math" } */
+/* { dg-final { scan-assembler "vrndscaleph\[ \t]\+\\\$11,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscaleph\[ \t]\+\\\$10,\[^\n\r]*%z" } } */
+/* { dg-final { scan-assembler "vrndscaleph\[ \t]\+\\\$9,\[^\n\r]*%z" } } */
+
+_Float16 a[32], b[32];
+
+void
+test_truncf (void)
+{
+ int i;
+ for (i = 0; i < 32; ++i)
+ b[i] = __builtin_truncf (a[i]);
+}
+
+void
+test_ceilf (void)
+{
+ int i;
+ for (i = 0; i < 32; ++i)
+ b[i] = __builtin_ceilf (a[i]);
+}
+
+void
+test_floorf (void)
+{
+ int i;
+ for (i = 0; i < 32; ++i)
+ b[i] = __builtin_floorf (a[i]);
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-pr127055.c b/gcc/testsuite/gcc.target/i386/sse4_1-pr127055.c
new file mode 100644
index 00000000000..b6ed83025f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-pr127055.c
@@ -0,0 +1,61 @@
+/* PR target/127055 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msse4.1 -mno-sse4.2 -masm=att" } */
+/* { dg-final { scan-assembler "roundps\[ \t]\+\\\$11," } } */
+/* { dg-final { scan-assembler "roundps\[ \t]\+\\\$10," } } */
+/* { dg-final { scan-assembler "roundps\[ \t]\+\\\$9," } } */
+/* { dg-final { scan-assembler "roundpd\[ \t]\+\\\$11," } } */
+/* { dg-final { scan-assembler "roundpd\[ \t]\+\\\$10," } } */
+/* { dg-final { scan-assembler "roundpd\[ \t]\+\\\$9," } } */
+
+float a[16], b[16];
+double c[8], d[8];
+
+void
+test_truncf (void)
+{
+ int i;
+ for (i = 0; i < 16; ++i)
+ b[i] = __builtin_truncf (a[i]);
+}
+
+void
+test_ceilf (void)
+{
+ int i;
+ for (i = 0; i < 16; ++i)
+ b[i] = __builtin_ceilf (a[i]);
+}
+
+void
+test_floorf (void)
+{
+ int i;
+ for (i = 0; i < 16; ++i)
+ b[i] = __builtin_floorf (a[i]);
+}
+
+void
+test_trunc (void)
+{
+ int i;
+ for (i = 0; i < 8; ++i)
+ d[i] = __builtin_trunc (c[i]);
+}
+
+void
+test_ceil (void)
+{
+ int i;
+ for (i = 0; i < 8; ++i)
+ d[i] = __builtin_ceil (c[i]);
+}
+
+void
+test_floor (void)
+{
+ int i;
+ for (i = 0; i < 8; ++i)
+ d[i] = __builtin_floor (c[i]);
+}
+