Make frange selftests work on !HONOR_NANS systems.

I'm just shuffling the FP self tests here, with no change to existing
functionality.

If we agree that explicit NANs in the source code with !HONOR_NANS
should behave any differently, I'm happy to address whatever needs
fixing, but for now I'd like to unblock the !HONOR_NANS build systems.

I have added an adaptation of a test Jakub suggested we handle in the PR:

void funk(int cond)
{
  float x;

  if (cond)
    x = __builtin_nan ("");
  else
    x = 1.24;

  bar(x);
}

For !HONOR_NANS, the range for the PHI of x_1 is the union of 1.24 and
NAN which is really 1.24 with a maybe NAN.  This reflects the IL-- the
presence of the actual NAN.  However, VRP will propagate this because
it sees the 1.24 and ignores the possibility of a NAN, per
!HONOR_NANS.  IMO, this is correct.  OTOH, for HONOR_NANS the unknown
NAN property keeps us from propagating the value.

Is there a reason we don't warn for calls to __builtin_nan when
!HONOR_NANS?  That makes no sense to me.

	PR tree-optimization/106785

gcc/ChangeLog:

	* value-range.cc (range_tests_nan): Adjust tests for !HONOR_NANS.
	(range_tests_floats): Same.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/vrp-float-nan-1.c: New test.
This commit is contained in:
Aldy Hernandez 2022-08-31 14:31:12 +02:00
parent ca8f4e8af1
commit bdfe0d1ce0
2 changed files with 32 additions and 9 deletions

View File

@ -0,0 +1,18 @@
// { dg-do compile }
// { dg-options "-O2 -ffinite-math-only -fdump-tree-evrp" }
void bar(float);
void funk(int cond)
{
float x;
if (cond)
x = __builtin_nan ("");
else
x = 1.24;
bar(x);
}
// { dg-final { scan-tree-dump-times "bar \\(1.24" 1 "evrp" } }

View File

@ -3535,13 +3535,16 @@ range_tests_nan ()
REAL_VALUE_TYPE q, r;
// Equal ranges but with differing NAN bits are not equal.
r1 = frange_float ("10", "12");
r0 = r1;
ASSERT_EQ (r0, r1);
r0.set_nan (fp_prop::NO);
ASSERT_NE (r0, r1);
r0.set_nan (fp_prop::YES);
ASSERT_NE (r0, r1);
if (HONOR_NANS (float_type_node))
{
r1 = frange_float ("10", "12");
r0 = r1;
ASSERT_EQ (r0, r1);
r0.set_nan (fp_prop::NO);
ASSERT_NE (r0, r1);
r0.set_nan (fp_prop::YES);
ASSERT_NE (r0, r1);
}
// NAN ranges are not equal to each other.
r0 = frange_nan (float_type_node);
@ -3624,9 +3627,11 @@ range_tests_floats ()
if (HONOR_SIGNED_ZEROS (float_type_node))
range_tests_signed_zeros ();
// A range of [-INF,+INF] is actually VARYING...
// A range of [-INF,+INF] is actually VARYING if no other properties
// are set.
r0 = frange_float ("-Inf", "+Inf");
ASSERT_TRUE (r0.varying_p ());
if (r0.get_nan ().varying_p ())
ASSERT_TRUE (r0.varying_p ());
// ...unless it has some special property...
r0.set_nan (fp_prop::NO);
ASSERT_FALSE (r0.varying_p ());