https://gcc.gnu.org/bugzilla/show_bug.cgi?id=32073
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Note there is a few things here that can be improved even more. With a slightly different testcase: void short_loop(int* __restrict dest, int* __restrict src, int count) { // same happens for assert(count <= 4) and if(count > 4) exit(-1) if(count > 4) count = 4; for(int i=0; i < count; i++) dest[i] = src[i] + 1; } In VRP2 we have: _5 = MIN_EXPR <count_10(D), 4>; if (count_10(D) > 0) goto <bb 3>; [80.00%] else goto <bb 9>; [20.00%] <bb 3> [local count: 171798694]: _23 = (unsigned int) _5; niters.4_24 = _5 > 0 ? _23 : 1; Which we don't optimize niters.4_24 to just _23. Without the +1 we optimize the above to memcpy (and still have the above issue too) and the expansion there needs help (which I thought I filed as another bug but I can't find it). There might be other issues where the vectorizer and such don't see that the count <= 4 and count >= 1.