Testing on h8300, newlib/libm/math/ef_j0.c revealed a crash.

The problem is that PREV turned out to be unlinked when we came to 

                  fixup_args_size_notes (prev, PREV_INSN (next),
                                         INTVAL (XEXP (p, 0)));

I'm not sure how this didn't previously crash at

                fixup_eh_region_note (insn, prev, next);

Thanks to reload inheritance deleting insns out from under, I can't
think of any other mechanism than to have a marker note before INSN
that won't get deleted.

Comments?


r~

commit 90060c3e9508d3bd0c930ba13cbe3230c7ea0b8f
Author: Richard Henderson <r...@redhat.com>
Date:   Mon Aug 1 18:47:04 2011 -0700

    reload: Work around reload inheritence deleting insns.

diff --git a/gcc/reload1.c b/gcc/reload1.c
index 3233580..ba6ce37 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -4548,7 +4548,7 @@ reload_as_needed (int live_known)
 #if defined (AUTO_INC_DEC)
   int i;
 #endif
-  rtx x;
+  rtx x, marker;
 
   memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
   memset (spill_reg_store, 0, sizeof spill_reg_store);
@@ -4559,6 +4559,10 @@ reload_as_needed (int live_known)
 
   set_initial_elim_offsets ();
 
+  /* Generate a marker insn that we will move around.  */
+  marker = emit_note (NOTE_INSN_DELETED);
+  unlink_insn_chain (marker, marker);
+
   for (chain = reload_insn_chain; chain; chain = chain->next)
     {
       rtx prev = 0;
@@ -4631,7 +4635,10 @@ reload_as_needed (int live_known)
              rtx next = NEXT_INSN (insn);
              rtx p;
 
+             /* ??? PREV can get deleted by reload inheritance.
+                Work around this by emitting a marker note.  */
              prev = PREV_INSN (insn);
+             reorder_insns_nobb (marker, marker, prev);
 
              /* Now compute which reload regs to reload them into.  Perhaps
                 reusing reload regs from previous insns, or else output
@@ -4649,6 +4656,9 @@ reload_as_needed (int live_known)
                 and that we moved the structure into).  */
              subst_reloads (insn);
 
+             prev = PREV_INSN (marker);
+             unlink_insn_chain (marker, marker);
+
              /* Adjust the exception region notes for loads and stores.  */
              if (cfun->can_throw_non_call_exceptions && !CALL_P (insn))
                fixup_eh_region_note (insn, prev, next);

Reply via email to