This patch addresses an ICE when building qemu for a Mips target in
Yocto. Both gcc-trunk, gcc-4.8 and all of the targets are potentially
affected. The problem occurs because the instruction combine phase uses
two data structures to keep track of registers, reg_stat and
regstat_n_sets_and_refs, but they potentially end up out of sync; when
combine inserts a new register into reg_stat it does not update
regstat_n_sets_and_refs. Failing to update the latter results in an
occasional segmentation fault.

Is this OK for trunk and gcc-4.8? If so, please check it in. I tested it
on Mips and x86-64 and no regressions showed up.

Thanks,
Cesar
2013-10-10  Cesar Philippidis  <ce...@codesourcery.com>

        gcc/
        * regs.h (REG_N_GROW): New function. 
        * combine.c (combine_split_insns): Call REG_N_GROW when
        new registers are created.

Index: gcc/regs.h
===================================================================
--- gcc/regs.h  (revision 421441)
+++ gcc/regs.h  (working copy)
@@ -85,6 +85,17 @@ REG_N_SETS (int regno)
   return regstat_n_sets_and_refs[regno].sets;
 }
 
+/* Indexed by n, inserts a new register (REG n).  */
+static inline void
+REG_N_GROW (int regno)
+{
+  regstat_n_sets_and_refs = XRESIZEVEC (struct regstat_n_sets_and_refs_t, 
+                                       regstat_n_sets_and_refs, regno+1);
+
+  regstat_n_sets_and_refs[regno].sets = 1;
+  regstat_n_sets_and_refs[regno].refs = 1;
+}
+
 /* Indexed by n, gives number of times (REG n) is set.  */
 #define SET_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets = V)
 #define INC_REG_N_SETS(N,V) (regstat_n_sets_and_refs[N].sets += V)
Index: gcc/combine.c
===================================================================
--- gcc/combine.c       (revision 421441)
+++ gcc/combine.c       (working copy)
@@ -518,7 +518,10 @@ combine_split_insns (rtx pattern, rtx insn)
   ret = split_insns (pattern, insn);
   nregs = max_reg_num ();
   if (nregs > reg_stat.length ())
-    reg_stat.safe_grow_cleared (nregs);
+    {
+      reg_stat.safe_grow_cleared (nregs);
+      REG_N_GROW (nregs);
+    }
   return ret;
 }
 

Reply via email to