&& 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),
static void
combine_reloads (void)
{
- int i;
+ int i, regno;
int output_reload = -1;
int secondary_out = -1;
rtx note;
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;
}
}
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];