https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109564
--- Comment #14 from Richard Biener <rguenth at gcc dot gnu.org> --- I think the issue is a bit more involved - when _1 = PHI <_2, _3> and _2 is UNDEFINED _on the edge!_, the equivalence _1 == _3 only holds when the condition making _2 UNDEFINED holds. Trivially that's for all blocks dominated by that edge but that's exactly zero blocks (unless it's a backedge but that would likely have other issues). Now, when the edge was proven to be not executable the story is different I think - still the equivalence then only holds for blocks dominated by the PHI. So we can replace _1 with _3 but not _3 with _1 outside of such region. The bottom line is equivalences derived from PHIs are conditional (not global), much like equivalences derived from if (_1 == _2) are. But somehow they end up being used differently: Optimizing block #12 1>>> STMT 1 = _3 le_expr -65536 1>>> STMT 1 = _3 ge_expr -65536 1>>> STMT 1 = _3 eq_expr -65536 1>>> STMT 0 = _3 ne_expr -65536 0>>> COPY _3 = -65536 Optimizing statement if (_1 != -65536) 226 range_of_expr(_1) at stmt if (_1 != -65536) 227 range_on_entry (_1) to BB 12 228 range_of_stmt (_1) at stmt _1 = *spec_16(D).state_size; TRUE : (228) cached (_1) [irange] long int VARYING _1 : CACHE: BB 12 DOM query for _1, found [irange] long int [-65536, -65536][1, 1600] at BB5 CACHE: Range for DOM returns : [irange] long int [-65536, -65536][1, 1600] Filled from dominator! : [irange] long int [-65536, -65536][1, 1600] good sofar, but then: Checking Equivalence ( == ) state_size_8 CACHE: BB 12 DOM query for state_size_8, found [irange] long int [1, 1600] NONZERO 0x7ff at BB5 CACHE: Range for DOM returns : [irange] long int [1, 1600] NONZERO 0x7ff Equivalence update! : state_size_8 has range : [irange] long int [1, 1600] NONZERO 0x7ff refining range to :[irange] long int [1, 1600] NONZERO 0x7ff oops.