https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115161

--- Comment #11 from Hongtao Liu <liuhongt at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #10)
> Any of the floating point to integer intrinsics if they have out of range
> value (haven't checked whether floating point to unsigned intrinsic is a
> problem too or not).
> No matter if it is float or double (dunno if _Float16 too, or __bf16), and
> no matter if it is scalar intrinsic (ss/sd etc.) or vector and how many
> vector elements.
> But, this isn't really a regression, GCC has always behaved that way, the
> only thing that actually changed is that perhaps we can constant fold more
> than we used to do in the past.
> When not using intrinsics, IMNSHO we should keep doing what we did before.

Can we restrict them under flag_trapping_math?

.i.e

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),

Reply via email to