Regrename tends to fall on its face if multiword registers are accessed both in their full width and in subparts. However, there's one case where it's relatively easy to improve the current situation - when tracking a wide register, and it's written to in a narrower mode, we can just close the chain, mark it as non-renameable, and move every involved register to live_hardregs.
Bootstrapped and tested along with the earlier REG_DEAD patch. I've been testing these and other changes in a 4.5 C6X tree as well. Bernd
* regrename.c (scan_rtx_reg): Handle the case where we write to an open chain in a smaller mode without failing the entire block. Index: gcc/regrename.c =================================================================== --- gcc/regrename.c (revision 174842) +++ gcc/regrename.c (working copy) @@ -753,25 +721,34 @@ scan_rtx_reg (rtx insn, rtx *loc, enum r In either case, we remove this element from open_chains. */ if ((action == terminate_dead || action == terminate_write) - && superset) + && (superset || subset)) { unsigned nregs; head->terminated = 1; + if (subset) + head->cannot_rename = 1; head->next_chain = closed_chains; closed_chains = head; bitmap_clear_bit (&open_chains_set, head->id); nregs = head->nregs; while (nregs-- > 0) - CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs); + { + CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs); + if (subset + && (head->regno + nregs < this_regno + || head->regno + nregs >= this_regno + this_nregs)) + SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs); + } *p = next; if (dump_file) fprintf (dump_file, - "Closing chain %s (%d) at insn %d (%s)\n", + "Closing chain %s (%d) at insn %d (%s%s)\n", reg_names[head->regno], head->id, INSN_UID (insn), - scan_actions_name[(int) action]); + scan_actions_name[(int) action], + superset ? ", superset" : subset ? ", subset" : ""); } else if (action == terminate_dead || action == terminate_write) {