Commit 96cdfb52 by Eric Botcazou Committed by Eric Botcazou

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
parent 91a17a34
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> 2007-11-09 Richard Guenther <rguenther@suse.de>
* tree-flow.h (struct ptr_info_def): Make escape_mask a * tree-flow.h (struct ptr_info_def): Make escape_mask a
...@@ -1518,11 +1518,11 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, ...@@ -1518,11 +1518,11 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
&& REG_P (XEXP (note, 0)) && REG_P (XEXP (note, 0))
&& (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
&& reg_mentioned_p (XEXP (note, 0), in) && reg_mentioned_p (XEXP (note, 0), in)
/* Check that we don't use a hardreg for an uninitialized /* Check that a former pseudo is valid; see find_dummy_reload. */
pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
|| ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR), || (!bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (XEXP (note, 0)))) ORIGINAL_REGNO (XEXP (note, 0)))
&& hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1))
&& ! refers_to_regno_for_reload_p (regno, && ! refers_to_regno_for_reload_p (regno,
end_hard_regno (rel_mode, end_hard_regno (rel_mode,
regno), regno),
...@@ -1678,7 +1678,7 @@ remove_address_replacements (rtx in_rtx) ...@@ -1678,7 +1678,7 @@ remove_address_replacements (rtx in_rtx)
static void static void
combine_reloads (void) combine_reloads (void)
{ {
int i; int i, regno;
int output_reload = -1; int output_reload = -1;
int secondary_out = -1; int secondary_out = -1;
rtx note; rtx note;
...@@ -1825,34 +1825,32 @@ combine_reloads (void) ...@@ -1825,34 +1825,32 @@ combine_reloads (void)
for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1)) for (note = REG_NOTES (this_insn); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_DEAD if (REG_NOTE_KIND (note) == REG_DEAD
&& REG_P (XEXP (note, 0)) && REG_P (XEXP (note, 0))
&& ! reg_overlap_mentioned_for_reload_p (XEXP (note, 0), && !reg_overlap_mentioned_for_reload_p (XEXP (note, 0),
rld[output_reload].out) rld[output_reload].out)
&& REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER && (regno = REGNO (XEXP (note, 0))) < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_MODE_OK (REGNO (XEXP (note, 0)), rld[output_reload].outmode) && HARD_REGNO_MODE_OK (regno, rld[output_reload].outmode)
&& TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class], && TEST_HARD_REG_BIT (reg_class_contents[(int) rld[output_reload].class],
REGNO (XEXP (note, 0))) regno)
&& (hard_regno_nregs[REGNO (XEXP (note, 0))][rld[output_reload].outmode] && (hard_regno_nregs[regno][rld[output_reload].outmode]
<= hard_regno_nregs[REGNO (XEXP (note, 0))][GET_MODE (XEXP (note, 0))]) <= hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))])
/* Ensure that a secondary or tertiary reload for this output /* Ensure that a secondary or tertiary reload for this output
won't want this register. */ won't want this register. */
&& ((secondary_out = rld[output_reload].secondary_out_reload) == -1 && ((secondary_out = rld[output_reload].secondary_out_reload) == -1
|| (! (TEST_HARD_REG_BIT || (!(TEST_HARD_REG_BIT
(reg_class_contents[(int) rld[secondary_out].class], (reg_class_contents[(int) rld[secondary_out].class], regno))
REGNO (XEXP (note, 0))))
&& ((secondary_out = rld[secondary_out].secondary_out_reload) == -1 && ((secondary_out = rld[secondary_out].secondary_out_reload) == -1
|| ! (TEST_HARD_REG_BIT || !(TEST_HARD_REG_BIT
(reg_class_contents[(int) rld[secondary_out].class], (reg_class_contents[(int) rld[secondary_out].class],
REGNO (XEXP (note, 0))))))) regno)))))
&& ! fixed_regs[REGNO (XEXP (note, 0))] && !fixed_regs[regno]
/* Check that we don't use a hardreg for an uninitialized /* Check that a former pseudo is valid; see find_dummy_reload. */
pseudo. See also find_dummy_reload(). */
&& (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER && (ORIGINAL_REGNO (XEXP (note, 0)) < FIRST_PSEUDO_REGISTER
|| ! bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR), || (!bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR),
ORIGINAL_REGNO (XEXP (note, 0))))) ORIGINAL_REGNO (XEXP (note, 0)))
&& hard_regno_nregs[regno][GET_MODE (XEXP (note, 0))] == 1)))
{ {
rld[output_reload].reg_rtx rld[output_reload].reg_rtx
= gen_rtx_REG (rld[output_reload].outmode, = gen_rtx_REG (rld[output_reload].outmode, regno);
REGNO (XEXP (note, 0)));
return; return;
} }
} }
...@@ -1992,16 +1990,24 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc, ...@@ -1992,16 +1990,24 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
has a real mode. */ has a real mode. */
(GET_MODE (out) != VOIDmode (GET_MODE (out) != VOIDmode
? GET_MODE (out) : outmode)) ? 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 && (ORIGINAL_REGNO (in) < FIRST_PSEUDO_REGISTER
|| ! bitmap_bit_p (DF_LIVE_OUT (ENTRY_BLOCK_PTR), /* However only do this if we can be sure that this input
ORIGINAL_REGNO (in)))) 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 regno = REGNO (in) + in_offset;
unsigned int nwords = hard_regno_nregs[regno][inmode]; unsigned int nwords = hard_regno_nregs[regno][inmode];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment