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.

Reply via email to