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

Reply via email to