re PR rtl-optimization/13567 ([sh] miscompiling calls.c)
authorKaz Kojima <kkojima@gcc.gnu.org>
Tue, 20 Jan 2004 02:34:23 +0000 (02:34 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Tue, 20 Jan 2004 02:34:23 +0000 (02:34 +0000)
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

gcc/ChangeLog
gcc/cse.c

index 3b53c62..b12049b 100644 (file)
@@ -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 
index bcfe68f..9c6dfcf 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -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