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