------- Comment #2 from matz at gcc dot gnu dot org  2007-11-22 04:26 -------
The problem starts already in the first iteration:
Value numbering destptr_3 stmt = destptr_3 = PHI <dest_9(6), destptr_14(7)>
Setting value number of destptr_3 to dest_9

So, for now we assume dest_9 == destptr_3, quite okay, lets assume so.  Next
statement:
Value numbering destptr.2_15 stmt = destptr.2_15 = (int) destptr_3;
Setting value number of destptr.2_15 to destptr.2_15

Looks innocent, but what this actually does is entering the RHS
((int)destptr_3) into the unary hash-table, but with translated (!) ssa names,
ergo it enters (int)dest_9 into the hashtable, as having destptr.2_15 as
value.  I.e. (int)dest_9 == destptr.2_15.  From there on everything breaks
apart, because nobody is ever removing this association from the hash-table.

So, from then on, whenever we are going to process this insn:
Value numbering dest.3_16 stmt = dest.3_16 = (int) dest_9;
Setting value number of dest.3_16 to destptr.2_15

We are looking up "(int)dest_9" in the unary hash-table, find it, see it's
associated value destptr.2_15 in there and happily use it.  Even in the later
iterations where the initial dest_9 == destptr_3 association isn't generated
anymore.  But the hashtable still contains the (then invalid) RHS (int)dest_9.

So, during the optimistic iterations we come to a fix point, but a completely
wrong one.  In particular we still (wrongly) think that nitems_19 is zero.  As
the valid_info only iterates once over the SCC this isn't enough to fix the
problem.  It has a clean hash-table again, so the above breakage isn't
reintroduced, but as it started with wrong info it still is wrong afterwards
(in particular when it sees that nitems_19 is not zero it won't reiterate).

This can be worked around with also iterating until nothing changes with
the new hash table (with valid_info).  That's obviously not what is wanted,
so there has to be a way to either cleanup the hashtable after iterations
(this also doesn't seem to be designed in this way), or to not enter
information into the hash tables which might become invalid in later
iterations.

The reason for inserting the translated expressions into the hash table
obviously is for optimization purposes (so that we are sure we have a canonical
version in it), but this canonicalization needs to happen when looking up
the hash table, not when _inserting_ into it, as canonicalization is transient
and changes from iteration to iteration.

Proof of concept patch fixing only the unary case (and hence this particular
bug) comes.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34176

Reply via email to