https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81088
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- And the issue is that associate: ... /* Only do something if we found more than two objects. Otherwise, nothing has changed and we risk infinite recursion. */ if (ok && (2 < ((var0 != 0) + (var1 != 0) + (con0 != 0) + (con1 != 0) + (lit0 != 0) + (lit1 != 0) + (minus_lit0 != 0) + (minus_lit1 != 0)))) { bool any_overflows = false; if (lit0) any_overflows |= TREE_OVERFLOW (lit0); if (lit1) any_overflows |= TREE_OVERFLOW (lit1); ... /* Don't introduce overflows through reassociation. */ if (!any_overflows && ((lit0 && TREE_OVERFLOW_P (lit0)) || (minus_lit0 && TREE_OVERFLOW_P (minus_lit0)))) return NULL_TREE; fails to see the overflow when associating (1(OVF) - (int) s) + 2147483647 the 1(OVF) is from (int)0xffffffffU which is implementation defined but IIRC the FEs require the TREE_OVERFLOW flag to be set. IMHO this any_overflows code is simply bogus. To avoid dropping useful association split_tree should drop pre-existing TREE_OVERFLOW.