From patchwork Wed Nov 7 22:11:58 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: patch to fix PR55122 Date: Wed, 07 Nov 2012 12:11:58 -0000 From: Vladimir Makarov X-Patchwork-Id: 197733 Message-Id: <509ADCAE.4060907@redhat.com> To: GCC Patches 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 PR rtl-optimization/55122 * lra-constraints.c (match_reload): Sync values for dead input pseudos. 2012-11-07 Vladimir Makarov 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; +}