https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66678
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to vries from comment #2) > Created attachment 35878 [details] > tentative patch That single-use case is awfully special ... just add an unrelated use to the function and we no longer optimize again. The real issue with VRP is that given an assert-expr we have no chance to record multiple ranges via equivalences because equivalences are still tied to SSA defs. The same issue pops up for other cases. So instead of hacking in single-use special-casing we should rather fix that deficiency... A possible different way to represent equivalences is to not tie value-ranges directly to SSA names (by indexing the array with their SSA_NAME_VERSION) but instead introduce an indirection and thus allow arbitrary new value-ranges to be stored. So instead of static value_range_t **vr_value; have vec<value_range_t> values; static unsigned *vr_value; and thus get_value_range doing unsigned ver = SSA_NAME_VERSION (var); return &values[vr_value[ver]]; and make equivalences a bitmap of indexes into 'values' instead of SSA_NAME_VERSIONs. Then you can always record both ranges from the assert (thus keep both the symbolic and a constant range when you now have to decide for one)