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

Reply via email to