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

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I think the bug is in irange::union_bitmask
with *this
[irange] long long unsigned int [0, 0][17, 17][25, 25] MASK 0xffffffffffffc000
VALUE 0x2d
and r
[irange] long long unsigned int [0, 0]
r.m_bitmask is MASK 0xffffffffffffffff VALUE 0x0.
2447      irange_bitmask bm = get_bitmask ();
2448      irange_bitmask save = bm;
2449      bm.union_ (r.get_bitmask ());
2450      if (save == bm)
2451        return false;
uses get_bitmask though, which first computes independently
2375      irange_bitmask bm
2376        = get_bitmask_from_range (type (), lower_bound (), upper_bound ());
and because lower_bound () is 0 (this is already partially merged) and
upper_bound ()
is 25, bm is then
MASK 0x1f VALUE 0x0
This is then
2377      if (!m_bitmask.unknown_p ())
2378        bm.intersect (m_bitmask);
and we get
MASK 0xffffffffffffffff VALUE 0x0
which is returned.
Now, obviously bm.union_ (r.get_bitmask ()); yields the same
MASK 0xffffffffffffffff VALUE 0x0
and so the code thinks ok, there is no change, we don't need to update
m_bitmask.

The comments talk about semantic bitmasks (what get_bitmask () returns) vs.
what is stored in m_bitmask, it is true that the semantic bitmask didn't really
change, it was
already
MASK 0xffffffffffffffff VALUE 0x0
when the range was just
[irange] long long unsigned int [17, 17][25, 25] MASK 0xffffffffffffc000 VALUE
0x2d
but guess this testcase shows that it is really undesirable to keep random
garbage in m_bitmask when the semantic bitmask didn't change, because we can
later union it with something that will change the semantic bitmask.

So wonder at least about
--- gcc/value-range.cc.jj       2025-01-02 11:23:25.118396777 +0100
+++ gcc/value-range.cc  2025-02-26 18:49:10.713107905 +0100
@@ -2447,7 +2447,7 @@ irange::union_bitmask (const irange &r)
   irange_bitmask bm = get_bitmask ();
   irange_bitmask save = bm;
   bm.union_ (r.get_bitmask ());
-  if (save == bm)
+  if (m_bitmask == bm)
     return false;

   m_bitmask = bm;

which fixes the testcase.  I.e. still return false, just update m_bitmask.

Reply via email to