diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2023-08-21 13:27:08 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2023-08-21 15:45:29 +0200 |
commit | f9ff6fa58217294d63f255dd02abfcc8a074f509 (patch) | |
tree | 0bea3d4aa889017814674883795a83862ec587e0 /gcc | |
parent | ab7de14eaf1d454cb8cbc37dbde89688ec6b7f5a (diff) | |
download | gcc-f9ff6fa58217294d63f255dd02abfcc8a074f509.zip gcc-f9ff6fa58217294d63f255dd02abfcc8a074f509.tar.gz gcc-f9ff6fa58217294d63f255dd02abfcc8a074f509.tar.bz2 |
[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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/value-range.cc | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 76f88d9..60180c8 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -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 |