On Fri, 7 Nov 2025, Andrew MacLeod wrote:
>
> On 11/7/25 13:28, Richard Biener wrote:
> >
> >> Am 07.11.2025 um 15:46 schrieb Andrew MacLeod <[email protected]>:
> >>
> >>
> >>> On 11/7/25 08:29, Richard Biener wrote:
> >>> When feeding non-SSA names to range_on_edge we degrade to a
> >>> non-contextual query even though range_on_exits handling suggests
> >>> that we can do better. The following does what it does in
> >>> range_on_edge directly, passing the edge source as 'bbend'
> >>> argument to get_tree_range if the edge source has a single
> >>> successor (as will be the case for queries from niter analysis).
> >>>
> >>> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> >>>
> >>> OK? The remainder of the series makes use of this, I'll hold of
> >>> that a bit for followup work.
> >> Yeah, That's good.
> > I did wonder whether the else path using range_on_exit is wrong in this
> > regard?
> >
> > Richard
> >
> No it is correct
>
> For the most part GORI calculates edge ranges for ssa-names independant of
> their actual range. So this is combined with the range-on-exit from the
> block, to produce the actual range on the edge.
>
> ie, if (a > 100) GORI will produce [101, +INF] for the edge range of 'a'
> on the true side.
>
> It is combined with the on exit range of 'a' in the edges src block to
> determine the true range of 'a' on an edge.,
>
> range_on_exit (r, e->src, name);
> <...>
> if (m_cache.range_on_edge (edge_range, e, name))
> r.intersect (edge_range);
>
> In your path with a non-SSA name, its important to only use the on exit range
> if there is a single successor since there will be no edge adjustment.
Hmm, but the above adjustment is intersection, it will make ranges only
smaller. There's also
// If this is not an abnormal edge, check for a non-null exit .
if ((e->flags & (EDGE_EH | EDGE_ABNORMAL)) == 0)
infer_oracle ().maybe_adjust_range (r, name, e->src);
at the <...>, not sure what that does.
That said, there's currently no worker for on_edge for GENERIC in GORI.
But this and the above means that even doing
if (!gimple_range_ssa_p (name))
res = get_tree_range (r, name, NULL, NULL, e->src);
should be correct. Similarly doing get_tree_range (r, name, NULL,
e->dest, NULL) should produce correct answers, no? So I should be
able to remove the single_succ (e->src) requirement - in fact I'd
expect the most precise ranges when using the e->dest in case
there's a single predecessor because then (hopefully) GORI can do
work on mentioned SSA names in the GENERIC expression?
I'm testing
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 942bf8bf0a5..cc474db6818 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -252,8 +252,12 @@ gimple_ranger::range_on_edge (vrange &r, edge e, tree
name)
bool res = true;
if (!gimple_range_ssa_p (name))
- res = get_tree_range (r, name, NULL, NULL,
- single_succ_p (e->src) ? e->src : NULL);
+ {
+ if (single_pred_p (e->dest)
+ res = get_tree_range (r, name, NULL, e->dest, NULL);
+ else
+ res = get_tree_range (r, name, NULL, NULL, e->src);
+ }
else
{
range_on_exit (r, e->src, name);
there's the twist that at e->dest not all mentioned SSA names might
be defined in a dominating position, so this would be an argument
against using e->dest. But then always using e->src should be still
correct?
Thanks,
Richard.