]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
frange::set_nonnegative should not contain -NAN.
authorAldy Hernandez <aldyh@redhat.com>
Mon, 19 Sep 2022 07:59:01 +0000 (09:59 +0200)
committerAldy Hernandez <aldyh@redhat.com>
Tue, 20 Sep 2022 17:33:32 +0000 (19:33 +0200)
A specifically nonnegative range should not contain -NAN, otherwise
signbit_p() would return false, because we'd be unsure of the sign.

PR 68097/tree-optimization

gcc/ChangeLog:

* value-range.cc (frange::set_nonnegative): Set +NAN.
(range_tests_signed_zeros): New test.
* value-range.h (frange::update_nan): New overload to set NAN sign.

gcc/value-range.cc
gcc/value-range.h

index a8e3bb39babed6da54142e0940b342d66531f72f..dc42b6d3120d2ac3f1c47d485e360a4b3894bd51 100644 (file)
@@ -775,6 +775,10 @@ void
 frange::set_nonnegative (tree type)
 {
   set (type, dconst0, dconstinf);
+
+  // Set +NAN as the only possibility.
+  if (HONOR_NANS (type))
+    update_nan (/*sign=*/0);
 }
 
 // Here we copy between any two irange's.  The ranges can be legacy or
@@ -3823,6 +3827,11 @@ range_tests_signed_zeros ()
   r1.update_nan ();
   r0.intersect (r1);
   ASSERT_TRUE (r0.known_isnan ());
+
+  r0.set_nonnegative (float_type_node);
+  ASSERT_TRUE (r0.signbit_p (signbit) && !signbit);
+  if (HONOR_NANS (float_type_node))
+    ASSERT_TRUE (r0.maybe_isnan ());
 }
 
 static void
index 795b1f00fdc1083d6ac54c52c6de4a6188bdfe96..7d5584a9294cd9ae7009bedadb44a1c19e4d8f82 100644 (file)
@@ -312,6 +312,7 @@ public:
   const REAL_VALUE_TYPE &lower_bound () const;
   const REAL_VALUE_TYPE &upper_bound () const;
   void update_nan ();
+  void update_nan (bool sign);
   void clear_nan ();
 
   // fpclassify like API
@@ -1099,6 +1100,19 @@ frange::update_nan ()
     verify_range ();
 }
 
+// Like above, but set the sign of the NAN.
+
+inline void
+frange::update_nan (bool sign)
+{
+  gcc_checking_assert (!undefined_p ());
+  m_pos_nan = !sign;
+  m_neg_nan = sign;
+  normalize_kind ();
+  if (flag_checking)
+    verify_range ();
+}
+
 // Clear the NAN bit and adjust the range.
 
 inline void