https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121206
Andrew Macleod <amacleod at redhat dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |amacleod at redhat dot com
--- Comment #12 from Andrew Macleod <amacleod at redhat dot com> ---
This issue boils down to the range bitmask code again.
During cache propagation, edge ranges are calculated and intersected with the
exit range to produce a range_on_edge, and these are then combined to produce
on entry ranges in the successor blocks.
Meanwhile, the intersection operation between 2 ranges intersects the ranges,
then intersects the bitmasks to produce a range.
In this testcase,
_3831 : exit range for bb 421 [irange] unsigned int [0, 0][4, 2147483644] MASK
0x7ffffffc VALUE 0x0
is intersected with an outgoing edge:
GORI TRUE : (171016) recomputation (_3831) [irange] unsigned int [0,
6]
and the result was coming up
edge 421->413 :[irange] unsigned int [0, 0][4, 6] MASK 0x4 VALUE 0x0
That mask indicates every bit except bit 2 has a value of two, so the actual
range SHOULD be [irange] unsigned int [0, 0][4, 4] MASK 0x4 VALUE 0x0
When bitmasks are intersected, set_range_from_bitmask is invoked to cull out
any obvious extraneous ranges, like the [5,6] range n the example. As this is
expensive to do everytime, there was a small snippet of code that tried to
predict when it was necessary and when it was not. This was flawed for this
case.
In the end, those extraneous values were causing a cycle in the cache
propagator as the next round of propagation produced:
_3831 exit range after oracle for bb 413 [irange] unsigned int [0, 0][4, 6]
MASK 0x7 VALUE 0x0,
where the mask now incorporates the range along the way... but those values
can't reach this block, so That value caused the original one to be produced
again, and this flipped back and forth infinitely as the propagator expects the
result to converge..
Removing the extraneous ranges removes the issue.
patches are in testing