[libc-commits] [PATCH] D152811: [libc] Dispatch memmove to memcpy when buffers are disjoint
Guillaume Chatelet via Phabricator via libc-commits
libc-commits at lists.llvm.org
Wed Jun 14 01:29:27 PDT 2023
This revision was automatically updated to reflect the committed changes.
Closed by commit rG2cfae7cdf451: [libc] Dispatch memmove to memcpy when buffers are disjoint (authored by gchatelet).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D152811/new/
https://reviews.llvm.org/D152811
Files:
libc/src/string/memmove.cpp
libc/src/string/memory_utils/utils.h
libc/test/src/string/memory_utils/utils_test.cpp
Index: libc/test/src/string/memory_utils/utils_test.cpp
===================================================================
--- libc/test/src/string/memory_utils/utils_test.cpp
+++ libc/test/src/string/memory_utils/utils_test.cpp
@@ -144,6 +144,19 @@
}
}
+TEST(LlvmLibcUtilsTest, DisjointBuffers) {
+ char buf[3];
+ const char *const a = buf + 0;
+ const char *const b = buf + 1;
+ EXPECT_TRUE(is_disjoint(a, b, 0));
+ EXPECT_TRUE(is_disjoint(a, b, 1));
+ EXPECT_FALSE(is_disjoint(a, b, 2));
+
+ EXPECT_TRUE(is_disjoint(b, a, 0));
+ EXPECT_TRUE(is_disjoint(b, a, 1));
+ EXPECT_FALSE(is_disjoint(b, a, 2));
+}
+
TEST(LlvmLibcUtilsTest, LoadStoreAligned) {
const uint64_t init = 0xDEAD'C0DE'BEEF'F00D;
CPtr const src = reinterpret_cast<CPtr>(&init);
Index: libc/src/string/memory_utils/utils.h
===================================================================
--- libc/src/string/memory_utils/utils.h
+++ libc/src/string/memory_utils/utils.h
@@ -84,6 +84,21 @@
return reinterpret_cast<T *>(__builtin_assume_aligned(ptr, alignment));
}
+// Returns true iff memory regions [p1, p1 + size] and [p2, p2 + size] are
+// disjoint.
+LIBC_INLINE bool is_disjoint(const void *p1, const void *p2, size_t size) {
+ const char *a = static_cast<const char *>(p1);
+ const char *b = static_cast<const char *>(p2);
+ if (a > b) {
+ // Swap a and b, this compiles down to conditionnal move for aarch64, x86
+ // and RISCV with zbb extension.
+ const char *tmp = a;
+ a = b;
+ b = tmp;
+ }
+ return a + size <= b;
+}
+
#if LIBC_HAS_BUILTIN(__builtin_memcpy_inline)
#define LLVM_LIBC_HAS_BUILTIN_MEMCPY_INLINE
#endif
Index: libc/src/string/memmove.cpp
===================================================================
--- libc/src/string/memmove.cpp
+++ libc/src/string/memmove.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "src/string/memmove.h"
+#include "src/string/memory_utils/memcpy_implementations.h"
#include "src/string/memory_utils/memmove_implementations.h"
#include <stddef.h> // size_t
@@ -14,7 +15,10 @@
LLVM_LIBC_FUNCTION(void *, memmove,
(void *dst, const void *src, size_t count)) {
- inline_memmove(dst, src, count);
+ if (is_disjoint(dst, src, count))
+ inline_memcpy(dst, src, count);
+ else
+ inline_memmove(dst, src, count);
return dst;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152811.531228.patch
Type: text/x-patch
Size: 2406 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20230614/0787d80f/attachment.bin>
More information about the libc-commits
mailing list