https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68963
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> --- Ok, I think the issue is really in record_nonwrapping_iv doing wide_int min, max; extreme = fold_convert (unsigned_type, high); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (low) == INTEGER_CST && INTEGRAL_TYPE_P (TREE_TYPE (orig_base)) && get_range_info (orig_base, &min, &max) == VR_RANGE && wi::gts_p (min, low)) base = wide_int_to_tree (unsigned_type, min); else if (TREE_CODE (base) != INTEGER_CST) base = fold_convert (unsigned_type, low); delta = fold_build2 (MINUS_EXPR, unsigned_type, extreme, base); and for the non-constant (no-range-info) base case simply assuming it's 'low' (the array types low bound). We can't simply treat low - base as zero and ignore those upfront iterations. If base were -1 then we'd correctly add 1 to the upper bound. Only if the stmt is always executed we can drop base to low (and we could do that always, not just if base is an INTEGER_CST, so we can have base = MIN (base, low) in that case - not at this time though). So, different patch in testing.