Hi, This patch is to address the problem described here: http://gcc.gnu.org/ml/gcc/2013-09/msg00187.html
The patch changes ALLOCNO_MODE of a pseudo reg to be outermode if the pseudo reg is used in a paradoxical subreg, so IRA will not mistakenly assign an operand with a bigger mode to a smaller hardreg which couldn't find a pair register. No test is added because I cannot create a small testcase to reproduce the problem on trunk, the difficulty of which was described in the above post. bootstrap and regression pass. ok for trunk? Thanks, Wei Mi. 2013-09-24 Wei Mi <w...@google.com> * ira-build.c (create_insn_allocnos): Fix ALLOCNO_MODE in the case of paradoxical subreg. Index: ira-build.c =================================================================== --- ira-build.c (revision 201963) +++ ira-build.c (working copy) @@ -1688,6 +1688,30 @@ create_insn_allocnos (rtx x, bool output } return; } + else if (code == SUBREG) + { + int regno; + rtx subreg_reg = SUBREG_REG (x); + enum machine_mode outermode, innermode; + + create_insn_allocnos (subreg_reg, output_p); + /* For paradoxical subreg, set allocno's mode to be + the outermode. */ + outermode = GET_MODE (x); + innermode = GET_MODE (subreg_reg); + if (REG_P (subreg_reg) + && (GET_MODE_SIZE (outermode) > GET_MODE_SIZE (innermode))) + { + regno = REGNO (subreg_reg); + if (regno >= FIRST_PSEUDO_REGISTER) + { + ira_allocno_t a = ira_curr_regno_allocno_map[regno]; + ira_assert (a != NULL); + ALLOCNO_MODE (a) = outermode; + } + } + return; + } else if (code == SET) { create_insn_allocnos (SET_DEST (x), true);