From: Eric Botcazou Date: Fri, 9 Nov 2007 12:49:55 +0000 (+0100) Subject: re PR rtl-optimization/33732 (gcc.c-torture/execute/longlong.c execution at -O3) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=96cdfb52ff5c5ff9c7b73ef81b23fc1e637b925b;p=gcc.git 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 --- 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 + + 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 * 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];