public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Don't simplify NAN/INF or out-of-range constant for FIX/UNSIGNED_FIX.
@ 2024-05-22  1:57 liuhongt
  2024-05-22  7:46 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: liuhongt @ 2024-05-22  1:57 UTC (permalink / raw)
  To: gcc-patches; +Cc: jakub, pinskia

According to IEEE standard, for conversions from floating point to
integer. When a NaN or infinite operand cannot be represented in the
destination format and this cannot otherwise be indicated, the invalid
operation exception shall be signaled. When a numeric operand would
convert to an integer outside the range of the destination format, the
invalid operation exception shall be signaled if this situation cannot
otherwise be indicated.

The patch prevent simplication of the conversion from floating point
to integer for NAN/INF/out-of-range constant when flag_trapping_math.

Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}
Ok for trunk?

gcc/ChangeLog:

	PR rtl-optimization/100927
	PR rtl-optimization/115161
	PR rtl-optimization/115115
	* simplify-rtx.cc (simplify_const_unary_operation): Prevent
	simplication of FIX/UNSIGNED_FIX for NAN/INF/out-of-range
	constant when flag_trapping_math.

gcc/testsuite/ChangeLog:

	* gcc.target/i386/pr100927.c: New test.
---
 gcc/simplify-rtx.cc                      | 23 ++++++++++++++++----
 gcc/testsuite/gcc.target/i386/pr100927.c | 27 ++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr100927.c

diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 53f54d1d392..b7a770dad60 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -2256,14 +2256,25 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
       switch (code)
 	{
 	case FIX:
+	  /* According to IEEE standard, for conversions from floating point to
+	     integer. When a NaN or infinite operand cannot be represented in
+	     the destination format and this cannot otherwise be indicated, the
+	     invalid operation exception shall be signaled. When a numeric
+	     operand would convert to an integer outside the range of the
+	     destination format, the invalid operation exception shall be
+	     signaled if this situation cannot otherwise be indicated.  */
 	  if (REAL_VALUE_ISNAN (*x))
-	    return const0_rtx;
+	    return flag_trapping_math ? NULL_RTX : const0_rtx;
+
+	  if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
+	    return NULL_RTX;
 
 	  /* Test against the signed upper bound.  */
 	  wmax = wi::max_value (width, SIGNED);
 	  real_from_integer (&t, VOIDmode, wmax, SIGNED);
 	  if (real_less (&t, x))
-	    return immed_wide_int_const (wmax, mode);
+	    return (flag_trapping_math
+		    ? NULL_RTX : immed_wide_int_const (wmax, mode));
 
 	  /* Test against the signed lower bound.  */
 	  wmin = wi::min_value (width, SIGNED);
@@ -2276,13 +2287,17 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
 
 	case UNSIGNED_FIX:
 	  if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
-	    return const0_rtx;
+	    return flag_trapping_math ? NULL_RTX : const0_rtx;
+
+	  if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
+	    return NULL_RTX;
 
 	  /* Test against the unsigned upper bound.  */
 	  wmax = wi::max_value (width, UNSIGNED);
 	  real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
 	  if (real_less (&t, x))
-	    return immed_wide_int_const (wmax, mode);
+	    return (flag_trapping_math
+		    ? NULL_RTX : immed_wide_int_const (wmax, mode));
 
 	  return immed_wide_int_const (real_to_integer (x, &fail, width),
 				       mode);
diff --git a/gcc/testsuite/gcc.target/i386/pr100927.c b/gcc/testsuite/gcc.target/i386/pr100927.c
new file mode 100644
index 00000000000..b137396c30f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr100927.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -O2 -ftrapping-math" } */
+/* { dg-final { scan-assembler-times "cvttps2dq" 3 } }  */
+
+#include <emmintrin.h>
+
+__m128i foo_ofr() {
+  const __m128i iv = _mm_set_epi32(0x4f000000, 0x4f000000, 0x4f000000, 0x4f000000);
+  const __m128  fv = _mm_castsi128_ps(iv);
+  const __m128i riv = _mm_cvttps_epi32(fv);
+  return riv;
+}
+
+__m128i foo_nan() {
+  const __m128i iv = _mm_set_epi32(0xff800001, 0xff800001, 0xff800001, 0xff800001);
+  const __m128  fv = _mm_castsi128_ps(iv);
+  const __m128i riv = _mm_cvttps_epi32(fv);
+  return riv;
+}
+
+__m128i foo_inf() {
+  const __m128i iv = _mm_set_epi32(0xff800000, 0xff800000, 0xff800000, 0xff800000);
+  const __m128  fv = _mm_castsi128_ps(iv);
+  const __m128i riv = _mm_cvttps_epi32(fv);
+  return riv;
+}
+
-- 
2.31.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2024-06-04 14:27 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-22  1:57 [PATCH] Don't simplify NAN/INF or out-of-range constant for FIX/UNSIGNED_FIX liuhongt
2024-05-22  7:46 ` Richard Biener
2024-05-22  7:59   ` Jakub Jelinek
2024-05-23  5:11     ` Hongtao Liu
2024-05-27  1:08       ` liuhongt
2024-06-04 14:27         ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).