re PR rtl-optimization/33732 (gcc.c-torture/execute/longlong.c execution at -O3)

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.

From-SVN: r130042
This commit is contained in:
Eric Botcazou 2007-11-09 13:49:55 +01:00 committed by Eric Botcazou
parent 91a17a346e
commit 96cdfb52ff
2 changed files with 49 additions and 34 deletions

View File

@ -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

View File

@ -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];