https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114331
--- Comment #6 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- (In reply to Andrew Macleod from comment #5) > (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? You may want to look at: // Return the bitmask inherent in the range. irange_bitmask irange::get_bitmask_from_range () const { } IIRC, this code was originally authored by Jakub and was embedded in the tree-ssanames.cc code setting nonzero bits every time we set a global range. I just abstracted it and adapted it to work within our framework.