https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45397
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Target Milestone|5.5 |7.0 --- Comment #22 from Richard Biener <rguenth at gcc dot gnu.org> --- I think the pattern to identify is the *tmp + val saturating addition. One of the issues is that we have tmp[i] + val in two forms: _5 = (int)tmp[i] + val; and _iftmp.1_13 = (int)(tmp[i] + (unsigned char)val); where the latter is guarded with an overflow check (_5 <= 255 && _5 >= 0). IMHO the unfortunate thing is that we arrive with this inconsistent narrowing here in the first place before we had a chance to clean things up. Of course as Jakub notices in comment#1 the user could have written this in this way. And _only_ if the no-overflow condition holds are the two expressions the same (contrary to Jakubs example that compares both values as unsigned char). As suggested above we may want to do "saturated OP" pattern matching here and then re-expand in more optimal form (using min/max as suggested or using an IFN like we have for the overflow cases). Another option is to teach VRP to detect the equivalence (but that looks hard and even more ad-hoc). As for using CSE in some way it would need to see the range of _5 and conditionally add (int)(unsigned char)expr-of-_5 simplified and hope things get detected that way... (but first of all it would need a value-range lattice). So the only "reasonable" suggestion is pattern matching the whole thing which fits phiopt. I do not think that having a 'widening' general pattern is the way to go. That has the same issues as the current narrowing one. Moving down the narrowing optimization from the FEs folding code is a step in the right direction anyway (but it would need putting elsewhere to not "regress"). I think that all but maybe a saturating-OP replacement in phiopt is GCC 8 material. Adjusting target milestone to GCC 7 meanwhile.