re PR target/35258 (two memcpy calls merged incorrectly with -O1)
authorAndreas Krebbel <krebbel1@de.ibm.com>
Mon, 25 Feb 2008 15:07:17 +0000 (15:07 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 25 Feb 2008 15:07:17 +0000 (15:07 +0000)
2008-02-25  Andreas Krebbel  <krebbel1@de.ibm.com>

PR target/35258
* cse.c (cse_insn): Avoid creation of overlapping MEMs.
* alias.c (nonoverlapping_memrefs_p): Export for use in other modules.
* alias.h (nonoverlapping_memrefs_p): Likewise.

2008-02-25  Andreas Krebbel  <krebbel1@de.ibm.com>

PR target/35258
* gcc.dg/pr35258.c: New testcase.

From-SVN: r132628

gcc/ChangeLog
gcc/alias.c
gcc/alias.h
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr35258.c [new file with mode: 0644]

index 13ca11e..fa691e7 100644 (file)
@@ -1,3 +1,10 @@
+2008-02-25  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       PR target/35258
+       * cse.c (cse_insn): Avoid creation of overlapping MEMs.
+       * alias.c (nonoverlapping_memrefs_p): Export for use in other modules.
+       * alias.h (nonoverlapping_memrefs_p): Likewise.
+
 2008-02-25  Jan Beulich  <jbeulich@novell.com>
 
        * Makefile.in: Also prefix uses of crt0.o and mcrt0.o with
index bd5c277..56afa86 100644 (file)
@@ -164,7 +164,6 @@ static int aliases_everything_p (const_rtx);
 static bool nonoverlapping_component_refs_p (const_tree, const_tree);
 static tree decl_for_component_ref (tree);
 static rtx adjust_offset_for_component_ref (tree, rtx);
-static int nonoverlapping_memrefs_p (const_rtx, const_rtx);
 static int write_dependence_p (const_rtx, const_rtx, int);
 
 static void memory_modified_1 (rtx, const_rtx, void *);
@@ -1976,7 +1975,7 @@ adjust_offset_for_component_ref (tree x, rtx offset)
 /* Return nonzero if we can determine the exprs corresponding to memrefs
    X and Y and they do not overlap.  */
 
-static int
+int
 nonoverlapping_memrefs_p (const_rtx x, const_rtx y)
 {
   tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
index a245493..772aea0 100644 (file)
@@ -28,6 +28,7 @@ extern alias_set_type get_varargs_alias_set (void);
 extern alias_set_type get_frame_alias_set (void);
 extern bool component_uses_parent_alias_set (const_tree);
 extern bool alias_set_subset_of (alias_set_type, alias_set_type);
+extern int nonoverlapping_memrefs_p (const_rtx, const_rtx);
 
 /* This alias set can be used to force a memory to conflict with all
    other memories, creating a barrier across which no memory reference
index f6660e4..9f31e67 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4753,6 +4753,23 @@ cse_insn (rtx insn, rtx libcall_insn)
              src_elt_cost = MAX_COST;
            }
 
+         /* Avoid creation of overlapping memory moves.  */
+         if (MEM_P (trial) && MEM_P (SET_DEST (sets[i].rtl)))
+           {
+             rtx src, dest;
+
+             /* BLKmode moves are not handled by cse anyway.  */
+             if (GET_MODE (trial) == BLKmode)
+               break;
+
+             src = canon_rtx (trial);
+             dest = canon_rtx (SET_DEST (sets[i].rtl));
+
+             if (!MEM_P (src) || !MEM_P (dest)
+                 || !nonoverlapping_memrefs_p (src, dest))
+               break;
+           }
+
          /* We don't normally have an insn matching (set (pc) (pc)), so
             check for this separately here.  We will delete such an
             insn below.
index cc2d87c..0e3977d 100644 (file)
@@ -1,3 +1,8 @@
+2008-02-25  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       PR target/35258
+       * gcc.dg/pr35258.c: New testcase.
+
 2008-02-25  Jan Beulich  <jbeulich@novell.com>
 
        * gcc.dg/20020426-2.c: Remove bogus workaround.
diff --git a/gcc/testsuite/gcc.dg/pr35258.c b/gcc/testsuite/gcc.dg/pr35258.c
new file mode 100644 (file)
index 0000000..d1c45a7
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+extern void *memcpy (void *, const void *, __SIZE_TYPE__);
+extern int memcmp (const void *, const void *, __SIZE_TYPE__);
+extern void abort(void);
+
+char str[9] = "1234";
+
+void
+bar (void)
+{
+  unsigned int temp;
+  char *p = &str[2];
+
+  memcpy (&temp, &str[1], 4);
+  memcpy (p, &temp, 4);
+  str[1] = '.';
+}
+
+int main()
+{
+  bar();
+  if (memcmp (str, "1.234", 5) != 0)
+    abort ();
+
+  return 0;
+}