On 1/12/26 10:23, Andrew MacLeod wrote:
On 1/6/26 12:35, Andrew MacLeod wrote:
VRP1 is allowed to remove a __builtin_unreachable () if it determines
that the other edge in the branch dominates all uses of all exports
from the block.
ie
<bb 3>:
x_8 = 1 << i_7;
if (x_8 <= 0) <<-- this is the branch in BB3
goto <bb 4>; [INV]
else
goto <bb 5>; [INV]
<bb 4> :
__builtin_unreachable ();
we can remove the branch and edge to bb 4 if we can prove that there
are no uses of x_8 or i_7 in or dominated by the edge 3->5. We can
then set the global ranges of i_7 and x_8 and move along.
This PR demonstrates that this normally works, but with rangers
ability to recompute values, we also have to look at the dependencies
of all the exports.
IN this case i_7 is defined:
<bb 7> :
# i_2 = PHI <i_7(5), n_4(D)(2), i_7(6)>
i_7 = i_2 + -1;
if (i_2 > 0)
goto <bb 3>; [INV]
else
goto <bb 8>; [INV]
so althoug the uses of i_7 Are dominated by 3->5, it does NOT
dominate the use of i_2 in bb_7. When early removal changes the
global value of i_7, ranger happily recomputes i_2 in the branch and
decides that if i_7 is now [0, +INF], i_2 must always be > 0 and
removes the branch.
Which is clearly incorrect. This patch teaches the early removal
code that it can only remove the unreachable call if x_8, i_7 and ALL
the dependencies used to calculate either name are ALL dominated by
the edge. This information is all trivially available in GORI, so
its noly a minor tweak.
Performance impact over a build of GCC is minimal. a 0.03% slowdown
in VRP.
In the PR I mentioned not removing it if any of the dependencies had
more than a single use, but that turned out to be too limiting. This
solution works much better.
Bootstraps on x86_64-pc-linux-gnu with no regressions. OK?
Andrew
Patch adjusted and applied to GCC-14. OK for branch or not?
Andrew
GCC15 patch was approved, is the same for GCC 14 as well?
Thanks
Andrew