Here's an example of bad assumptions. The current code calculates the subreg location BEFORE checking to see if such a subreg is legal. This patch moved the legality check before the location calculations. With this patch, I can build gcc's libraries and newlib, but I haven't run full regressions on it yet.
Index: reload1.c =================================================================== --- reload1.c (revision 121130) +++ reload1.c (working copy) @@ -5653,7 +5653,16 @@ choose_reload_regs (struct insn_chain *c regno = subreg_regno (rld[r].in); #endif - if (regno >= 0 && reg_last_reload_reg[regno] != 0) + if (regno >= 0 + && reg_last_reload_reg[regno] != 0 +#ifdef CANNOT_CHANGE_MODE_CLASS + /* Verify that the register it's in can be used in + mode MODE. */ + && !REG_CANNOT_CHANGE_MODE_P (REGNO (reg_last_reload_reg[regno]), + GET_MODE (reg_last_reload_reg[regno]), + mode) +#endif + ) { enum reg_class class = rld[r].class, last_class; rtx last_reg = reg_last_reload_reg[regno]; @@ -5673,13 +5682,6 @@ choose_reload_regs (struct insn_chain *c if ((GET_MODE_SIZE (GET_MODE (last_reg)) >= GET_MODE_SIZE (need_mode)) -#ifdef CANNOT_CHANGE_MODE_CLASS - /* Verify that the register in "i" can be obtained - from LAST_REG. */ - && !REG_CANNOT_CHANGE_MODE_P (REGNO (last_reg), - GET_MODE (last_reg), - mode) -#endif && reg_reloaded_contents[i] == regno && TEST_HARD_REG_BIT (reg_reloaded_valid, i) && HARD_REGNO_MODE_OK (i, rld[r].mode)