diff options
author | Kaz Kojima <kkojima@gcc.gnu.org> | 2004-01-20 02:34:23 +0000 |
---|---|---|
committer | Kaz Kojima <kkojima@gcc.gnu.org> | 2004-01-20 02:34:23 +0000 |
commit | 26d107dba89128b74d968900bbb669b47879ba18 (patch) | |
tree | 333f34d67e325259f0ce4e6af2fd6b39e16501d1 /gcc | |
parent | 9dfcd6092ef71da399221e59d535c5b893390243 (diff) | |
download | gcc-26d107dba89128b74d968900bbb669b47879ba18.zip gcc-26d107dba89128b74d968900bbb669b47879ba18.tar.gz gcc-26d107dba89128b74d968900bbb669b47879ba18.tar.bz2 |
re PR rtl-optimization/13567 ([sh] miscompiling calls.c)
PR optimization/13567
* cse.c (cse_basic_block): Call cse_insn with a non-null
libcall_insn for the last SET insn of a no-confilict block.
From-SVN: r76195
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cse.c | 20 |
2 files changed, 24 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3b53c62..b12049b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2004-01-20 Kaz Kojima <kkojima@gcc.gnu.org> + + PR optimization/13567 + * cse.c (cse_basic_block): Call cse_insn with a non-null + libcall_insn for the last SET insn of a no-confilict block. + 2004-01-20 Kelley Cook <kcook@gcc.gnu.org> * Makefile.in (target_noncanonical, program_transform_name): Use @@ -1,6 +1,6 @@ /* Common subexpression elimination for GNU compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -7108,6 +7108,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch, int to_usage = 0; rtx libcall_insn = NULL_RTX; int num_insns = 0; + int no_conflict = 0; /* This array is undefined before max_reg, so only allocate the space actually needed and adjust the start. */ @@ -7187,11 +7188,26 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch, if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX))) libcall_insn = XEXP (p, 0); else if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) - libcall_insn = 0; + { + /* Keep libcall_insn for the last SET insn of a no-conflict + block to prevent changing the destination. */ + if (! no_conflict) + libcall_insn = 0; + else + no_conflict = -1; + } + else if (find_reg_note (insn, REG_NO_CONFLICT, NULL_RTX)) + no_conflict = 1; } cse_insn (insn, libcall_insn); + if (no_conflict == -1) + { + libcall_insn = 0; + no_conflict = 0; + } + /* If we haven't already found an insn where we added a LABEL_REF, check this one. */ if (GET_CODE (insn) == INSN && ! recorded_label_ref |