diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cse.c | 25 |
2 files changed, 22 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ae3918f66d6..d2d03983631 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2002-09-04 Richard Henderson <rth@redhat.com> + + * cse.c (cse_insn): Avoid subreg games if the equivalence + is already in the proper mode. + 2002-09-04 Eric Botcazou <ebotcazou@multimania.com> PR c/7102 diff --git a/gcc/cse.c b/gcc/cse.c index afdc8daa8b0..7f0365aa173 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -6203,14 +6203,23 @@ cse_insn (insn, libcall_insn) && ! exp_equiv_p (elt->exp, elt->exp, 1, 0)) continue; - /* Calculate big endian correction for the SUBREG_BYTE - (or equivalent). We have already checked that M1 - ( GET_MODE (dest) ) is not narrower than M2 (new_mode). */ - if (BYTES_BIG_ENDIAN) - byte = (GET_MODE_SIZE (GET_MODE (dest)) - - GET_MODE_SIZE (new_mode)); - new_src = simplify_gen_subreg (new_mode, elt->exp, - GET_MODE (dest), byte); + /* We may have already been playing subreg games. If the + mode is already correct for the destination, use it. */ + if (GET_MODE (elt->exp) == new_mode) + new_src = elt->exp; + else + { + /* Calculate big endian correction for the SUBREG_BYTE. + We have already checked that M1 (GET_MODE (dest)) + is not narrower than M2 (new_mode). */ + if (BYTES_BIG_ENDIAN) + byte = (GET_MODE_SIZE (GET_MODE (dest)) + - GET_MODE_SIZE (new_mode)); + + new_src = simplify_gen_subreg (new_mode, elt->exp, + GET_MODE (dest), byte); + } + /* The call to simplify_gen_subreg fails if the value is VOIDmode, yet we can't do any simplification, e.g. for EXPR_LISTs denoting function call results. |