On 9/27/22 15:00, Mikael Morin wrote:
Hello,
Le 16/09/2022 à 15:26, Aldy Hernandez via Gcc-patches a écrit :
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index d759fcf178c..55a216efd8b 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -617,21 +602,24 @@ frange::contains_p (tree cst) const
if (varying_p ())
return true;
(...)
if (real_compare (GE_EXPR, rv, &m_min) && real_compare (LE_EXPR,
rv, &m_max))
{
+ // Make sure the signs are equal for signed zeros.
if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
- {
- // FIXME: This is still using get_signbit() instead of
- // known_signbit() because the latter bails on possible NANs
- // (for now).
- if (get_signbit ().yes_p ())
- return real_isneg (rv);
- else if (get_signbit ().no_p ())
- return !real_isneg (rv);
- else
- return true;
- }
+ return m_min.sign == m_max.sign && m_min.sign == rv->sign;
return true;
}
return false;
It seems that this won't report any range with mismatching bound signs
as containing zero.
Maybe a selftest explains it better: the following fails.
My apologies for only seeing this now. You did not CC me in the
response, and it got lost amongst my other list mail.
You are absolutely right.
The attached patch fixes this problem. It has been tested on x86-64
Linux and pushed.
Thanks for pointing this out.
Aldy
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 9ca442478c9..8fc909171bc 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -3780,6 +3780,14 @@ range_tests_signed_zeros ()
ASSERT_TRUE (r0.contains_p (neg_zero));
ASSERT_FALSE (r0.contains_p (zero));
+ r0 = frange_float ("-3", "5");
+ ASSERT_TRUE (r0.contains_p (neg_zero));
+ ASSERT_TRUE (r0.contains_p (zero));
+
+ r0 = frange (neg_zero, zero);
+ ASSERT_TRUE (r0.contains_p (neg_zero));
+ ASSERT_TRUE (r0.contains_p (zero));
+
// The intersection of zeros that differ in sign is a NAN (or
// undefined if not honoring NANs).
r0 = frange (neg_zero, neg_zero);
From da2d128a87b2f3359f6f38f29624387094875a60 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez <al...@redhat.com>
Date: Wed, 2 Nov 2022 12:39:45 +0100
Subject: [PATCH] Fix bug in frange::contains_p() for signed zeros.
The contains_p() code wasn't returning true for non-singleton ranges
containing signed zeros. With this patch we now handle:
-0.0 exists in [-3, +5.0]
+0.0 exists in [-3, +5.0]
gcc/ChangeLog:
* value-range.cc (frange::contains_p): Fix signed zero handling.
(range_tests_signed_zeros): New test.
---
gcc/value-range.cc | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 3743ec714b3..a855aaf626c 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -661,7 +661,7 @@ frange::contains_p (tree cst) const
{
// Make sure the signs are equal for signed zeros.
if (HONOR_SIGNED_ZEROS (m_type) && real_iszero (rv))
- return m_min.sign == m_max.sign && m_min.sign == rv->sign;
+ return rv->sign == m_min.sign || rv->sign == m_max.sign;
return true;
}
return false;
@@ -3859,6 +3859,14 @@ range_tests_signed_zeros ()
ASSERT_TRUE (r0.contains_p (neg_zero));
ASSERT_FALSE (r0.contains_p (zero));
+ r0 = frange (neg_zero, zero);
+ ASSERT_TRUE (r0.contains_p (neg_zero));
+ ASSERT_TRUE (r0.contains_p (zero));
+
+ r0 = frange_float ("-3", "5");
+ ASSERT_TRUE (r0.contains_p (neg_zero));
+ ASSERT_TRUE (r0.contains_p (zero));
+
// The intersection of zeros that differ in sign is a NAN (or
// undefined if not honoring NANs).
r0 = frange (neg_zero, neg_zero);
--
2.38.1