[frange] Return false if nothing changed in union_nans().

When one operand is a known NAN, we always return TRUE from
union_nans(), even if no change occurred.  This patch fixes the
oversight.

gcc/ChangeLog:

	* value-range.cc (frange::union_nans): Return false if nothing
	changed.
	(range_tests_floats): New test.
This commit is contained in:
Aldy Hernandez 2023-08-21 13:27:08 +02:00
parent ab7de14eaf
commit f9ff6fa582

View file

@ -540,16 +540,26 @@ frange::union_nans (const frange &r)
{
gcc_checking_assert (known_isnan () || r.known_isnan ());
if (known_isnan ())
bool changed = false;
if (known_isnan () && m_kind != r.m_kind)
{
m_kind = r.m_kind;
m_min = r.m_min;
m_max = r.m_max;
changed = true;
}
m_pos_nan |= r.m_pos_nan;
m_neg_nan |= r.m_neg_nan;
normalize_kind ();
return true;
if (m_pos_nan != r.m_pos_nan || m_neg_nan != r.m_neg_nan)
{
m_pos_nan |= r.m_pos_nan;
m_neg_nan |= r.m_neg_nan;
changed = true;
}
if (changed)
{
normalize_kind ();
return true;
}
return false;
}
bool
@ -2715,6 +2725,22 @@ range_tests_nan ()
ASSERT_TRUE (real_identical (&r, &r0.upper_bound ()));
ASSERT_TRUE (!r0.signbit_p (signbit));
ASSERT_TRUE (r0.maybe_isnan ());
// NAN U NAN shouldn't change anything.
r0.set_nan (float_type_node);
r1.set_nan (float_type_node);
ASSERT_FALSE (r0.union_ (r1));
// [3,5] NAN U NAN shouldn't change anything.
r0 = frange_float ("3", "5");
r1.set_nan (float_type_node);
ASSERT_FALSE (r0.union_ (r1));
// [3,5] U NAN *does* trigger a change.
r0 = frange_float ("3", "5");
r0.clear_nan ();
r1.set_nan (float_type_node);
ASSERT_TRUE (r0.union_ (r1));
}
static void