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.