aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.tile5
-rw-r--r--sysdeps/tile/tilegx/memcpy.c13
2 files changed, 17 insertions, 1 deletions
diff --git a/ChangeLog.tile b/ChangeLog.tile
index 5cdc293f8e..83136aa6c3 100644
--- a/ChangeLog.tile
+++ b/ChangeLog.tile
@@ -1,5 +1,10 @@
2012-05-12 Chris Metcalf <cmetcalf@tilera.com>
+ * sysdeps/tile/tilegx/memcpy.c: Allow memcpy(p, p, n)
+ without corrupting memory at "p".
+
+2012-05-12 Chris Metcalf <cmetcalf@tilera.com>
+
* sysdeps/tile/__tls_get_addr.S: Use __WORDSIZE, not _LP64.
2012-05-12 Chris Metcalf <cmetcalf@tilera.com>
diff --git a/sysdeps/tile/tilegx/memcpy.c b/sysdeps/tile/tilegx/memcpy.c
index 9cfb283c82..dd6e30dd60 100644
--- a/sysdeps/tile/tilegx/memcpy.c
+++ b/sysdeps/tile/tilegx/memcpy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2011-2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
@@ -107,6 +107,17 @@ __memcpy (void *__restrict dstv, const void *__restrict srcv, size_t n)
n -= sizeof (word_t))
*dst8++ = *src8++;
+ /* If copying to self, return. The test is cheap enough
+ that we do it despite the fact that the memcpy() contract
+ doesn't require us to support overlapping dst and src.
+ This is the most common case of overlap, and any close
+ overlap will cause corruption due to the wh64 below.
+ This case is particularly important since the compiler
+ will emit memcpy() calls for aggregate copies even if it
+ can't prove that src != dst. */
+ if (__builtin_expect (dst8 == src8, 0))
+ return dstv;
+
for (; n >= CHIP_L2_LINE_SIZE ();)
{
__insn_wh64 (dst8);