aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.cc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2023-07-06 11:23:04 +0200
committerAldy Hernandez <aldyh@redhat.com>2023-07-07 09:55:58 +0200
commitc496d15954cdeab7f9039328f94a6f62cf893d5f (patch)
tree69aeef19876ca1f269ce78965fe8ffe9380b777a /gcc/value-range.cc
parentbf3469b6474f6cff168c1e9171879d29a8296fae (diff)
downloadgcc-c496d15954cdeab7f9039328f94a6f62cf893d5f.zip
gcc-c496d15954cdeab7f9039328f94a6f62cf893d5f.tar.gz
gcc-c496d15954cdeab7f9039328f94a6f62cf893d5f.tar.bz2
A singleton irange has all known bits.
gcc/ChangeLog: * value-range.cc (irange::get_bitmask_from_range): Return all the known bits for a singleton. (irange::set_range_from_bitmask): Set a range of a singleton when all bits are known.
Diffstat (limited to 'gcc/value-range.cc')
-rw-r--r--gcc/value-range.cc19
1 files changed, 18 insertions, 1 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index fbc0c7a..011bdbd 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -1766,10 +1766,19 @@ irange::invert ()
irange_bitmask
irange::get_bitmask_from_range () const
{
+ unsigned prec = TYPE_PRECISION (type ());
wide_int min = lower_bound ();
wide_int max = upper_bound ();
+
+ // All the bits of a singleton are known.
+ if (min == max)
+ {
+ wide_int mask = wi::zero (prec);
+ wide_int value = lower_bound ();
+ return irange_bitmask (value, mask);
+ }
+
wide_int xorv = min ^ max;
- unsigned prec = TYPE_PRECISION (type ());
if (xorv != 0)
xorv = wi::mask (prec - wi::clz (xorv), false, prec);
@@ -1786,6 +1795,14 @@ irange::set_range_from_bitmask ()
gcc_checking_assert (!undefined_p ());
if (m_bitmask.unknown_p ())
return false;
+
+ // If all the bits are known, this is a singleton.
+ if (m_bitmask.mask () == 0)
+ {
+ set (m_type, m_bitmask.value (), m_bitmask.value ());
+ return true;
+ }
+
unsigned popcount = wi::popcount (m_bitmask.get_nonzero_bits ());
// If we have only one bit set in the mask, we can figure out the