diff mbox series

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

Message ID 20230821134653.97329-1-aldyh@redhat.com
State New
Headers show
Series [COMMITTED,frange] Return false if nothing changed in union_nans(). | expand

Commit Message

Aldy Hernandez Aug. 21, 2023, 1:46 p.m. UTC
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.
---
 gcc/value-range.cc | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 76f88d91046..60180c80e55 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