------- Comment #4 from abel at gcc dot gnu dot org 2009-04-21 14:16 ------- What happens in the test is that when pipelining, after several consecutive substitutions we end up with moving expressions r64=r16-r16 and r64=r16-r51 through r16=r51, after which both expressions become r64=r51-r51, as a result of substitution. When merging these expressions, we hit an assert in insert_in_history_vect.
This assert tries to describe the situations when earlier different, and now same expressions would have similar entries in their history of changes vector, i.e. somewhere on their way up they were transformed on the same insn. The main thing in the assert is that both expressions are supposed to be equal before this transformation was recorded. Now we have a test case when this is not the case. I presume that we didn't hit this before because the situations like ' b = c; a = b - c; ' are quite rare. We have two choices: either to extend the assert to cover this case or to remove it completely. If we'd extend it, then the assert becomes not very useful, as it basically says that all variations in the above situation are possible. So I'm inclined just to remove it. This would not hurt correctness, only in extreme rare situations like this we'd not be able to find both expressions to move them up, but only the one, as history vector has a single entry per uid, and thus we'd be unable to perform unification. So I will bootstrap/regtest the below patch. Index: gcc/sel-sched-ir.c =================================================================== *** gcc/sel-sched-ir.c (revision 146520) --- gcc/sel-sched-ir.c (working copy) *************** insert_in_history_vect (VEC (expr_histor *** 1512,1525 **** { expr_history_def *phist = VEC_index (expr_history_def, vect, ind); - /* When merging, either old vinsns are the *same* or, if not, both - old and new vinsns are different pointers. In the latter case, - though, new vinsns should be equal. */ - gcc_assert (phist->old_expr_vinsn == old_expr_vinsn - || (phist->new_expr_vinsn != new_expr_vinsn - && (vinsn_equal_p - (phist->old_expr_vinsn, old_expr_vinsn)))); - /* It is possible that speculation types of expressions that were propagated through different paths will be different here. In this case, merge the status to get the correct check later. */ -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39580