[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