------- 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