https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85929
--- Comment #1 from Marc Glisse <glisse at gcc dot gnu.org> --- With size_type = unsigned long, the bounds check turns out to be exactly the same test as the loop exit check, and FRE3 gets rid of it. With size_type = unsigned int, it is harder. We have roughly long int _16; unsigned int i; count_8 = (unsigned int) _16; if (i_4 >= count_8) [... else branch] _1 = (long unsigned int) i_4; _21 = (long unsigned int) _16; if (_1 >= _21) It is true that i < (unsigned)_16 implies (unsigned long)i < (unsigned long)_16, though that's clearly not an equivalence. So the transformation should be possible, but I am not sure how to fit it into FRE (or anywhere).