Hi! find_removable_extensions/add_removable_extensions was storing pointers into the *insn_list vector in def_map array. Unfortunately when the vector is reallocated, this may result in all the pointers pointing into freed memory. Detected by valgrind, fixed by instead just storing the vector indexes (+ 1, so that 0 means former NULL), bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
For 4.8 I think the def_map array could be dropped altogether, now that we keep the UD/DU links, but this change looks smaller and safer. 2012-01-31 Jakub Jelinek <ja...@redhat.com> PR bootstrap/52041 PR bootstrap/52039 PR target/51974 * ree.c (add_removable_extension): Change def_map argument to unsigned *, store in def_map 1 + offset into *insn_list vector instead of pointers into the vector. (find_removable_extensions): Adjust caller. --- gcc/ree.c.jj 2012-01-30 00:10:01.205444366 +0100 +++ gcc/ree.c 2012-01-30 22:54:00.864425203 +0100 @@ -747,10 +747,11 @@ combine_reaching_defs (ext_cand *cand, c static void add_removable_extension (const_rtx expr, rtx insn, VEC (ext_cand, heap) **insn_list, - ext_cand **def_map) + unsigned *def_map) { enum rtx_code code; enum machine_mode mode; + unsigned int idx; rtx src, dest; /* We are looking for SET (REG N) (ANY_EXTEND (REG N)). */ @@ -786,7 +787,8 @@ add_removable_extension (const_rtx expr, /* Second, make sure the reaching definitions don't feed another and different extension. FIXME: this obviously can be improved. */ for (def = defs; def; def = def->next) - if ((cand = def_map[INSN_UID(DF_REF_INSN (def->ref))]) + if ((idx = def_map[INSN_UID(DF_REF_INSN (def->ref))]) + && (cand = VEC_index (ext_cand, *insn_list, idx - 1)) && (cand->code != code || cand->mode != mode)) { if (dump_file) @@ -805,9 +807,10 @@ add_removable_extension (const_rtx expr, cand->code = code; cand->mode = mode; cand->insn = insn; + idx = VEC_length (ext_cand, *insn_list); for (def = defs; def; def = def->next) - def_map[INSN_UID(DF_REF_INSN (def->ref))] = cand; + def_map[INSN_UID(DF_REF_INSN (def->ref))] = idx; } } @@ -820,7 +823,7 @@ find_removable_extensions (void) VEC (ext_cand, heap) *insn_list = NULL; basic_block bb; rtx insn, set; - ext_cand **def_map = XCNEWVEC (ext_cand *, max_insn_uid); + unsigned *def_map = XCNEWVEC (unsigned, max_insn_uid); FOR_EACH_BB (bb) FOR_BB_INSNS (bb, insn) Jakub