https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114331

--- Comment #5 from Andrew Macleod <amacleod at redhat dot com> ---
(In reply to Jakub Jelinek from comment #4)
> Actually, looking at value-range.h, irange_bitmask doesn't have just the
> mask but also value, so I wonder why it isn't able to figure this out.
> I'd think m_mask should be ~0xffff and value 111.

    _1 = (short int) num_5(D);
    _2 = (int) _1;
    switch (_1)

globally we know 
_2 : [irange] int [-32768, 32767]
and coming into bb 3:
_2 : [irange] int [-32768, 32767]
2->3      _1 :  [irange] short int [111, 111]
2->3      _2 :  [irange] int [111, 111]
2->3      num_5(D) :    [irange] int [-INF, -65537][-65425, -65425][111,
111][65536, +INF]

I guess what you are looking for is to add known bits to the range produced for
num_5 on the outgoing edge.

This would have to be done in operator_cast::op1_range  where we are reducing
it to known range of the switch.  I do not believe it makes any attempts to set
bitmasks based on casts like that currently.

so, GORI working backwards has _1 = [irange] short int [111, 111] , so it would
be satisfying the expression:
  short int [111, 111] = (short int) num_5(D);

when evaluating num_5 in operator_cast::op1_range, in the truncating_cast_p
section we could also see if there is a bitmask pattern for the LHS that could
be applied to the range..  I think that basically what you are asking for.  
Simple enough for a constant I suppose for starters.   Or maybe Aldy has a
routine that picks bitmasks and values from ranges somewhere?

Reply via email to