From: Richard Earnshaw Date: Mon, 5 Aug 2013 17:58:22 +0000 (+0000) Subject: re PR rtl-optimization/57708 (function clobbers callee saved register on ARM) X-Git-Tag: releases/gcc-4.9.0~4705 X-Git-Url: https://gcc.gnu.org/git/?a=commitdiff_plain;h=d0b2f8311e5e1917464aa4f65d506fbe4e580eb1;p=gcc.git re PR rtl-optimization/57708 (function clobbers callee saved register on ARM) PR rtl-optimization/57708 * recog.c (peep2_find_free_register): Validate all regs in a multi-reg mode. From-SVN: r201501 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a40d4a0afbf8..eece522af1a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-08-05 Richard Earnshaw + + PR rtl-optimization/57708 + * recog.c (peep2_find_free_register): Validate all regs in a + multi-reg mode. + 2013-08-05 Jan Hubicka PR lto/57602 diff --git a/gcc/recog.c b/gcc/recog.c index 6a607ba2a5af..aa026a27d599 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -3124,32 +3124,53 @@ peep2_find_free_register (int from, int to, const char *class_str, regno = raw_regno; #endif - /* Don't allocate fixed registers. */ - if (fixed_regs[regno]) - continue; - /* Don't allocate global registers. */ - if (global_regs[regno]) - continue; - /* Make sure the register is of the right class. */ - if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno)) - continue; - /* And can support the mode we need. */ + /* Can it support the mode we need? */ if (! HARD_REGNO_MODE_OK (regno, mode)) continue; - /* And that we don't create an extra save/restore. */ - if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno)) - continue; - if (! targetm.hard_regno_scratch_ok (regno)) - continue; - - /* And we don't clobber traceback for noreturn functions. */ - if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM) - && (! reload_completed || frame_pointer_needed)) - continue; success = 1; - for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--) + for (j = 0; success && j < hard_regno_nregs[regno][mode]; j++) { + /* Don't allocate fixed registers. */ + if (fixed_regs[regno + j]) + { + success = 0; + break; + } + /* Don't allocate global registers. */ + if (global_regs[regno + j]) + { + success = 0; + break; + } + /* Make sure the register is of the right class. */ + if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j)) + { + success = 0; + break; + } + /* And that we don't create an extra save/restore. */ + if (! call_used_regs[regno + j] && ! df_regs_ever_live_p (regno + j)) + { + success = 0; + break; + } + + if (! targetm.hard_regno_scratch_ok (regno + j)) + { + success = 0; + break; + } + + /* And we don't clobber traceback for noreturn functions. */ + if ((regno + j == FRAME_POINTER_REGNUM + || regno + j == HARD_FRAME_POINTER_REGNUM) + && (! reload_completed || frame_pointer_needed)) + { + success = 0; + break; + } + if (TEST_HARD_REG_BIT (*reg_set, regno + j) || TEST_HARD_REG_BIT (live, regno + j)) { @@ -3157,6 +3178,7 @@ peep2_find_free_register (int from, int to, const char *class_str, break; } } + if (success) { add_to_hard_reg_set (reg_set, mode, regno);