https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90036
--- Comment #23 from Andrew Macleod <amacleod at redhat dot com> --- (In reply to Richard Biener from comment #19) > <bb 2> [local count: 1073741824]: > _1 = vptr_14(D) == 0; > _2 = ownvptr_15(D) != 0; > _3 = _1 | _2; > if (_3 != 0) > goto <bb 4>; [67.00%] > else > goto <bb 3>; [33.00%] > > <bb 4> [local count: 719407024]: > if (vptr_14(D) != 0) > goto <bb 5>; [25.37%] > else > goto <bb 9>; [74.63%] > > <bb 5> [local count: 182536112]: > if (_2 != 0) > goto <bb 7>; [80.00%] > else > goto <bb 6>; [20.00%] > > from _3 != 0 && vptr_14(D) != 0 follows _2 != 0. Why do we not see this? Its complex. Too many layers of indirection for it to currently be automatically detected. >From _3 != 0 && vptr_14(D) != 0 it follows that _2 != 0. Why don’t we derive that? The issue is dependency structure. _2 depends only on ownvptr_15, and nothing directly ties _2 to vptr_14. The only connection is indirect via _3 = _1 | _2, where _1 = (vptr_14 == 0). When vptr_14 is refined on edge 4→5 to ~[0,0], we can calculate _1 = [0,0], but that requires explicitly querying _1. Since _3 itself doesn’t change on that edge, GORI has no trigger to revisit _3, and thus no reason to re-evaluate _2. Ranger tracks forward dependencies (e.g. _3 depends on _1 and _2), but it does not track reverse dependencies. So when vptr_14 changes, we don’t know that _3 may need recomputation unless _3 is *explicitly* queried. And even if _3 were recomputed, there’s no mechanism to propagate that refinement sideways to _2, since _2 is not directly dependent on _3. Logically this is straightforward, but efficiently detecting and propagating these second-order effects without providing the reverse dependencies is non-trivial.
