[libc-commits] [libc] 436c8f4 - [reland][libc] Add bcopy
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Thu Dec 1 02:07:14 PST 2022
Author: Guillaume Chatelet
Date: 2022-12-01T10:07:04Z
New Revision: 436c8f4420a62e7d3601693f4097bc6e6a5ee9f4
URL: https://github.com/llvm/llvm-project/commit/436c8f4420a62e7d3601693f4097bc6e6a5ee9f4
DIFF: https://github.com/llvm/llvm-project/commit/436c8f4420a62e7d3601693f4097bc6e6a5ee9f4.diff
LOG: [reland][libc] Add bcopy
Differential Revision: https://reviews.llvm.org/D138994
Added:
libc/src/string/bcopy.cpp
libc/src/string/bcopy.h
libc/test/src/string/bcopy_test.cpp
Modified:
libc/config/darwin/arm/entrypoints.txt
libc/config/linux/aarch64/entrypoints.txt
libc/config/linux/arm/entrypoints.txt
libc/config/linux/x86_64/entrypoints.txt
libc/config/windows/entrypoints.txt
libc/docs/strings.rst
libc/spec/llvm_libc_ext.td
libc/src/string/CMakeLists.txt
libc/test/src/string/CMakeLists.txt
utils/bazel/llvm-project-overlay/libc/BUILD.bazel
utils/bazel/llvm-project-overlay/libc/test/src/string/BUILD.bazel
Removed:
################################################################################
diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt
index cd500736ac175..d16bf0816e54e 100644
--- a/libc/config/darwin/arm/entrypoints.txt
+++ b/libc/config/darwin/arm/entrypoints.txt
@@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bcmp
+ libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 8db3b795a83b6..a67165e96f669 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bcmp
+ libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index c88cbb1c3b5ef..725365231af5c 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bcmp
+ libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index e9e173a831013..14043b039041c 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -28,6 +28,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bcmp
+ libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 69a0acab6ad5f..bf52c8caccdfc 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -19,6 +19,7 @@ set(TARGET_LIBC_ENTRYPOINTS
# string.h entrypoints
libc.src.string.bcmp
+ libc.src.string.bcopy
libc.src.string.bzero
libc.src.string.memccpy
libc.src.string.memchr
diff --git a/libc/docs/strings.rst b/libc/docs/strings.rst
index c475134937861..50b479bf2117e 100644
--- a/libc/docs/strings.rst
+++ b/libc/docs/strings.rst
@@ -36,6 +36,7 @@ Function Name Available
============= =========
bzero |check|
bcmp |check|
+bcopy |check|
memcpy |check|
memset |check|
memcmp |check|
diff --git a/libc/spec/llvm_libc_ext.td b/libc/spec/llvm_libc_ext.td
index 76f06223756da..731671f7306bc 100644
--- a/libc/spec/llvm_libc_ext.td
+++ b/libc/spec/llvm_libc_ext.td
@@ -5,6 +5,11 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
[], // Types
[], // Enumerations
[
+ FunctionSpec<
+ "bcopy",
+ RetValSpec<VoidType>,
+ [ArgSpec<ConstVoidPtr>, ArgSpec<VoidPtr>, ArgSpec<SizeTType>]
+ >,
FunctionSpec<
"bzero",
RetValSpec<VoidType>,
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 7719178da457b..422d24c131312 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -20,6 +20,14 @@ add_header_library(
.memory_utils.memcpy_implementation
)
+add_entrypoint_object(
+ bcopy
+ SRCS
+ bcopy.cpp
+ HDRS
+ bcopy.h
+)
+
add_entrypoint_object(
memccpy
SRCS
@@ -28,7 +36,6 @@ add_entrypoint_object(
memccpy.h
)
-
add_entrypoint_object(
mempcpy
SRCS
diff --git a/libc/src/string/bcopy.cpp b/libc/src/string/bcopy.cpp
new file mode 100644
index 0000000000000..9653c73f1305d
--- /dev/null
+++ b/libc/src/string/bcopy.cpp
@@ -0,0 +1,19 @@
+//===-- Implementation of bcopy -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/bcopy.h"
+#include "src/__support/common.h"
+#include "src/string/memory_utils/memmove_implementations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(void, bcopy, (const void *src, void *dst, size_t count)) {
+ return inline_memmove(dst, src, count);
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/string/bcopy.h b/libc/src/string/bcopy.h
new file mode 100644
index 0000000000000..12de749d4640d
--- /dev/null
+++ b/libc/src/string/bcopy.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for bcopy -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_BCOPY_H
+#define LLVM_LIBC_SRC_STRING_BCOPY_H
+
+#include <stddef.h> // size_t
+
+namespace __llvm_libc {
+
+void bcopy(const void *src, void *dest, size_t count);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_BCOPY_H
diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt
index b0b352913cc94..8b427cc2d116e 100644
--- a/libc/test/src/string/CMakeLists.txt
+++ b/libc/test/src/string/CMakeLists.txt
@@ -2,6 +2,18 @@ add_libc_testsuite(libc_string_unittests)
add_subdirectory(memory_utils)
+add_libc_unittest(
+ bcopy_test
+ SUITE
+ libc_string_unittests
+ SRCS
+ bcopy_test.cpp
+ DEPENDS
+ libc.src.string.bcopy
+ LINK_LIBRARIES
+ LibcMemoryHelpers
+)
+
add_libc_unittest(
memccpy_test
SUITE
diff --git a/libc/test/src/string/bcopy_test.cpp b/libc/test/src/string/bcopy_test.cpp
new file mode 100644
index 0000000000000..fa57d2502c2de
--- /dev/null
+++ b/libc/test/src/string/bcopy_test.cpp
@@ -0,0 +1,104 @@
+//===-- Unittests for bcopy -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/CPP/span.h"
+#include "src/string/bcopy.h"
+#include "utils/UnitTest/MemoryMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+using __llvm_libc::cpp::array;
+using __llvm_libc::cpp::span;
+
+TEST(LlvmLibcBcopyTest, MoveZeroByte) {
+ char Buffer[] = {'a', 'b', 'y', 'z'};
+ const char Expected[] = {'a', 'b', 'y', 'z'};
+ void *const Dst = Buffer;
+ __llvm_libc::bcopy(Buffer + 2, Dst, 0);
+ ASSERT_MEM_EQ(Buffer, Expected);
+}
+
+TEST(LlvmLibcBcopyTest, DstAndSrcPointToSameAddress) {
+ char Buffer[] = {'a', 'b'};
+ const char Expected[] = {'a', 'b'};
+ void *const Dst = Buffer;
+ __llvm_libc::bcopy(Buffer, Dst, 1);
+ ASSERT_MEM_EQ(Buffer, Expected);
+}
+
+TEST(LlvmLibcBcopyTest, DstStartsBeforeSrc) {
+ // Set boundary at beginning and end for not overstepping when
+ // copy forward or backward.
+ char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
+ const char Expected[] = {'z', 'b', 'c', 'c', 'z'};
+ void *const Dst = Buffer + 1;
+ __llvm_libc::bcopy(Buffer + 2, Dst, 2);
+ ASSERT_MEM_EQ(Buffer, Expected);
+}
+
+TEST(LlvmLibcBcopyTest, DstStartsAfterSrc) {
+ char Buffer[] = {'z', 'a', 'b', 'c', 'z'};
+ const char Expected[] = {'z', 'a', 'a', 'b', 'z'};
+ void *const Dst = Buffer + 2;
+ __llvm_libc::bcopy(Buffer + 1, Dst, 2);
+ ASSERT_MEM_EQ(Buffer, Expected);
+}
+
+// e.g. `Dst` follow `src`.
+// str: [abcdefghij]
+// [__src_____]
+// [_____Dst__]
+TEST(LlvmLibcBcopyTest, SrcFollowDst) {
+ char Buffer[] = {'z', 'a', 'b', 'z'};
+ const char Expected[] = {'z', 'b', 'b', 'z'};
+ void *const Dst = Buffer + 1;
+ __llvm_libc::bcopy(Buffer + 2, Dst, 1);
+ ASSERT_MEM_EQ(Buffer, Expected);
+}
+
+TEST(LlvmLibcBcopyTest, DstFollowSrc) {
+ char Buffer[] = {'z', 'a', 'b', 'z'};
+ const char Expected[] = {'z', 'a', 'a', 'z'};
+ void *const Dst = Buffer + 2;
+ __llvm_libc::bcopy(Buffer + 1, Dst, 1);
+ ASSERT_MEM_EQ(Buffer, Expected);
+}
+
+static constexpr int kMaxSize = 512;
+
+char GetRandomChar() {
+ static constexpr const uint64_t A = 1103515245;
+ static constexpr const uint64_t C = 12345;
+ static constexpr const uint64_t M = 1ULL << 31;
+ static uint64_t Seed = 123456789;
+ Seed = (A * Seed + C) % M;
+ return Seed;
+}
+
+void Randomize(span<char> Buffer) {
+ for (auto ¤t : Buffer)
+ current = GetRandomChar();
+}
+
+TEST(LlvmLibcBcopyTest, SizeSweep) {
+ using LargeBuffer = array<char, 3 * kMaxSize>;
+ LargeBuffer GroundTruth;
+ Randomize(GroundTruth);
+ for (int Size = 0; Size < kMaxSize; ++Size) {
+ for (int Offset = -Size; Offset < Size; ++Offset) {
+ LargeBuffer Buffer = GroundTruth;
+ LargeBuffer Expected = GroundTruth;
+ size_t DstOffset = kMaxSize;
+ size_t SrcOffset = kMaxSize + Offset;
+ for (int I = 0; I < Size; ++I)
+ Expected[DstOffset + I] = GroundTruth[SrcOffset + I];
+ void *const Dst = Buffer.data() + DstOffset;
+ __llvm_libc::bcopy(Buffer.data() + SrcOffset, Dst, Size);
+ ASSERT_MEM_EQ(Buffer, Expected);
+ }
+ }
+}
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 1aafa2a8473b1..48c84fc96e69f 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -1124,6 +1124,17 @@ libc_function(
],
)
+libc_function(
+ name = "bcopy",
+ srcs = ["src/string/bcopy.cpp"],
+ hdrs = ["src/string/bcopy.h"],
+ features = no_sanitize_features,
+ deps = [
+ ":__support_common",
+ ":string_memory_utils",
+ ],
+)
+
libc_function(
name = "memcmp",
srcs = ["src/string/memcmp.cpp"],
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/string/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/string/BUILD.bazel
index 8ccc62767696d..cfda301ff2d7a 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/string/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/string/BUILD.bazel
@@ -146,6 +146,18 @@ libc_test(
],
)
+libc_test(
+ name = "bcopy_test",
+ srcs = ["bcopy_test.cpp"],
+ libc_function_deps = [
+ "//libc:bcopy",
+ ],
+ deps = [
+ "//libc:__support_cpp_span",
+ "//libc/utils/UnitTest:memory_matcher",
+ ],
+)
+
libc_test(
name = "memcmp_test",
srcs = ["memcmp_test.cpp"],
More information about the libc-commits
mailing list