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

Alexander Monakov <amonakov at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2011-09-06
                 CC|                            |abel at gcc dot gnu.org,
                   |                            |amonakov at gcc dot gnu.org
         AssignedTo|unassigned at gcc dot       |amonakov at gcc dot gnu.org
                   |gnu.org                     |
     Ever Confirmed|0                           |1

--- Comment #1 from Alexander Monakov <amonakov at gcc dot gnu.org> 2011-09-06 
11:17:47 UTC ---
We attempt to substitute an insn like (... (cmp (mem (reg:DI ax)) (reg:SI ax)))
(note different modes) through (set (reg:DI ax) (reg:DI dx)), which leaves the
(reg:SI ax) part of the comparison intact, causing an ICE later on when we
notice that the dependency on ax is still present.  As this is quite rare, we
can simply forbid substitution in such circumstances, much like substitution of
multiple hard reg references is forbidden now.  The patch I'm going to test:

diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index f11faca..2af01ae 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -813,18 +813,12 @@ count_occurrences_1 (rtx *cur_rtx, void *arg)
 {
   rtx_search_arg_p p = (rtx_search_arg_p) arg;

-  /* The last param FOR_GCSE is true, because otherwise it performs excessive
-    substitutions like
-    r8 = r33
-    r16 = r33
-    for the last insn it presumes r33 equivalent to r8, so it changes it to
-    r33.  Actually, there's no change, but it spoils debugging.  */
-  if (exp_equiv_p (*cur_rtx, p->x, 0, true))
-    {
-      /* Bail out if we occupy more than one register.  */
-      if (REG_P (*cur_rtx)
-          && HARD_REGISTER_P (*cur_rtx)
-          && hard_regno_nregs[REGNO(*cur_rtx)][GET_MODE (*cur_rtx)] > 1)
+  if (REG_P (*cur_rtx) && REGNO (*cur_rtx) == REGNO (p->x))
+    {
+      /* Bail out if mode is different or more than one register is used.  */
+      if (GET_MODE (*cur_rtx) != GET_MODE (p->x)
+          || (HARD_REGISTER_P (*cur_rtx)
+          && hard_regno_nregs[REGNO(*cur_rtx)][GET_MODE (*cur_rtx)] > 1))
         {
           p->n = 0;
           return 1;
@@ -837,7 +831,6 @@ count_occurrences_1 (rtx *cur_rtx, void *arg)
     }

   if (GET_CODE (*cur_rtx) == SUBREG
-      && REG_P (p->x)
       && (!REG_P (SUBREG_REG (*cur_rtx))
       || REGNO (SUBREG_REG (*cur_rtx)) == REGNO (p->x)))
     {
@@ -859,6 +852,7 @@ count_occurrences_equiv (rtx what, rtx where)
 {
   struct rtx_search_arg arg;

+  gcc_assert (REG_P (what));
   arg.x = what;
   arg.n = 0;

Reply via email to