On 11/5/24 03:37, Richard Biener wrote:
On Mon, Nov 4, 2024 at 4:52 PM Andrew MacLeod <amacl...@redhat.com> wrote:

Am 04.11.2024 um 16:32 schrieb Andrew MacLeod <amacl...@redhat.com>:


On 11/4/24 10:27, Richard Biener wrote:

Am 04.11.2024 um 16:01 schrieb Andrew MacLeod <amacl...@redhat.com>:
The invert() range operation is not supported on values of either VARYING or 
UNDEFINED.  Primarily this is because UNDEFINED has no type, which makes it 
impossible to perform invert() twice on a value, and produce that same value.  
There were also times when it wasn't precisely clear what the client expects 
when UNDEFINED or VARYING is inverted.. so it is handled at the caller point.

When processing switches, whenever we find the ranges for a particular label, we invert 
that range, and intersect that inversion with the current "default:" ranges to 
determine the default case.   In this testcase, one label has all possible values, so the 
label was producing VARYING.  inverting that value was causing a trap.

This patch simple checks for VARYING and sets the default ranges to UNDEFINED 
in this case.
Is that correct?  The VARYING is not necessarily precise so „the rest“ should 
be VARYING as well?  That said, I don’t think you can use invert and intersect 
to compute the default case range.
The varying *is* precise. It only comes up with varying if all the precise 
values on each edge unioned together  come out to varying.   in this case, 
boolean true and false. proiduces varying, leaving nothing for the default 
cause.
It never gets VARYING because too many incoming edges and thus conservatively 
merging subranges?  I would doubt ranger can do precise ranges this way.  1 and 
5 are conservatively [1, 5] but the inversion does not include 2 and thus is 
not conservative.

Richard

No, that does not happen,at least it should not.  If we have too many
edges to process (-param=vrp-switch-limit=) , we do not process the
switch at all.  The limit is because processing massive numbers of
subranges can get expensive and ceases to be worthwhile after a while .

we've generated the range for default this way since gcc12 at least.
Default starts with VARYING, and as we process each edge, we add the
ranges on the edge to the destination case, and remove those ranges from
the default case  (hence invert and intersect).   At the end, the range
for default contains all the ranges that do not reach a case label.
OK, so I looked and the important detail seems to be that we use int_range_max
which actually has no "max" number of sub-ranges but dynamically grows, allowing
for "exact" operation (assuming union and intersect never "give up" themselves).

Richard.


By design virtually all internal routines use int_range_max so that any incoming ranges (which themselves may be an int_range_max) can retain and utilize whatever precision they we're given.

Andrew

Reply via email to