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; }