aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2007-11-09 12:49:55 +0000
committerEric Botcazou <ebotcazou@libertysurf.fr>2007-11-09 12:49:55 +0000
commit4922b63f26c1117f91a489523579f1c25b4782d0 (patch)
tree02eb0b8225223e9a89c38c461a3257d4c11bc7ce
parentad54e2495dab54b954f63529f2a2cd7bfe116dea (diff)
PR rtl-optimization/33732
* reload.c (push_reload): Check that the REG_DEAD note was referring to a hardreg or to a pseudo that has been assigned exactly one hardreg before considering it in order to select the reload register. (combine_reloads): Likewise. (find_dummy_reload): Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@130042 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/reload.c74
2 files changed, 49 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6dc7fedf38f..53c97771f9d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2007-11-09 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR rtl-optimization/33732
+ * reload.c (push_reload): Check that the REG_DEAD note was referring
+ to a hardreg or to a pseudo that has been assigned exactly one hardreg
+ before considering it in order to select the reload register.
+ (combine_reloads): Likewise.
+ (find_dummy_reload): Likewise.
+
2007-11-09 Richard Guenther <rguenther@suse.de>
* tree-flow.h (struct ptr_info_def): Make escape_mask a
diff --git a/gcc/reload.c b/gcc/reload.c
index 871f1718301..fd791b2d57f 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -1518,11 +1518,11 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
&& REG_P (XEXP (note, 0))
&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
&& reg_mentioned_p (XEXP (note, 0), in)
- /* Check that we don't use a hardreg for an uninitialized
- pseudo. See also find_dummy_reload(). */
+ /* Check that a former pseudo is valid; see find_dummy_reload. */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
- ORIGINAL_REGNO (XEXP (note, 0))))
+ || (!bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
+ ORIGINAL_REGNO (XEXP (note, 0)))
+ && hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1))
&& ! refers_to_regno_for_reload_p (regno,
end_hard_regno (rel_mode,
regno),
@@ -1678,7 +1678,7 @@ remove_address_replacements (rtx in_rtx)
static void
combine_reloads (void)
{
- int i;
+ int i, regno;
int output_reload = -1;
int secondary_out = -1;
rtx note;
@@ -1825,34 +1825,32 @@ combine_reloads (void)
for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_DEAD
&& REG_P (XEXP (note, 0))
- && ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
- rld[output_reload].out)
- && REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- && HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode)
+ && !reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
+ rld[output_reload].out)
+ && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
+ && HARD_REGNO_MODE_OK (regno, rld[output_reload].outmode)
&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
- REGNO (XEXP (note, 0)))
- && (hard_regno_nregs[REGNO (XEXP (note, 0))][rld[output_reload].outmode]
- <= hard_regno_nregs[REGNO (XEXP (note, 0))][GET_MODE (XEXP (note, 0))])
+ regno)
+ && (hard_regno_nregs[regno][rld[output_reload].outmode]
+ <= hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))])
/* Ensure that a secondary or tertiary reload for this output
won't want this register. */
&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1
- || (! (TEST_HARD_REG_BIT
- (reg_class_contents[(int) rld[secondary_out].class],
- REGNO (XEXP (note, 0))))
+ || (!(TEST_HARD_REG_BIT
+ (reg_class_contents[(int) rld[secondary_out].class], regno))
&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
- || ! (TEST_HARD_REG_BIT
- (reg_class_contents[(int) rld[secondary_out].class],
- REGNO (XEXP (note, 0)))))))
- && ! fixed_regs[REGNO (XEXP (note, 0))]
- /* Check that we don't use a hardreg for an uninitialized
- pseudo. See also find_dummy_reload(). */
+ || !(TEST_HARD_REG_BIT
+ (reg_class_contents[(int) rld[secondary_out].class],
+ regno)))))
+ && !fixed_regs[regno]
+ /* Check that a former pseudo is valid; see find_dummy_reload. */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR),
- ORIGINAL_REGNO (XEXP (note, 0)))))
+ || (!bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR),
+ ORIGINAL_REGNO (XEXP (note, 0)))
+ && hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1)))
{
rld[output_reload].reg_rtx
- = gen_rtx_REG (rld[output_reload].outmode,
- REGNO (XEXP (note, 0)));
+ = gen_rtx_REG (rld[output_reload].outmode, regno);
return;
}
}
@@ -1992,16 +1990,24 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
has a real mode. */
(GET_MODE (out) != VOIDmode
? GET_MODE (out) : outmode))
- /* But only do all this if we can be sure, that this input
- operand doesn't correspond with an uninitialized pseudoreg.
- global can assign some hardreg to it, which is the same as
- a different pseudo also currently live (as it can ignore the
- conflict). So we never must introduce writes to such hardregs,
- as they would clobber the other live pseudo using the same.
- See also PR20973. */
&& (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
- || ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
- ORIGINAL_REGNO (in))))
+ /* However only do this if we can be sure that this input
+ operand doesn't correspond with an uninitialized pseudo.
+ global can assign some hardreg to it that is the same as
+ the one assigned to a different, also live pseudo (as it
+ can ignore the conflict). We must never introduce writes
+ to such hardregs, as they would clobber the other live
+ pseudo. See PR 20973. */
+ || (!bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
+ ORIGINAL_REGNO (in))
+ /* Similarly, only do this if we can be sure that the death
+ note is still valid. global can assign some hardreg to
+ the pseudo referenced in the note and simultaneously a
+ subword of this hardreg to a different, also live pseudo,
+ because only another subword of the hardreg is actually
+ used in the insn. This cannot happen if the pseudo has
+ been assigned exactly one hardreg. See PR 33732. */
+ && hard_regno_nregs[REGNO (in)][GET_MODE (in)] == 1)))
{
unsigned int regno = REGNO (in) + in_offset;
unsigned int nwords = hard_regno_nregs[regno][inmode];