diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2023-07-06 11:23:04 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2023-07-07 09:55:58 +0200 |
commit | c496d15954cdeab7f9039328f94a6f62cf893d5f (patch) | |
tree | 69aeef19876ca1f269ce78965fe8ffe9380b777a /gcc/value-range.cc | |
parent | bf3469b6474f6cff168c1e9171879d29a8296fae (diff) | |
download | gcc-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.cc | 19 |
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 |