On Wed, Oct 27, 2021 at 04:29:38PM +0200, Richard Biener wrote:
> So something like the following below?  Note I have to fix 
> simplify_const_unary_operation to not perform the invalid constant
> folding with (not worrying about the exact conversion case - I doubt
> any of the constant folding is really relevant on RTL these days,
> maybe we should simply punt for all unary float-float ops when either
> mode has sign dependent rounding modes)
> 
> diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
> index bbbd6b74942..9522a31570e 100644
> --- a/gcc/simplify-rtx.c
> +++ b/gcc/simplify-rtx.c
> @@ -2068,6 +2073,9 @@ simplify_const_unary_operation (enum rtx_code code, 
> machine_mode mode,
>              and the operand is a signaling NaN.  */
>           if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
>             return NULL_RTX;
> +         /* Or if flag_rounding_math is on.  */
> +         if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
> +           return NULL_RTX;
>           d = real_value_truncate (mode, d);
>           break;

Won't this stop folding of truncations that are never a problem?
I mean at least if the wider float mode constant is exactly representable
in the narrower float mode, no matter what rounding mode is used the value
will be always the same...
And people use
  float f = 1.0;
or
  float f = 1.25;
etc. a lot.
So perhaps again
        if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
            && !exact_real_truncate (mode, &d))
          return NULL_RTX;
?

> /* PR57245 */
> /* { dg-do run } */
> /* { dg-require-effective-target fenv } */
> /* { dg-additional-options "-frounding-math" } */
> 
> #include <fenv.h>
> #include <stdlib.h>
> 
> int
> main ()
> {

Roughly yes.  Some tests also do #ifdef FE_*, so in your case
> #if __DBL_MANT_DIG__ == 53 && __FLT_MANT_DIG__ == 24
+#ifdef FE_UPWARD
>   fesetround (FE_UPWARD);
>   float f = 1.3;
>   if (f != 0x1.4ccccep+0f)
>     __builtin_abort ();
+#endif
+#ifdef FE_TONEAREST
etc.
>   fesetround (FE_TONEAREST);
>   /* Use different actual values so the bogus CSE we perform does not
>      break things.  */
>   f = 1.33;
>   if (f != 0x1.547ae2p+0f)
>     abort ();
>   fesetround (FE_DOWNWARD);
>   f = 1.333;
>   if (f != 0x1.553f7cp+0f)
>     abort ();
>   fesetround (FE_TOWARDZERO);
>   f = 1.3333;
>   if (f != 0x1.555326p+0f)
>     abort ();
> #endif
>   return 0;
> }

        Jakub

Reply via email to