re PR rtl-optimization/34998 (gcc.c-torture/execute/20040709-1.c fails for -EL -mips16 -O3)

gcc/
	PR rtl-optimization/34998
	* global.c (build_insn_chain): Treat non-subreg_lowpart
	SUBREGs of pseudos as clobbering all the words covered by the
	SUBREG, not just all the bytes.
	* ra-conflict.c (clear_reg_in_live): Likewise.  Take the
	original df_ref rather than an extract parameter.
	(global_conflicts): Update call accordingly.

From-SVN: r131960
This commit is contained in:
Richard Sandiford 2008-01-30 11:18:27 +00:00 committed by Richard Sandiford
parent 393c005884
commit f36a5a8853
3 changed files with 37 additions and 9 deletions

View File

@ -1,3 +1,13 @@
2008-01-30 Richard Sandiford <rsandifo@nildram.co.uk>
PR rtl-optimization/34998
* global.c (build_insn_chain): Treat non-subreg_lowpart
SUBREGs of pseudos as clobbering all the words covered by the
SUBREG, not just all the bytes.
* ra-conflict.c (clear_reg_in_live): Likewise. Take the
original df_ref rather than an extract parameter.
(global_conflicts): Update call accordingly.
2008-01-30 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): Rearrange

View File

@ -1501,6 +1501,17 @@ build_insn_chain (void)
live_subregs,
live_subregs_used,
regno, reg);
if (!DF_REF_FLAGS_IS_SET
(def, DF_REF_STRICT_LOWER_PART))
{
/* Expand the range to cover entire words.
Bytes added here are "don't care". */
start = start / UNITS_PER_WORD * UNITS_PER_WORD;
last = ((last + UNITS_PER_WORD - 1)
/ UNITS_PER_WORD * UNITS_PER_WORD);
}
/* Ignore the paradoxical bits. */
if ((int)last > live_subregs_used[regno])
last = live_subregs_used[regno];

View File

@ -441,16 +441,14 @@ ra_init_live_subregs (bool init_value,
/* Set REG to be not live in the sets ALLOCNOS_LIVE, LIVE_SUBREGS,
HARD_REGS_LIVE. If EXTRACT is false, assume that the entire reg is
set not live even if REG is a subreg. */
HARD_REGS_LIVE. DEF is the definition of the register. */
inline static void
clear_reg_in_live (sparseset allocnos_live,
sbitmap *live_subregs,
int *live_subregs_used,
HARD_REG_SET *hard_regs_live,
rtx reg,
bool extract)
rtx reg, struct df_ref *def)
{
unsigned int regno = (GET_CODE (reg) == SUBREG)
? REGNO (SUBREG_REG (reg)): REGNO (reg);
@ -458,8 +456,8 @@ clear_reg_in_live (sparseset allocnos_live,
if (allocnum >= 0)
{
if ((GET_CODE (reg) == SUBREG) && !extract)
if (GET_CODE (reg) == SUBREG
&& !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
{
unsigned int start = SUBREG_BYTE (reg);
unsigned int last = start + GET_MODE_SIZE (GET_MODE (reg));
@ -467,6 +465,15 @@ clear_reg_in_live (sparseset allocnos_live,
ra_init_live_subregs (sparseset_bit_p (allocnos_live, allocnum),
live_subregs, live_subregs_used, allocnum, reg);
if (!DF_REF_FLAGS_IS_SET (def, DF_REF_STRICT_LOWER_PART))
{
/* Expand the range to cover entire words.
Bytes added here are "don't care". */
start = start / UNITS_PER_WORD * UNITS_PER_WORD;
last = ((last + UNITS_PER_WORD - 1)
/ UNITS_PER_WORD * UNITS_PER_WORD);
}
/* Ignore the paradoxical bits. */
if ((int)last > live_subregs_used[allocnum])
last = live_subregs_used[allocnum];
@ -503,7 +510,8 @@ clear_reg_in_live (sparseset allocnos_live,
if (! fixed_regs[regno])
{
unsigned int start = regno;
if ((GET_CODE (reg) == SUBREG) && !extract)
if (GET_CODE (reg) == SUBREG
&& !DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT))
{
unsigned int last;
start += SUBREG_BYTE (reg);
@ -890,8 +898,7 @@ global_conflicts (void)
rtx reg = DF_REF_REG (def);
clear_reg_in_live (allocnos_live, live_subregs, live_subregs_used,
&hard_regs_live, reg,
DF_REF_FLAGS_IS_SET (def, DF_REF_EXTRACT));
&hard_regs_live, reg, def);
if (dump_file)
dump_ref (dump_file, " clearing def", "\n",
reg, DF_REF_REGNO (def), live_subregs, live_subregs_used);