This is a report of a crash in IRA. If you debug it with a sufficiently old compiler, you'll find that we manage to delete some basic blocks from within IRA. Later on, reload calls alter_reg for all unallocated pseudos, including one that only occurs in the deleted blocks. reload does not notice it is unused, because REG_N_REFS is still 3. We crash in an IRA callback because the pseudo has no allocno.

Fixed as below. A similar patch cures the problem in gcc-4.6. Adding a testcase seems pointless - the crashing code was derived from an existing Fortran testcase with exotic options, and the whole thing only ever triggered in one gcc version AFAICT. Current gcc can't trigger it because it's not using reload on x86_64.

Bootstrapped and tested on x86_64-linux, ok?


Bernd
	PR rtl-optimization/47992
	* ira.c (ira): Update regstat data if we deleted insns.

Index: gcc/ira.c
===================================================================
--- gcc/ira.c	(revision 232339)
+++ gcc/ira.c	(working copy)
@@ -5185,19 +5185,27 @@ ira (FILE *f)
   setup_reg_equiv ();
   setup_reg_equiv_init ();
 
+  bool update_regstat = false;
+
   if (optimize && rebuild_p)
     {
       timevar_push (TV_JUMP);
       rebuild_jump_labels (get_insns ());
       if (purge_all_dead_edges ())
-	delete_unreachable_blocks ();
+	{
+	  delete_unreachable_blocks ();
+	  update_regstat = true;
+	}
       timevar_pop (TV_JUMP);
     }
 
   allocated_reg_info_size = max_reg_num ();
 
   if (delete_trivially_dead_insns (get_insns (), max_reg_num ()))
-    df_analyze ();
+    {
+      df_analyze ();
+      update_regstat = true;
+    }
 
   /* It is not worth to do such improvement when we use a simple
      allocation because of -O0 usage or because the function is too
@@ -5308,7 +5316,7 @@ ira (FILE *f)
     check_allocation ();
 #endif
 
-  if (max_regno != max_regno_before_ira)
+  if (update_regstat || max_regno != max_regno_before_ira)
     {
       regstat_free_n_sets_and_refs ();
       regstat_free_ri ();

Reply via email to