From: Richard Sandiford Date: Wed, 30 Jan 2008 11:18:27 +0000 (+0000) Subject: re PR rtl-optimization/34998 (gcc.c-torture/execute/20040709-1.c fails for -EL -mips1... X-Git-Tag: releases/gcc-4.3.0~329 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f36a5a8853c2407900cdc21b3a400130aa6f6dda;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 176a1372e662..f2021d2c51ad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2008-01-30 Richard Sandiford + + 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 * config/s390/fixdfdi.h (__fixunstfdi, __fixtfdi): Rearrange diff --git a/gcc/global.c b/gcc/global.c index b8a0ec781585..12641a60cba5 100644 --- a/gcc/global.c +++ b/gcc/global.c @@ -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]; diff --git a/gcc/ra-conflict.c b/gcc/ra-conflict.c index ce1dfdfcfb77..78d4f9246f07 100644 --- a/gcc/ra-conflict.c +++ b/gcc/ra-conflict.c @@ -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);