summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-05 17:58:22 +0000
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-05 17:58:22 +0000
commitcdbf60c9b10cc26cc0db84078d0725de865fb09b (patch)
tree3587b9b99a17949bd6632984ba58cb5ef4ee7daa /gcc
parent69c554056b0b456f6b2dc57e5b3d96640de5d19e (diff)
downloadgcc-cdbf60c9b10cc26cc0db84078d0725de865fb09b.tar.gz
PR rtl-optimization/57708
* recog.c (peep2_find_free_register): Validate all regs in a multi-reg mode. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201501 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/recog.c64
2 files changed, 49 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a40d4a0afbf..eece522af1a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-08-05 Richard Earnshaw <rearnsha@arm.com>
+
+ PR rtl-optimization/57708
+ * recog.c (peep2_find_free_register): Validate all regs in a
+ multi-reg mode.
+
2013-08-05 Jan Hubicka <jh@suse.cz>
PR lto/57602
diff --git a/gcc/recog.c b/gcc/recog.c
index 6a607ba2a5a..aa026a27d59 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);