On Tuesday 21 March 2006 17:15, Jeffrey A Law wrote: > On Tue, 2006-03-21 at 10:14 +0100, Duncan Sands wrote: > > > Hi Jeff, on the subject of seeing through typecasts, I was playing around > > with VRP and noticed that the following "if" statement is not eliminated: > > > > int u (unsigned char c) { > > int i = c; > > > > if (i < 0 || i > 255) > > return -1; /* never taken */ > > else > > return 0; > > } > > > > Is it supposed to be? > Depends... > > The "problem" is the parameter is marked a VR_VARYING (as it > should be).
Should it be? I was surprised to see that all ranges are initialised to VR_VARYING in the vrp pass, since many types have natural ranges associated with them, for example [0, 255] for the above unsigned char; starting off with this natural range is, well, natural, and surely simplifies a bunch of code, by making things more uniform, eg: no need to special case unsigned values, type conversions, ... > Unfortunately, the VR_VARYING source operand prevents > us from extracting a range for the result of the typecast. > > Sigh. We've got this "interesting" problem in VRP, namely that > we can sometimes extract ranges for operations on VR_VARYING > objects, but generally we punt. To compensate we often create > a range, say 0..MAXINT for an unsigned object -- that's effectively > a VARYING range, but the rest of VRP doesn't pessimize so much > when presented with 0..MAXINT vs VARYING. > > If we weren't so pessimistic with VR_VARYING or we always created > ranges, even if they cover TYPE_MIN .. TYPE_MAX then this wouldn't > be a problem. > > I'll see what I can cobble together... That would be great. All the best, Duncan.