On Wed, May 22, 2024 at 3:58 AM liuhongt <hongtao....@intel.com> wrote:
>
> 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?

OK if there are no further comments today.

Thanks,
Richard.

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

Reply via email to