Fix sched REG_DEAD note handling bug found by post-reload-flow pass.
authorJim Wilson <wilson@cygnus.com>
Thu, 29 Oct 1998 19:06:48 +0000 (19:06 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Thu, 29 Oct 1998 19:06:48 +0000 (11:06 -0800)
* sched.c (update_flow_info): Add code to ! found_orig_dest case to
handle deleted no-op moves of hard registers.
* haifa-sched.c (update_flow_info): Likewise.

From-SVN: r23431

gcc/ChangeLog
gcc/haifa-sched.c
gcc/sched.c

index b67825de419f17efb48b314179273eb4c079347a..22c38bc8c115adc0278e0d9ff861890cecc26957 100644 (file)
@@ -1,3 +1,9 @@
+Thu Oct 29 19:05:17 1998  Jim Wilson  <wilson@cygnus.com>
+
+       * sched.c (update_flow_info): Add code to ! found_orig_dest case to
+       handle deleted no-op moves of hard registers.
+       * haifa-sched.c (update_flow_info): Likewise.
+
 Thu Oct 29 18:07:47 1998  Jeffrey A Law  (law@cygnus.com)
 
        * mips.md (reload_{in,out}{si,di}): Emit a USE of HILO at the end
index 806bb396d8864142f219249a4aea64e9e47a9c6b..ea043907262356bbdd3643d90fa777585698ff08 100644 (file)
@@ -8340,8 +8340,28 @@ update_flow_info (notes, first, last, orig_insn)
        }
       else if (!found_orig_dest)
        {
-         /* This should never happen.  */
-         abort ();
+         int i, regno;
+
+         /* Should never reach here for a pseudo reg.  */
+         if (REGNO (orig_dest) >= FIRST_PSEUDO_REGISTER)
+           abort ();
+
+         /* This can happen for a hard register, if the splitter
+            does not bother to emit instructions which would be no-ops.
+            We try to verify that this is the case by checking to see if
+            the original instruction uses all of the registers that it
+            set.  This case is OK, because deleting a no-op can not affect
+            REG_DEAD notes on other insns.  If this is not the case, then
+            abort.  */
+         
+         regno = REGNO (orig_dest);
+         for (i = HARD_REGNO_NREGS (regno, GET_MODE (orig_dest)) - 1;
+              i >= 0; i--)
+           if (! refers_to_regno_p (regno + i, regno + i + 1, orig_insn,
+                                    NULL_PTR))
+             break;
+         if (i >= 0)
+           abort ();
        }
     }
 
index 1d81407c3f4298ea3d427e686d16a7edd8673c7d..e27f70e28eaa36ea11944e770e81da969dffe303 100644 (file)
@@ -4174,8 +4174,28 @@ update_flow_info (notes, first, last, orig_insn)
        }
       else if (! found_orig_dest)
        {
-         /* This should never happen.  */
-         abort ();
+         int i, regno;
+
+         /* Should never reach here for a pseudo reg.  */
+         if (REGNO (orig_dest) >= FIRST_PSEUDO_REGISTER)
+           abort ();
+
+         /* This can happen for a hard register, if the splitter
+            does not bother to emit instructions which would be no-ops.
+            We try to verify that this is the case by checking to see if
+            the original instruction uses all of the registers that it
+            set.  This case is OK, because deleting a no-op can not affect
+            REG_DEAD notes on other insns.  If this is not the case, then
+            abort.  */
+         
+         regno = REGNO (orig_dest);
+         for (i = HARD_REGNO_NREGS (regno, GET_MODE (orig_dest)) - 1;
+              i >= 0; i--)
+           if (! refers_to_regno_p (regno + i, regno + i + 1, orig_insn,
+                                    NULL_PTR))
+             break;
+         if (i >= 0)
+           abort ();
        }
     }