The following patch fixes http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55122
The problem was in generation of reload pseudo for matching operands with uniq value which prevented to assign the same hard register for the reload pseudo and the original input pseudo when the choice of hard regs was quite small (AD regs).
The patch was successfully bootstrapped and tested on x86/x86-64. Committed as rev. 193310. 2012-11-07 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/55122 * lra-constraints.c (match_reload): Sync values for dead input pseudos. 2012-11-07 Vladimir Makarov <vmaka...@redhat.com> PR rtl-optimization/55122 * gcc.dg/pr55122.c: New test.
Index: lra-constraints.c =================================================================== --- lra-constraints.c (revision 193303) +++ lra-constraints.c (working copy) @@ -682,6 +682,11 @@ match_reload (signed char out, signed ch new_out_reg = gen_lowpart_SUBREG (outmode, reg); else new_out_reg = gen_rtx_SUBREG (outmode, reg, 0); + /* If the input reg is dying here, we can use the same hard + register for REG and IN_RTX. */ + if (REG_P (in_rtx) + && find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))) + lra_reg_info[REGNO (reg)].val = lra_reg_info[REGNO (in_rtx)].val; } else { @@ -698,6 +703,19 @@ match_reload (signed char out, signed ch it at the end of LRA work. */ clobber = emit_clobber (new_out_reg); LRA_TEMP_CLOBBER_P (PATTERN (clobber)) = 1; + if (GET_CODE (in_rtx) == SUBREG) + { + rtx subreg_reg = SUBREG_REG (in_rtx); + + /* If SUBREG_REG is dying here and sub-registers IN_RTX + and NEW_IN_REG are similar, we can use the same hard + register for REG and SUBREG_REG. */ + if (REG_P (subreg_reg) && GET_MODE (subreg_reg) == outmode + && SUBREG_BYTE (in_rtx) == SUBREG_BYTE (new_in_reg) + && find_regno_note (curr_insn, REG_DEAD, REGNO (subreg_reg))) + lra_reg_info[REGNO (reg)].val + = lra_reg_info[REGNO (subreg_reg)].val; + } } } else Index: testsuite/gcc.dg/pr55122.c =================================================================== --- testsuite/gcc.dg/pr55122.c (revision 0) +++ testsuite/gcc.dg/pr55122.c (working copy) @@ -0,0 +1,14 @@ +/* PR rtl-optimization/55122 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int i, a; +unsigned long long b; + +void f(void) +{ + for(i = 0; i < 15; i++) + b *= b; + + b *= a ? 0 : b; +}