https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128401

Aldy Hernandez <aldyh at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #2 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
Some FP experts needs to look at this, but I think this is a problem with the
op1_range range-ops as Zhiyang mentions.

We’re trying to solve:
[-INF, -1] +- NAN = op1 / [-INF, -1]

The current code is getting [1, +INF] +-NAN, but I think we should include
-INF, because -INF / -INF is a NAN.

Here is a self test that may help.

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 49dd705db32..f685f9ac538 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -3365,6 +3365,25 @@ range_op_float_tests ()
   ASSERT_FALSE (r.contains_p (val));   // not the cross product's negatives
   real_from_string (&val, "3.0");
   ASSERT_FALSE (r.contains_p (val));   // tighter than the hull [0, 9]
+
+  if (HONOR_NANS (float_type_node) && HONOR_INFINITIES (float_type_node))
+    {
+      r0 = frange (float_type_node, dconstninf, dconstm1);
+      r1 = r0;
+      r1.clear_nan ();
+
+      // We're trying to solve [-INF, -1] +-NAN = op1 / [-INF, -1].
+      // The current code gets [1, +INF] +-NAN, but the correct answer
+      // must include -INF, because -INF / -INF is a NAN.
+      range_op_handler (RDIV_EXPR).op1_range (r, float_type_node, r0, r1);
+      ASSERT_TRUE (r.contains_p (dconstninf));
+
+      // We're trying to solve [-INF, -1] +-NAN = op1 / ([-INF, -1] +-NAN).
+      // The current code gets [1, +INF] +-NAN, but the correct answer
+      // is VARYING +-NAN, because any op1 / NAN is a NAN.
+      range_op_handler (RDIV_EXPR).op1_range (r, float_type_node, r0, r0);
+      ASSERT_TRUE (r.contains_p (dconstm1));
+    }
 }

 } // namespace selftest

Reply via email to