[libc-commits] [libc] [libc] Explicitly mark memcpy implementation no-builtin-memcpy (PR #216247)
Aiden Grossman via libc-commits
libc-commits at lists.llvm.org
Thu Aug 13 22:03:43 PDT 2026
https://github.com/boomanaiden154 created https://github.com/llvm/llvm-project/pull/216247
THis works towards disabling -fno-builtin from the libc build, which
will allow inlining of libc into user code, which should help with
performance. We still need to preserve the no-builtin behavior for libc
so that the compiler does not turn the implementation into a recursive
call to the libcall.
>From 668df407630b9a3fb2afcf9676a9477936ee91b7 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Fri, 14 Aug 2026 05:03:32 +0000
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
libc/src/__support/common.h | 11 ++++-
libc/src/__support/macros/attributes.h | 7 ++++
libc/src/string/memcpy.cpp | 2 +
.../memory_utils/aarch64/inline_memcpy.h | 8 ++--
.../string/memory_utils/arm/inline_memcpy.h | 28 +++++++------
.../memory_utils/generic/aligned_access.h | 17 ++++----
.../src/string/memory_utils/generic/builtin.h | 6 +--
.../memory_utils/generic/byte_per_byte.h | 7 ++--
libc/src/string/memory_utils/inline_memcpy.h | 6 +--
.../string/memory_utils/riscv/inline_memcpy.h | 6 +--
.../memory_utils/x86_64/inline_memcpy.h | 42 +++++++++----------
11 files changed, 83 insertions(+), 57 deletions(-)
diff --git a/libc/src/__support/common.h b/libc/src/__support/common.h
index 454dfb43b744e..104799ce7dcab 100644
--- a/libc/src/__support/common.h
+++ b/libc/src/__support/common.h
@@ -51,6 +51,15 @@
#define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name)
+#ifdef LLVM_LIBC_FUNCTION_IS_BUILTIN
+#define TO_STR(builtin) #builtin
+#define TO_TO_STR(builtin) TO_STR(builtin)
+#define LLVM_LIBC_DISABLE_BUILTIN_FUNCTION \
+ __attribute__((no_builtin(TO_TO_STR(LLVM_LIBC_FUNCTION_IS_BUILTIN))))
+#else
+#define LLVM_LIBC_DISABLE_BUILTIN_FUNCTION
+#endif
+
// Export both `func` and `LIBC_NAMESPACE::func` using an alias symbol.
// This does not work on platfors with LIBC_TARGET_USES_LEADING_UNDERSCORE
// so there this only exports `_func`.
@@ -61,7 +70,7 @@
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \
__##name##_impl__ asm(c_alias); \
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(c_alias)]]; \
- type __##name##_impl__ arglist
+ LLVM_LIBC_DISABLE_BUILTIN_FUNCTION type __##name##_impl__ arglist
#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
extern "C" decltype(LIBC_NAMESPACE::name) c_alias [[gnu::alias(#name)]]
diff --git a/libc/src/__support/macros/attributes.h b/libc/src/__support/macros/attributes.h
index cffcabcd29bd3..f78de08c917cc 100644
--- a/libc/src/__support/macros/attributes.h
+++ b/libc/src/__support/macros/attributes.h
@@ -165,4 +165,11 @@ LIBC_THREAD_MODE_EXTERNAL.
#define LIBC_NO_SANITIZE_OOB_ACCESS
#endif
+#if defined(__clang__)
+#define LIBC_BUILTIN_IMPL(BUILTIN) \
+ LIBC_INLINE __attribute__((no_builtin(#BUILTIN)))
+#else
+#define LIBC_BUILTIN_IMPL LIBC_INLINE
+#endif
+
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_ATTRIBUTES_H
diff --git a/libc/src/string/memcpy.cpp b/libc/src/string/memcpy.cpp
index 4d4ff4dd38726..9e8881b02ae28 100644
--- a/libc/src/string/memcpy.cpp
+++ b/libc/src/string/memcpy.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#define LLVM_LIBC_FUNCTION_IS_BUILTIN memcpy
+
#include "src/string/memcpy.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
diff --git a/libc/src/string/memory_utils/aarch64/inline_memcpy.h b/libc/src/string/memory_utils/aarch64/inline_memcpy.h
index 0c9224010784f..be26ef0c40e4f 100644
--- a/libc/src/string/memory_utils/aarch64/inline_memcpy.h
+++ b/libc/src/string/memory_utils/aarch64/inline_memcpy.h
@@ -8,7 +8,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_AARCH64_INLINE_MEMCPY_H
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_BUILTIN_IMPL
#include "src/__support/macros/properties/cpu_features.h"
#include "src/string/memory_utils/op_builtin.h"
#include "src/string/memory_utils/utils.h"
@@ -19,8 +19,10 @@
#include <arm_sve.h>
#endif
namespace LIBC_NAMESPACE_DECL {
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_aarch64(Ptr __restrict dst, CPtr __restrict src, size_t count) {
+[[maybe_unused]]
+LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_aarch64(Ptr __restrict dst,
+ CPtr __restrict src,
+ size_t count) {
// Always avoid emit any memory operation if count == 0.
if (count == 0)
return;
diff --git a/libc/src/string/memory_utils/arm/inline_memcpy.h b/libc/src/string/memory_utils/arm/inline_memcpy.h
index 5eddb80d25506..97e173909abcd 100644
--- a/libc/src/string/memory_utils/arm/inline_memcpy.h
+++ b/libc/src/string/memory_utils/arm/inline_memcpy.h
@@ -14,7 +14,7 @@
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_ARM_INLINE_MEMCPY_H
#include "src/__support/CPP/type_traits.h" // always_false
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_BUILTIN_IMPL
#include "src/__support/macros/optimization.h" // LIBC_LOOP_NOUNROLL
#include "src/string/memory_utils/arm/common.h" // LIBC_ATTR_LIKELY, LIBC_ATTR_UNLIKELY
#include "src/string/memory_utils/utils.h" // memcpy_inline, distance_to_align
@@ -29,7 +29,8 @@ namespace {
// semantics of `memcpy` where `src` and `dst` are `__restrict`. The compiler is
// free to use whatever instruction is best for the size and assumed access.
template <size_t bytes, AssumeAccess access>
-LIBC_INLINE void copy(void *dst, const void *src) {
+LIBC_BUILTIN_IMPL(memcpy)
+void copy(void *dst, const void *src) {
if constexpr (access == AssumeAccess::kAligned) {
constexpr size_t alignment = bytes > kWordSize ? kWordSize : bytes;
memcpy_inline<bytes>(assume_aligned<alignment>(dst),
@@ -43,7 +44,8 @@ LIBC_INLINE void copy(void *dst, const void *src) {
template <size_t bytes, BlockOp block_op = BlockOp::kFull,
AssumeAccess access = AssumeAccess::kUnknown>
-LIBC_INLINE void copy_block_and_bump_pointers(Ptr &dst, CPtr &src) {
+LIBC_BUILTIN_IMPL(memcpy)
+void copy_block_and_bump_pointers(Ptr &dst, CPtr &src) {
if constexpr (block_op == BlockOp::kFull) {
copy<bytes, access>(dst, src);
} else if constexpr (block_op == BlockOp::kByWord) {
@@ -67,15 +69,16 @@ LIBC_INLINE void copy_block_and_bump_pointers(Ptr &dst, CPtr &src) {
}
template <size_t bytes, BlockOp block_op, AssumeAccess access>
-LIBC_INLINE void consume_by_block(Ptr &dst, CPtr &src, size_t &size) {
+LIBC_BUILTIN_IMPL(memcpy)
+void consume_by_block(Ptr &dst, CPtr &src, size_t &size) {
LIBC_LOOP_NOUNROLL
for (size_t i = 0; i < size / bytes; ++i)
copy_block_and_bump_pointers<bytes, block_op, access>(dst, src);
size %= bytes;
}
-[[maybe_unused]] LIBC_INLINE void
-copy_bytes_and_bump_pointers(Ptr &dst, CPtr &src, size_t size) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void copy_bytes_and_bump_pointers(
+ Ptr &dst, CPtr &src, size_t size) {
LIBC_LOOP_NOUNROLL
for (size_t i = 0; i < size; ++i)
*dst++ = *src++;
@@ -95,8 +98,8 @@ copy_bytes_and_bump_pointers(Ptr &dst, CPtr &src, size_t size) {
// - When `src` and `dst` are misaligned, we align `dst` and recompose words
// using multiple aligned loads. `load_aligned` takes care of endianness
// issues.
-[[maybe_unused]] LIBC_INLINE void inline_memcpy_arm_low_end(Ptr dst, CPtr src,
- size_t size) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_arm_low_end(
+ Ptr dst, CPtr src, size_t size) {
if (size >= 8) {
if (const size_t offset = distance_to_align_up<kWordSize>(dst))
LIBC_ATTR_UNLIKELY {
@@ -142,8 +145,8 @@ copy_bytes_and_bump_pointers(Ptr &dst, CPtr &src, size_t size) {
// Implementation for Cortex-M3, M4, M7, M23, M33, M35P, M52 with hardware
// support for unaligned loads and stores. It compiles down to 272 bytes when
// used through `memcpy` that also needs to return the `dst` ptr.
-[[maybe_unused]] LIBC_INLINE void inline_memcpy_arm_mid_end(Ptr dst, CPtr src,
- size_t size) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_arm_mid_end(
+ Ptr dst, CPtr src, size_t size) {
if (misaligned(bitwise_or(src, dst)))
LIBC_ATTR_UNLIKELY {
if (size < 8)
@@ -192,8 +195,9 @@ copy_bytes_and_bump_pointers(Ptr &dst, CPtr &src, size_t size) {
copy_block_and_bump_pointers<2>(dst, src);
}
-[[maybe_unused]] LIBC_INLINE void inline_memcpy_arm(Ptr dst, CPtr src,
- size_t size) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_arm(Ptr dst,
+ CPtr src,
+ size_t size) {
// The compiler performs alias analysis and is able to prove that `dst` and
// `src` do not alias by propagating the `__restrict` keyword from the
// `memcpy` prototype. This allows the compiler to merge consecutive
diff --git a/libc/src/string/memory_utils/generic/aligned_access.h b/libc/src/string/memory_utils/generic/aligned_access.h
index 49a318d9c8a95..19e305752e4e2 100644
--- a/libc/src/string/memory_utils/generic/aligned_access.h
+++ b/libc/src/string/memory_utils/generic/aligned_access.h
@@ -13,7 +13,8 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_ALIGNED_ACCESS_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_ALIGNED_ACCESS_H
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "builtin.h"
+#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_BUILTIN_IMPL
#include "src/string/memory_utils/generic/byte_per_byte.h"
#include "src/string/memory_utils/op_generic.h" // generic::splat
#include "src/string/memory_utils/utils.h" // Ptr, CPtr
@@ -51,9 +52,10 @@ namespace LIBC_NAMESPACE_DECL {
// memcpy
///////////////////////////////////////////////////////////////////////////////
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_aligned_access_32bit(Ptr __restrict dst, CPtr __restrict src,
- size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(
+ memcpy) void inline_memcpy_aligned_access_32bit(Ptr __restrict dst,
+ CPtr __restrict src,
+ size_t count) {
constexpr size_t kAlign = sizeof(uint32_t);
if (count <= 2 * kAlign)
return inline_memcpy_byte_per_byte(dst, src, count);
@@ -69,9 +71,10 @@ inline_memcpy_aligned_access_32bit(Ptr __restrict dst, CPtr __restrict src,
inline_memcpy_byte_per_byte(dst, src, count, offset);
}
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_aligned_access_64bit(Ptr __restrict dst, CPtr __restrict src,
- size_t count) {
+[[maybe_unused]] LIBC_BULTIN_IMPL(
+ memcpy) void inline_memcpy_aligned_access_64bit(Ptr __restrict dst,
+ CPtr __restrict src,
+ size_t count) {
constexpr size_t kAlign = sizeof(uint64_t);
if (count <= 2 * kAlign)
return inline_memcpy_byte_per_byte(dst, src, count);
diff --git a/libc/src/string/memory_utils/generic/builtin.h b/libc/src/string/memory_utils/generic/builtin.h
index 4f1bba00446c7..3177d680cc929 100644
--- a/libc/src/string/memory_utils/generic/builtin.h
+++ b/libc/src/string/memory_utils/generic/builtin.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BUILTIN_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BUILTIN_H
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_BUILTIN_IMPL
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
#include "src/string/memory_utils/utils.h" // Ptr, CPtr
@@ -23,8 +23,8 @@ namespace LIBC_NAMESPACE_DECL {
#error "Builtin not defined"
#endif
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_builtin(Ptr dst, CPtr src, size_t count, size_t offset = 0) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_builtin(
+ Ptr dst, CPtr src, size_t count, size_t offset = 0) {
__builtin_memcpy(dst + offset, src + offset, count);
}
diff --git a/libc/src/string/memory_utils/generic/byte_per_byte.h b/libc/src/string/memory_utils/generic/byte_per_byte.h
index 862aeecab7f55..1e537e705dafa 100644
--- a/libc/src/string/memory_utils/generic/byte_per_byte.h
+++ b/libc/src/string/memory_utils/generic/byte_per_byte.h
@@ -12,7 +12,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_GENERIC_BYTE_PER_BYTE_H
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_BUILTIN_IMPL
#include "src/__support/macros/optimization.h" // LIBC_LOOP_NOUNROLL
#include "src/string/memory_utils/utils.h" // Ptr, CPtr
@@ -20,9 +20,8 @@
namespace LIBC_NAMESPACE_DECL {
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_byte_per_byte(Ptr dst, CPtr src, size_t count,
- size_t offset = 0) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_byte_per_byte(
+ Ptr dst, CPtr src, size_t count, size_t offset = 0) {
LIBC_LOOP_NOUNROLL
for (; offset < count; ++offset)
dst[offset] = src[offset];
diff --git a/libc/src/string/memory_utils/inline_memcpy.h b/libc/src/string/memory_utils/inline_memcpy.h
index 6924339927a35..7c1f16f97aed6 100644
--- a/libc/src/string/memory_utils/inline_memcpy.h
+++ b/libc/src/string/memory_utils/inline_memcpy.h
@@ -9,7 +9,7 @@
#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMCPY_H
#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMCPY_H
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_BUILTIN_IMPL
#include "src/__support/macros/properties/architectures.h" // LIBC_TARGET_ARCH_IS_
#include "src/string/memory_utils/utils.h" // Ptr, CPtr
@@ -44,8 +44,8 @@
namespace LIBC_NAMESPACE_DECL {
-[[gnu::flatten]] LIBC_INLINE void
-inline_memcpy(void *__restrict dst, const void *__restrict src, size_t count) {
+[[gnu::flatten]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy(
+ void *__restrict dst, const void *__restrict src, size_t count) {
LIBC_SRC_STRING_MEMORY_UTILS_MEMCPY(reinterpret_cast<Ptr>(dst),
reinterpret_cast<CPtr>(src), count);
}
diff --git a/libc/src/string/memory_utils/riscv/inline_memcpy.h b/libc/src/string/memory_utils/riscv/inline_memcpy.h
index e907ae4c079e0..b84c8c6b0a0ba 100644
--- a/libc/src/string/memory_utils/riscv/inline_memcpy.h
+++ b/libc/src/string/memory_utils/riscv/inline_memcpy.h
@@ -8,7 +8,7 @@
#ifndef LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMCPY_H
#define LIBC_SRC_STRING_MEMORY_UTILS_RISCV_INLINE_MEMCPY_H
-#include "src/__support/macros/attributes.h" // LIBC_INLINE
+#include "src/__support/macros/attributes.h" // LIBC_BUILTIN_IMPL
#include "src/__support/macros/config.h" // LIBC_NAMESPACE_DECL
#include "src/__support/macros/properties/architectures.h" // LIBC_TARGET_ARCH_IS_RISCV64
#include "src/string/memory_utils/generic/aligned_access.h"
@@ -18,8 +18,8 @@
namespace LIBC_NAMESPACE_DECL {
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_riscv(Ptr __restrict dst, CPtr __restrict src, size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_riscv(
+ Ptr __restrict dst, CPtr __restrict src, size_t count) {
#if defined(LIBC_TARGET_ARCH_IS_RISCV64)
return inline_memcpy_aligned_access_64bit(dst, src, count);
#elif defined(LIBC_TARGET_ARCH_IS_RISCV32)
diff --git a/libc/src/string/memory_utils/x86_64/inline_memcpy.h b/libc/src/string/memory_utils/x86_64/inline_memcpy.h
index 4198f22722d1b..871f1817924a6 100644
--- a/libc/src/string/memory_utils/x86_64/inline_memcpy.h
+++ b/libc/src/string/memory_utils/x86_64/inline_memcpy.h
@@ -11,7 +11,7 @@
#include <stddef.h> // size_t
#include "hdr/stdint_proxy.h" // SIZE_MAX
-#include "src/__support/macros/attributes.h" // LIBC_INLINE_VAR
+#include "src/__support/macros/attributes.h" // LIBC_INLINE_VAR, LIBC_BUILTIN_IMPL
#include "src/__support/macros/is_defined.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/string/memory_utils/op_builtin.h"
@@ -68,9 +68,8 @@ struct alignas(32) m256i {
} // namespace x86
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_x86_sse2_ge64(Ptr __restrict dst, CPtr __restrict src,
- size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_x86_sse2_ge64(
+ Ptr __restrict dst, CPtr __restrict src, size_t count) {
if (count <= 128)
return builtin::Memcpy<64>::head_tail(dst, src, count);
builtin::Memcpy<32>::block(dst, src);
@@ -78,9 +77,8 @@ inline_memcpy_x86_sse2_ge64(Ptr __restrict dst, CPtr __restrict src,
return builtin::Memcpy<32>::loop_and_tail(dst, src, count);
}
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_x86_avx_ge64(Ptr __restrict dst, CPtr __restrict src,
- size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_x86_avx_ge64(
+ Ptr __restrict dst, CPtr __restrict src, size_t count) {
if (count <= 128)
return builtin::Memcpy<64>::head_tail(dst, src, count);
if (count < 256)
@@ -90,16 +88,16 @@ inline_memcpy_x86_avx_ge64(Ptr __restrict dst, CPtr __restrict src,
return builtin::Memcpy<64>::loop_and_tail(dst, src, count);
}
-[[maybe_unused]] LIBC_INLINE void inline_memcpy_prefetch(Ptr __restrict dst,
- CPtr __restrict src,
- size_t distance) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_prefetch(
+ Ptr __restrict dst, CPtr __restrict src, size_t distance) {
prefetch_to_local_cache(src + distance);
prefetch_for_write(dst + distance);
}
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_x86_sse2_ge64_sw_prefetching(Ptr __restrict dst,
- CPtr __restrict src, size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(
+ memcpy) void inline_memcpy_x86_sse2_ge64_sw_prefetching(Ptr __restrict dst,
+ CPtr __restrict src,
+ size_t count) {
using namespace LIBC_NAMESPACE::x86;
inline_memcpy_prefetch(dst, src, K_ONE_CACHELINE);
if (count <= 128)
@@ -144,9 +142,10 @@ inline_memcpy_x86_sse2_ge64_sw_prefetching(Ptr __restrict dst,
return builtin::Memcpy<32>::tail(dst, src, count);
}
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_x86_avx_ge64_sw_prefetching(Ptr __restrict dst,
- CPtr __restrict src, size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(
+ memcpy) void inline_memcpy_x86_avx_ge64_sw_prefetching(Ptr __restrict dst,
+ CPtr __restrict src,
+ size_t count) {
using namespace LIBC_NAMESPACE::x86;
inline_memcpy_prefetch(dst, src, K_ONE_CACHELINE);
if (count <= 128)
@@ -201,8 +200,8 @@ inline_memcpy_x86_avx_ge64_sw_prefetching(Ptr __restrict dst,
return builtin::Memcpy<64>::tail(dst, src, count);
}
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_x86(Ptr __restrict dst, CPtr __restrict src, size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(memcpy) void inline_memcpy_x86(
+ Ptr __restrict dst, CPtr __restrict src, size_t count) {
constexpr size_t VECTOR_SIZE = x86::K_AVX512_F ? 64
: x86::K_AVX ? 32
: x86::K_SSE2 ? 16
@@ -249,9 +248,10 @@ inline_memcpy_x86(Ptr __restrict dst, CPtr __restrict src, size_t count) {
}
}
-[[maybe_unused]] LIBC_INLINE void
-inline_memcpy_x86_maybe_interpose_repmovsb(Ptr __restrict dst,
- CPtr __restrict src, size_t count) {
+[[maybe_unused]] LIBC_BUILTIN_IMPL(
+ memcpy) void inline_memcpy_x86_maybe_interpose_repmovsb(Ptr __restrict dst,
+ CPtr __restrict src,
+ size_t count) {
if constexpr (x86::K_REP_MOVSB_THRESHOLD == 0) {
return x86::Memcpy::repmovsb(dst, src, count);
} else if constexpr (x86::K_REP_MOVSB_THRESHOLD == SIZE_MAX) {
More information about the libc-commits
mailing list