]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[frange] Return false if nothing changed in union_nans().
authorAldy Hernandez <aldyh@redhat.com>
Mon, 21 Aug 2023 11:27:08 +0000 (13:27 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Mon, 21 Aug 2023 13:45:29 +0000 (15:45 +0200)
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

index 76f88d9104672002de154e765febbdadd19da6e1..60180c80e55b19c322c31e92f2ad5660cc27633c 100644 (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