[libc-commits] [libc] [libc] move bcmp, bzero, bcopy, index, rindex, strcasecmp, strncasecmp to strings.h (PR #118899)

Nick Desaulniers via libc-commits libc-commits at lists.llvm.org
Mon Dec 9 10:09:51 PST 2024


https://github.com/nickdesaulniers updated https://github.com/llvm/llvm-project/pull/118899

>From 3e00483190edf1c8511f2c06bfd491aaeb0ef99e Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Thu, 5 Dec 2024 13:46:38 -0800
Subject: [PATCH 1/2] [libc] move bcmp, bzero, bcopy, index, rindex,
 strcasecmp, strncasecmp to strings.h

docgen relies on the convention that we have a file foo.cpp in
libc/src/<header>/. Because the above functions weren't in libc/src/strings/
but rather libc/src/string/, docgen could not find that we had implemented
these.

Rather than add special carve outs to docgen, let's fix up our sources for
these 7 functions to stick with the existing conventions the rest of the
codebase follows.

Link: #118860
Fixes: #118875
---
 libc/benchmarks/CMakeLists.txt                |   6 +-
 libc/cmake/modules/LLVMLibCObjectRules.cmake  |  38 +++++
 libc/cmake/modules/LLVMLibCTestRules.cmake    |  40 ++++-
 libc/config/baremetal/arm/entrypoints.txt     |  16 +-
 libc/config/baremetal/riscv/entrypoints.txt   |  16 +-
 libc/config/darwin/arm/entrypoints.txt        |  12 +-
 libc/config/darwin/x86_64/entrypoints.txt     |   8 +-
 libc/config/gpu/entrypoints.txt               |  16 +-
 libc/config/linux/aarch64/entrypoints.txt     |  16 +-
 libc/config/linux/arm/entrypoints.txt         |  16 +-
 libc/config/linux/riscv/entrypoints.txt       |  15 +-
 libc/config/linux/x86_64/entrypoints.txt      |  16 +-
 libc/config/windows/entrypoints.txt           |  12 +-
 libc/fuzzing/string/CMakeLists.txt            |   2 +-
 libc/fuzzing/string/bcmp_fuzz.cpp             |   2 +-
 libc/hdr/func/free.h                          |   3 +-
 libc/hdr/func/malloc.h                        |   4 +-
 libc/hdr/func/realloc.h                       |   4 +-
 libc/src/CMakeLists.txt                       |   1 +
 libc/src/string/CMakeLists.txt                | 146 ------------------
 libc/src/strings/CMakeLists.txt               |  99 ++++++++++++
 libc/src/{string => strings}/bcmp.cpp         |   2 +-
 libc/src/{string => strings}/bcmp.h           |   6 +-
 libc/src/{string => strings}/bcopy.cpp        |   2 +-
 libc/src/{string => strings}/bcopy.h          |   6 +-
 libc/src/{string => strings}/bzero.cpp        |   2 +-
 libc/src/{string => strings}/bzero.h          |   6 +-
 libc/src/{string => strings}/index.cpp        |   2 +-
 libc/src/{string => strings}/index.h          |   6 +-
 libc/src/{string => strings}/rindex.cpp       |   2 +-
 libc/src/{string => strings}/rindex.h         |   6 +-
 libc/src/{string => strings}/strcasecmp.cpp   |   2 +-
 libc/src/{string => strings}/strcasecmp.h     |   6 +-
 libc/src/{string => strings}/strncasecmp.cpp  |   2 +-
 libc/src/{string => strings}/strncasecmp.h    |   6 +-
 libc/test/src/CMakeLists.txt                  |   1 +
 libc/test/src/string/CMakeLists.txt           |  94 +----------
 .../test/src/string/memory_utils/op_tests.cpp |   1 +
 .../src/{string => strings}/bcmp_test.cpp     |   4 +-
 .../src/{string => strings}/bcopy_test.cpp    |   6 +-
 .../src/{string => strings}/bzero_test.cpp    |   4 +-
 .../src/{string => strings}/index_test.cpp    |   0
 .../src/{string => strings}/rindex_test.cpp   |   0
 .../{string => strings}/strcasecmp_test.cpp   |   2 +-
 .../{string => strings}/strncasecmp_test.cpp  |   2 +-
 45 files changed, 310 insertions(+), 348 deletions(-)
 create mode 100644 libc/src/strings/CMakeLists.txt
 rename libc/src/{string => strings}/bcmp.cpp (95%)
 rename libc/src/{string => strings}/bcmp.h (83%)
 rename libc/src/{string => strings}/bcopy.cpp (95%)
 rename libc/src/{string => strings}/bcopy.h (83%)
 rename libc/src/{string => strings}/bzero.cpp (95%)
 rename libc/src/{string => strings}/bzero.h (82%)
 rename libc/src/{string => strings}/index.cpp (95%)
 rename libc/src/{string => strings}/index.h (81%)
 rename libc/src/{string => strings}/rindex.cpp (95%)
 rename libc/src/{string => strings}/rindex.h (81%)
 rename libc/src/{string => strings}/strcasecmp.cpp (96%)
 rename libc/src/{string => strings}/strcasecmp.h (80%)
 rename libc/src/{string => strings}/strncasecmp.cpp (96%)
 rename libc/src/{string => strings}/strncasecmp.h (80%)
 rename libc/test/src/{string => strings}/bcmp_test.cpp (95%)
 rename libc/test/src/{string => strings}/bcopy_test.cpp (97%)
 rename libc/test/src/{string => strings}/bzero_test.cpp (91%)
 rename libc/test/src/{string => strings}/index_test.cpp (100%)
 rename libc/test/src/{string => strings}/rindex_test.cpp (100%)
 rename libc/test/src/{string => strings}/strcasecmp_test.cpp (97%)
 rename libc/test/src/{string => strings}/strncasecmp_test.cpp (97%)

diff --git a/libc/benchmarks/CMakeLists.txt b/libc/benchmarks/CMakeLists.txt
index 52e3f942d16ea3..6c011ef3015bcd 100644
--- a/libc/benchmarks/CMakeLists.txt
+++ b/libc/benchmarks/CMakeLists.txt
@@ -204,11 +204,11 @@ target_link_libraries(libc.benchmarks.memory_functions.opt_host
   PRIVATE
   libc-memory-benchmark
   libc.src.string.memcmp_opt_host.__internal__
-  libc.src.string.bcmp_opt_host.__internal__
   libc.src.string.memcpy_opt_host.__internal__
-  libc.src.string.memset_opt_host.__internal__
-  libc.src.string.bzero_opt_host.__internal__
   libc.src.string.memmove_opt_host.__internal__
+  libc.src.string.memset_opt_host.__internal__
+  libc.src.strings.bcmp_opt_host.__internal__
+  libc.src.strings.bzero_opt_host.__internal__
   benchmark_main
 )
 llvm_update_compile_flags(libc.benchmarks.memory_functions.opt_host)
diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake
index 68b5ed1ed51c04..142778d9ea1cc5 100644
--- a/libc/cmake/modules/LLVMLibCObjectRules.cmake
+++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake
@@ -452,3 +452,41 @@ function(add_redirector_object target_name)
     BEFORE PRIVATE -fPIC ${LIBC_COMPILE_OPTIONS_DEFAULT}
   )
 endfunction(add_redirector_object)
+
+# Helper to define a function with multiple implementations
+# - Computes flags to satisfy required/rejected features and arch,
+# - Declares an entry point,
+# - Attach the REQUIRE_CPU_FEATURES property to the target,
+# - Add the fully qualified target to `${name}_implementations` global property for tests.
+function(add_implementation name impl_name)
+  cmake_parse_arguments(
+    "ADD_IMPL"
+    "" # Optional arguments
+    "" # Single value arguments
+    "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;MLLVM_COMPILE_OPTIONS" # Multi value arguments
+    ${ARGN})
+
+  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+    # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication.
+    foreach(opt IN LISTS ADD_IMPL_MLLVM_COMPILE_OPTIONS)
+      list(APPEND ADD_IMPL_COMPILE_OPTIONS "SHELL:-mllvm ${opt}")
+    endforeach()
+  endif()
+
+  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
+    # Prevent warning when passing x86 SIMD types as template arguments.
+    # e.g. "warning: ignoring attributes on template argument ā€˜__m128iā€™ [-Wignored-attributes]"
+    list(APPEND ADD_IMPL_COMPILE_OPTIONS "-Wno-ignored-attributes")
+  endif()
+
+  add_entrypoint_object(${impl_name}
+    NAME ${name}
+    SRCS ${ADD_IMPL_SRCS}
+    HDRS ${ADD_IMPL_HDRS}
+    DEPENDS ${ADD_IMPL_DEPENDS}
+    COMPILE_OPTIONS ${libc_opt_high_flag} ${ADD_IMPL_COMPILE_OPTIONS}
+  )
+  get_fq_target_name(${impl_name} fq_target_name)
+  set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}")
+  set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}")
+endfunction()
diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake
index 36f871920c3c33..84f3125d557eae 100644
--- a/libc/cmake/modules/LLVMLibCTestRules.cmake
+++ b/libc/cmake/modules/LLVMLibCTestRules.cmake
@@ -416,12 +416,12 @@ function(add_integration_test test_name)
       libc.test.IntegrationTest.test
       # We always add the memory functions objects. This is because the
       # compiler's codegen can emit calls to the C memory functions.
-      libc.src.string.bcmp
-      libc.src.string.bzero
       libc.src.string.memcmp
       libc.src.string.memcpy
       libc.src.string.memmove
       libc.src.string.memset
+      libc.src.strings.bcmp
+      libc.src.strings.bzero
   )
 
   if(libc.src.compiler.__stack_chk_fail IN_LIST TARGET_LLVMLIBC_ENTRYPOINTS)
@@ -583,13 +583,13 @@ function(add_libc_hermetic test_name)
       libc.startup.${LIBC_TARGET_OS}.crt1
       # We always add the memory functions objects. This is because the
       # compiler's codegen can emit calls to the C memory functions.
-      libc.src.string.bcmp
-      libc.src.string.bzero
+      libc.src.__support.StringUtil.error_to_string
       libc.src.string.memcmp
       libc.src.string.memcpy
       libc.src.string.memmove
       libc.src.string.memset
-      libc.src.__support.StringUtil.error_to_string
+      libc.src.strings.bcmp
+      libc.src.strings.bzero
   )
 
   if(libc.src.compiler.__stack_chk_fail IN_LIST TARGET_LLVMLIBC_ENTRYPOINTS)
@@ -766,3 +766,33 @@ function(add_libc_test test_name)
     endif()
   endif()
 endfunction(add_libc_test)
+
+# Tests all implementations that can run on the target CPU.
+function(add_libc_multi_impl_test name suite)
+  get_property(fq_implementations GLOBAL PROPERTY ${name}_implementations)
+  foreach(fq_config_name IN LISTS fq_implementations)
+    get_target_property(required_cpu_features ${fq_config_name} REQUIRE_CPU_FEATURES)
+    cpu_supports(can_run "${required_cpu_features}")
+    if(can_run)
+      string(FIND ${fq_config_name} "." last_dot_loc REVERSE)
+      math(EXPR name_loc "${last_dot_loc} + 1")
+      string(SUBSTRING ${fq_config_name} ${name_loc} -1 target_name)
+      add_libc_test(
+        ${target_name}_test
+        SUITE
+          ${suite}
+        COMPILE_OPTIONS
+          ${LIBC_COMPILE_OPTIONS_NATIVE}
+        LINK_LIBRARIES
+          LibcMemoryHelpers
+        ${ARGN}
+        DEPENDS
+          ${fq_config_name}
+          libc.src.__support.macros.sanitizer
+      )
+      get_fq_target_name(${fq_config_name}_test fq_target_name)
+    else()
+      message(STATUS "Skipping test for '${fq_config_name}' insufficient host cpu features '${required_cpu_features}'")
+    endif()
+  endforeach()
+endfunction()
diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt
index 9027717acb4dae..71b49d98942916 100644
--- a/libc/config/baremetal/arm/entrypoints.txt
+++ b/libc/config/baremetal/arm/entrypoints.txt
@@ -31,10 +31,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.setjmp.setjmp
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -45,10 +41,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memrchr
     libc.src.string.memset
     libc.src.string.memset_explicit
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -62,7 +56,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -76,6 +69,15 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strtok_r
     libc.src.string.strxfrm
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt
index afae2b3e082be3..e84d139d09dd8e 100644
--- a/libc/config/baremetal/riscv/entrypoints.txt
+++ b/libc/config/baremetal/riscv/entrypoints.txt
@@ -27,10 +27,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.errno.errno
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -41,10 +37,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memrchr
     libc.src.string.memset
     libc.src.string.memset_explicit
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -58,7 +52,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -72,6 +65,15 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strtok_r
     libc.src.string.strxfrm
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt
index 2d5dbeff485747..7972d285f963a4 100644
--- a/libc/config/darwin/arm/entrypoints.txt
+++ b/libc/config/darwin/arm/entrypoints.txt
@@ -21,9 +21,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.errno.errno
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -35,7 +32,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memset
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -46,7 +42,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -62,6 +57,13 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strdup
     libc.src.string.strndup
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt
index 64eeed18f3819e..19230cde471989 100644
--- a/libc/config/darwin/x86_64/entrypoints.txt
+++ b/libc/config/darwin/x86_64/entrypoints.txt
@@ -18,11 +18,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.toupper
 
     # search.h entrypoints
-    libc.src.search.lfind 
+    libc.src.search.lfind
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bzero
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -58,6 +56,10 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strdup
     libc.src.string.strndup
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bzero
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 38e9f2e685caed..e3ebd3ca472560 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -35,10 +35,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.toupper_l
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -48,10 +44,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.mempcpy
     libc.src.string.memrchr
     libc.src.string.memset
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -66,7 +60,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -82,6 +75,15 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strxfrm
     libc.src.string.strxfrm_l
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # stdbit.h entrypoints
     libc.src.stdbit.stdc_bit_ceil_uc
     libc.src.stdbit.stdc_bit_ceil_ui
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index effa5b12d87ac4..6b46f925cec288 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -45,10 +45,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sched.sched_yield
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -59,10 +55,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memrchr
     libc.src.string.memset
     libc.src.string.memset_explicit
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -77,7 +71,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -93,6 +86,15 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strtok_r
     libc.src.string.strxfrm
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 31d81de06fb6b0..7c83e09792f3b3 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -21,10 +21,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.errno.errno
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -34,10 +30,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.mempcpy
     libc.src.string.memrchr
     libc.src.string.memset
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -48,7 +42,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -61,6 +54,15 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strtok
     libc.src.string.strtok_r
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 5a48baf104159f..bd035c71f91646 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -45,10 +45,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sched.sched_yield
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -59,10 +55,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memrchr
     libc.src.string.memset
     libc.src.string.memset_explicit
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -77,7 +71,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -93,6 +86,14 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strtok_r
     libc.src.string.strxfrm
 
+    # strings.h entrypoints
+    libc.src.string.index
+    libc.src.string.rindex
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.strcasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 1bedc25a9d0291..aa2034bad23aca 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -45,10 +45,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sched.sched_yield
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
-    libc.src.string.index
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -59,10 +55,8 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memrchr
     libc.src.string.memset
     libc.src.string.memset_explicit
-    libc.src.string.rindex
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -77,7 +71,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -93,6 +86,15 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strtok_r
     libc.src.string.strxfrm
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.index
+    libc.src.strings.rindex
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt
index 8f0b50bcc83ea2..36dc08ce2cbc82 100644
--- a/libc/config/windows/entrypoints.txt
+++ b/libc/config/windows/entrypoints.txt
@@ -18,9 +18,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.ctype.toupper
 
     # string.h entrypoints
-    libc.src.string.bcmp
-    libc.src.string.bcopy
-    libc.src.string.bzero
     libc.src.string.memccpy
     libc.src.string.memchr
     libc.src.string.memcmp
@@ -32,7 +29,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.memset
     libc.src.string.stpcpy
     libc.src.string.stpncpy
-    libc.src.string.strcasecmp
     libc.src.string.strcasestr
     libc.src.string.strcat
     libc.src.string.strchr
@@ -43,7 +39,6 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strlcat
     libc.src.string.strlcpy
     libc.src.string.strlen
-    libc.src.string.strncasecmp
     libc.src.string.strncat
     libc.src.string.strncmp
     libc.src.string.strncpy
@@ -59,6 +54,13 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.string.strdup
     libc.src.string.strndup
 
+    # strings.h entrypoints
+    libc.src.strings.bcmp
+    libc.src.strings.bcopy
+    libc.src.strings.bzero
+    libc.src.strings.strcasecmp
+    libc.src.strings.strncasecmp
+
     # inttypes.h entrypoints
     libc.src.inttypes.imaxabs
     libc.src.inttypes.imaxdiv
diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt
index 9dd4fceee3b596..efda80b59c951f 100644
--- a/libc/fuzzing/string/CMakeLists.txt
+++ b/libc/fuzzing/string/CMakeLists.txt
@@ -38,5 +38,5 @@ add_libc_fuzzer(
   SRCS
     bcmp_fuzz.cpp
   DEPENDS
-    libc.src.string.bcmp
+    libc.src.strings.bcmp
 )
diff --git a/libc/fuzzing/string/bcmp_fuzz.cpp b/libc/fuzzing/string/bcmp_fuzz.cpp
index 65949dfdf0c562..710d115b0ae801 100644
--- a/libc/fuzzing/string/bcmp_fuzz.cpp
+++ b/libc/fuzzing/string/bcmp_fuzz.cpp
@@ -9,7 +9,7 @@
 /// Fuzzing test for llvm-libc bcmp implementation.
 ///
 //===----------------------------------------------------------------------===//
-#include "src/string/bcmp.h"
+#include "src/strings/bcmp.h"
 #include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
diff --git a/libc/hdr/func/free.h b/libc/hdr/func/free.h
index b1190a777da327..316556b21e3b08 100644
--- a/libc/hdr/func/free.h
+++ b/libc/hdr/func/free.h
@@ -10,7 +10,8 @@
 #define LLVM_LIBC_HDR_FUNC_FREE_H
 
 #ifdef LIBC_FULL_BUILD
-extern "C" void free(void *);
+
+extern "C" void free(void *) noexcept;
 
 #else // Overlay mode
 
diff --git a/libc/hdr/func/malloc.h b/libc/hdr/func/malloc.h
index b395f41f2bce26..8281021f799696 100644
--- a/libc/hdr/func/malloc.h
+++ b/libc/hdr/func/malloc.h
@@ -10,8 +10,10 @@
 #define LLVM_LIBC_HDR_FUNC_MALLOC_H
 
 #ifdef LIBC_FULL_BUILD
+
 #include "hdr/types/size_t.h"
-extern "C" void *malloc(size_t);
+
+extern "C" void *malloc(size_t) noexcept;
 
 #else // Overlay mode
 
diff --git a/libc/hdr/func/realloc.h b/libc/hdr/func/realloc.h
index 0096045e8330b5..ecb29541fe34ab 100644
--- a/libc/hdr/func/realloc.h
+++ b/libc/hdr/func/realloc.h
@@ -10,8 +10,10 @@
 #define LLVM_LIBC_HDR_FUNC_REALLOC_H
 
 #ifdef LIBC_FULL_BUILD
+
 #include "hdr/types/size_t.h"
-extern "C" void *realloc(void *ptr, size_t new_size);
+
+extern "C" void *realloc(void *ptr, size_t new_size) noexcept;
 
 #else // Overlay mode
 
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 02c193e635362e..c7dc4dc7ba0ea6 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -12,6 +12,7 @@ add_subdirectory(stdfix)
 add_subdirectory(stdio)
 add_subdirectory(stdlib)
 add_subdirectory(string)
+add_subdirectory(strings)
 add_subdirectory(wchar)
 
 if(${LIBC_TARGET_OS} STREQUAL "linux")
diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt
index 8fe1226dd6a7a5..e3faa543e630cc 100644
--- a/libc/src/string/CMakeLists.txt
+++ b/libc/src/string/CMakeLists.txt
@@ -34,24 +34,6 @@ add_header_library(
     libc.src.__support.macros.config
 )
 
-add_entrypoint_object(
-  bcopy
-  SRCS
-    bcopy.cpp
-  HDRS
-    bcopy.h
-)
-
-add_entrypoint_object(
-  index
-  SRCS
-    index.cpp
-  HDRS
-    index.h
-  DEPENDS
-    .string_utils
-)
-
 add_entrypoint_object(
   memccpy
   SRCS
@@ -98,16 +80,6 @@ add_entrypoint_object(
     memrchr.h
 )
 
-add_entrypoint_object(
-  rindex
-  SRCS
-    rindex.cpp
-  HDRS
-    rindex.h
-  DEPENDS
-    .string_utils
-)
-
 add_entrypoint_object(
   stpcpy
   SRCS
@@ -171,17 +143,6 @@ add_entrypoint_object(
     .memory_utils.inline_strcmp
 )
 
-add_entrypoint_object(
-  strcasecmp
-  SRCS
-    strcasecmp.cpp
-  HDRS
-    strcasecmp.h
-  DEPENDS
-    .memory_utils.inline_strcmp
-    libc.src.__support.ctype_utils
-)
-
 add_entrypoint_object(
   strcasestr
   SRCS
@@ -319,17 +280,6 @@ add_entrypoint_object(
     .memory_utils.inline_strcmp
 )
 
-add_entrypoint_object(
-  strncasecmp
-  SRCS
-    strncasecmp.cpp
-  HDRS
-    strncasecmp.h
-  DEPENDS
-    .memory_utils.inline_strcmp
-    libc.src.__support.ctype_utils
-)
-
 add_entrypoint_object(
   strncpy
   SRCS
@@ -475,102 +425,6 @@ add_entrypoint_object(
     .memory_utils.inline_memset
 )
 
-# Helper to define a function with multiple implementations
-# - Computes flags to satisfy required/rejected features and arch,
-# - Declares an entry point,
-# - Attach the REQUIRE_CPU_FEATURES property to the target,
-# - Add the fully qualified target to `${name}_implementations` global property for tests.
-function(add_implementation name impl_name)
-  cmake_parse_arguments(
-    "ADD_IMPL"
-    "" # Optional arguments
-    "" # Single value arguments
-    "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;MLLVM_COMPILE_OPTIONS" # Multi value arguments
-    ${ARGN})
-
-  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
-    # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication.
-    foreach(opt IN LISTS ADD_IMPL_MLLVM_COMPILE_OPTIONS)
-      list(APPEND ADD_IMPL_COMPILE_OPTIONS "SHELL:-mllvm ${opt}")
-    endforeach()
-  endif()
-
-  if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
-    # Prevent warning when passing x86 SIMD types as template arguments.
-    # e.g. "warning: ignoring attributes on template argument ā€˜__m128iā€™ [-Wignored-attributes]"
-    list(APPEND ADD_IMPL_COMPILE_OPTIONS "-Wno-ignored-attributes")
-  endif()
-
-  add_entrypoint_object(${impl_name}
-    NAME ${name}
-    SRCS ${ADD_IMPL_SRCS}
-    HDRS ${ADD_IMPL_HDRS}
-    DEPENDS ${ADD_IMPL_DEPENDS}
-    COMPILE_OPTIONS ${libc_opt_high_flag} ${ADD_IMPL_COMPILE_OPTIONS}
-  )
-  get_fq_target_name(${impl_name} fq_target_name)
-  set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}")
-  set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}")
-endfunction()
-
-# ------------------------------------------------------------------------------
-# bcmp
-# ------------------------------------------------------------------------------
-
-function(add_bcmp bcmp_name)
-  add_implementation(bcmp ${bcmp_name}
-    SRCS ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp
-    HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h
-    DEPENDS
-      .memory_utils.memory_utils
-      libc.include.string
-    ${ARGN}
-  )
-endfunction()
-
-if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
-  add_bcmp(bcmp_x86_64_opt_sse2   COMPILE_OPTIONS -march=k8             REQUIRE SSE2)
-  add_bcmp(bcmp_x86_64_opt_sse4   COMPILE_OPTIONS -march=nehalem        REQUIRE SSE4_2)
-  add_bcmp(bcmp_x86_64_opt_avx2   COMPILE_OPTIONS -march=haswell        REQUIRE AVX2)
-  add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512BW)
-  add_bcmp(bcmp_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
-  add_bcmp(bcmp)
-elseif(LIBC_TARGET_OS_IS_GPU)
-  add_bcmp(bcmp)
-else()
-  add_bcmp(bcmp_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
-  add_bcmp(bcmp)
-endif()
-
-# ------------------------------------------------------------------------------
-# bzero
-# ------------------------------------------------------------------------------
-
-function(add_bzero bzero_name)
-  add_implementation(bzero ${bzero_name}
-    SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp
-    HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h
-    DEPENDS
-      .memory_utils.inline_memset
-      libc.include.string
-    ${ARGN}
-  )
-endfunction()
-
-if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
-  add_bzero(bzero_x86_64_opt_sse2   COMPILE_OPTIONS -march=k8             REQUIRE SSE2)
-  add_bzero(bzero_x86_64_opt_sse4   COMPILE_OPTIONS -march=nehalem        REQUIRE SSE4_2)
-  add_bzero(bzero_x86_64_opt_avx2   COMPILE_OPTIONS -march=haswell        REQUIRE AVX2)
-  add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F)
-  add_bzero(bzero_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
-  add_bzero(bzero)
-elseif(LIBC_TARGET_OS_IS_GPU)
-  add_bzero(bzero)
-else()
-  add_bzero(bzero_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
-  add_bzero(bzero)
-endif()
-
 # ------------------------------------------------------------------------------
 # memcmp
 # ------------------------------------------------------------------------------
diff --git a/libc/src/strings/CMakeLists.txt b/libc/src/strings/CMakeLists.txt
new file mode 100644
index 00000000000000..9f710fe91a62bc
--- /dev/null
+++ b/libc/src/strings/CMakeLists.txt
@@ -0,0 +1,99 @@
+function(add_bcmp bcmp_name)
+  add_implementation(bcmp ${bcmp_name}
+    SRCS ${LIBC_SOURCE_DIR}/src/strings/bcmp.cpp
+    HDRS ${LIBC_SOURCE_DIR}/src/strings/bcmp.h
+    DEPENDS
+      libc.include.string
+      libc.src.string.memory_utils.memory_utils
+    ${ARGN}
+  )
+endfunction()
+
+if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
+  add_bcmp(bcmp_x86_64_opt_sse2   COMPILE_OPTIONS -march=k8             REQUIRE SSE2)
+  add_bcmp(bcmp_x86_64_opt_sse4   COMPILE_OPTIONS -march=nehalem        REQUIRE SSE4_2)
+  add_bcmp(bcmp_x86_64_opt_avx2   COMPILE_OPTIONS -march=haswell        REQUIRE AVX2)
+  add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512BW)
+  add_bcmp(bcmp_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
+  add_bcmp(bcmp)
+elseif(LIBC_TARGET_OS_IS_GPU)
+  add_bcmp(bcmp)
+else()
+  add_bcmp(bcmp_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
+  add_bcmp(bcmp)
+endif()
+
+function(add_bzero bzero_name)
+  add_implementation(bzero ${bzero_name}
+    SRCS ${LIBC_SOURCE_DIR}/src/strings/bzero.cpp
+    HDRS ${LIBC_SOURCE_DIR}/src/strings/bzero.h
+    DEPENDS
+      libc.include.string
+      libc.src.string.memory_utils.inline_memset
+    ${ARGN}
+  )
+endfunction()
+
+if(${LIBC_TARGET_ARCHITECTURE_IS_X86})
+  add_bzero(bzero_x86_64_opt_sse2   COMPILE_OPTIONS -march=k8             REQUIRE SSE2)
+  add_bzero(bzero_x86_64_opt_sse4   COMPILE_OPTIONS -march=nehalem        REQUIRE SSE4_2)
+  add_bzero(bzero_x86_64_opt_avx2   COMPILE_OPTIONS -march=haswell        REQUIRE AVX2)
+  add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F)
+  add_bzero(bzero_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
+  add_bzero(bzero)
+elseif(LIBC_TARGET_OS_IS_GPU)
+  add_bzero(bzero)
+else()
+  add_bzero(bzero_opt_host          COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE})
+  add_bzero(bzero)
+endif()
+
+add_entrypoint_object(
+  bcopy
+  SRCS
+    bcopy.cpp
+  HDRS
+    bcopy.h
+)
+
+add_entrypoint_object(
+  index
+  SRCS
+    index.cpp
+  HDRS
+    index.h
+  DEPENDS
+    libc.src.string.string_utils
+)
+
+add_entrypoint_object(
+  rindex
+  SRCS
+    rindex.cpp
+  HDRS
+    rindex.h
+  DEPENDS
+    libc.src.string.string_utils
+)
+
+add_entrypoint_object(
+  strcasecmp
+  SRCS
+    strcasecmp.cpp
+  HDRS
+    strcasecmp.h
+  DEPENDS
+    libc.src.__support.ctype_utils
+    libc.src.string.memory_utils.inline_strcmp
+)
+
+add_entrypoint_object(
+  strncasecmp
+  SRCS
+    strncasecmp.cpp
+  HDRS
+    strncasecmp.h
+  DEPENDS
+    libc.src.__support.ctype_utils
+    libc.src.string.memory_utils.inline_strcmp
+)
diff --git a/libc/src/string/bcmp.cpp b/libc/src/strings/bcmp.cpp
similarity index 95%
rename from libc/src/string/bcmp.cpp
rename to libc/src/strings/bcmp.cpp
index 6e9c9ae3b7a3b7..083f13d3f95d3a 100644
--- a/libc/src/string/bcmp.cpp
+++ b/libc/src/strings/bcmp.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/bcmp.h"
+#include "src/strings/bcmp.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/string/memory_utils/inline_bcmp.h"
diff --git a/libc/src/string/bcmp.h b/libc/src/strings/bcmp.h
similarity index 83%
rename from libc/src/string/bcmp.h
rename to libc/src/strings/bcmp.h
index a82b529164d950..46b4d7163b52e6 100644
--- a/libc/src/string/bcmp.h
+++ b/libc/src/strings/bcmp.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_BCMP_H
-#define LLVM_LIBC_SRC_STRING_BCMP_H
+#ifndef LLVM_LIBC_SRC_STRINGS_BCMP_H
+#define LLVM_LIBC_SRC_STRINGS_BCMP_H
 
 #include "src/__support/macros/config.h"
 #include <stddef.h> // size_t
@@ -18,4 +18,4 @@ int bcmp(const void *lhs, const void *rhs, size_t count);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_BCMP_H
+#endif // LLVM_LIBC_SRC_STRINGS_BCMP_H
diff --git a/libc/src/string/bcopy.cpp b/libc/src/strings/bcopy.cpp
similarity index 95%
rename from libc/src/string/bcopy.cpp
rename to libc/src/strings/bcopy.cpp
index 89aad71e354c7f..eb0358c1874727 100644
--- a/libc/src/string/bcopy.cpp
+++ b/libc/src/strings/bcopy.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/bcopy.h"
+#include "src/strings/bcopy.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/string/memory_utils/inline_memmove.h"
diff --git a/libc/src/string/bcopy.h b/libc/src/strings/bcopy.h
similarity index 83%
rename from libc/src/string/bcopy.h
rename to libc/src/strings/bcopy.h
index 4cf0263a7d6397..d8ee77e83c6d83 100644
--- a/libc/src/string/bcopy.h
+++ b/libc/src/strings/bcopy.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_BCOPY_H
-#define LLVM_LIBC_SRC_STRING_BCOPY_H
+#ifndef LLVM_LIBC_SRC_STRINGS_BCOPY_H
+#define LLVM_LIBC_SRC_STRINGS_BCOPY_H
 
 #include "src/__support/macros/config.h"
 #include <stddef.h> // size_t
@@ -18,4 +18,4 @@ void bcopy(const void *src, void *dest, size_t count);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_BCOPY_H
+#endif // LLVM_LIBC_SRC_STRINGS_BCOPY_H
diff --git a/libc/src/string/bzero.cpp b/libc/src/strings/bzero.cpp
similarity index 95%
rename from libc/src/string/bzero.cpp
rename to libc/src/strings/bzero.cpp
index 7bcbee3547b9b3..9c2e9700442af5 100644
--- a/libc/src/string/bzero.cpp
+++ b/libc/src/strings/bzero.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/bzero.h"
+#include "src/strings/bzero.h"
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
 #include "src/string/memory_utils/inline_bzero.h"
diff --git a/libc/src/string/bzero.h b/libc/src/strings/bzero.h
similarity index 82%
rename from libc/src/string/bzero.h
rename to libc/src/strings/bzero.h
index d9722197e8e8ba..3e270fe41f6cde 100644
--- a/libc/src/string/bzero.h
+++ b/libc/src/strings/bzero.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_BZERO_H
-#define LLVM_LIBC_SRC_STRING_BZERO_H
+#ifndef LLVM_LIBC_SRC_STRINGS_BZERO_H
+#define LLVM_LIBC_SRC_STRINGS_BZERO_H
 
 #include "src/__support/macros/config.h"
 #include <stddef.h> // size_t
@@ -18,4 +18,4 @@ void bzero(void *ptr, size_t count);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_BZERO_H
+#endif // LLVM_LIBC_SRC_STRINGS_BZERO_H
diff --git a/libc/src/string/index.cpp b/libc/src/strings/index.cpp
similarity index 95%
rename from libc/src/string/index.cpp
rename to libc/src/strings/index.cpp
index 46cf54825f6ce2..33b2be9f33e0d3 100644
--- a/libc/src/string/index.cpp
+++ b/libc/src/strings/index.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/index.h"
+#include "src/strings/index.h"
 
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
diff --git a/libc/src/string/index.h b/libc/src/strings/index.h
similarity index 81%
rename from libc/src/string/index.h
rename to libc/src/strings/index.h
index 9843bcdf9a573f..d382cdd249aa94 100644
--- a/libc/src/string/index.h
+++ b/libc/src/strings/index.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_INDEX_H
-#define LLVM_LIBC_SRC_STRING_INDEX_H
+#ifndef LLVM_LIBC_SRC_STRINGS_INDEX_H
+#define LLVM_LIBC_SRC_STRINGS_INDEX_H
 
 #include "src/__support/macros/config.h"
 
@@ -17,4 +17,4 @@ char *index(const char *src, int c);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_INDEX_H
+#endif // LLVM_LIBC_SRC_STRINGS_INDEX_H
diff --git a/libc/src/string/rindex.cpp b/libc/src/strings/rindex.cpp
similarity index 95%
rename from libc/src/string/rindex.cpp
rename to libc/src/strings/rindex.cpp
index 25879ddb07f627..1242e0faf85fc5 100644
--- a/libc/src/string/rindex.cpp
+++ b/libc/src/strings/rindex.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/rindex.h"
+#include "src/strings/rindex.h"
 
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
diff --git a/libc/src/string/rindex.h b/libc/src/strings/rindex.h
similarity index 81%
rename from libc/src/string/rindex.h
rename to libc/src/strings/rindex.h
index cfc35daa1f4d56..f8aa7b9be28f59 100644
--- a/libc/src/string/rindex.h
+++ b/libc/src/strings/rindex.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_RINDEX_H
-#define LLVM_LIBC_SRC_STRING_RINDEX_H
+#ifndef LLVM_LIBC_SRC_STRINGS_RINDEX_H
+#define LLVM_LIBC_SRC_STRINGS_RINDEX_H
 
 #include "src/__support/macros/config.h"
 
@@ -17,4 +17,4 @@ char *rindex(const char *src, int c);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_RINDEX_H
+#endif // LLVM_LIBC_SRC_STRINGS_RINDEX_H
diff --git a/libc/src/string/strcasecmp.cpp b/libc/src/strings/strcasecmp.cpp
similarity index 96%
rename from libc/src/string/strcasecmp.cpp
rename to libc/src/strings/strcasecmp.cpp
index 1274c047fc28ef..4bbe2909df1e28 100644
--- a/libc/src/string/strcasecmp.cpp
+++ b/libc/src/strings/strcasecmp.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/strcasecmp.h"
+#include "src/strings/strcasecmp.h"
 
 #include "src/__support/common.h"
 #include "src/__support/ctype_utils.h"
diff --git a/libc/src/string/strcasecmp.h b/libc/src/strings/strcasecmp.h
similarity index 80%
rename from libc/src/string/strcasecmp.h
rename to libc/src/strings/strcasecmp.h
index 2916b8d417075c..b02fb316158790 100644
--- a/libc/src/string/strcasecmp.h
+++ b/libc/src/strings/strcasecmp.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_STRCASECMP_H
-#define LLVM_LIBC_SRC_STRING_STRCASECMP_H
+#ifndef LLVM_LIBC_SRC_STRINGS_STRCASECMP_H
+#define LLVM_LIBC_SRC_STRINGS_STRCASECMP_H
 
 #include "src/__support/macros/config.h"
 
@@ -17,4 +17,4 @@ int strcasecmp(const char *left, const char *right);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_STRCASECMP_H
+#endif // LLVM_LIBC_SRC_STRINGS_STRCASECMP_H
diff --git a/libc/src/string/strncasecmp.cpp b/libc/src/strings/strncasecmp.cpp
similarity index 96%
rename from libc/src/string/strncasecmp.cpp
rename to libc/src/strings/strncasecmp.cpp
index 45f82c98069b29..9c2f0ab1312690 100644
--- a/libc/src/string/strncasecmp.cpp
+++ b/libc/src/strings/strncasecmp.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/strncasecmp.h"
+#include "src/strings/strncasecmp.h"
 
 #include "src/__support/common.h"
 #include "src/__support/ctype_utils.h"
diff --git a/libc/src/string/strncasecmp.h b/libc/src/strings/strncasecmp.h
similarity index 80%
rename from libc/src/string/strncasecmp.h
rename to libc/src/strings/strncasecmp.h
index 15f74994ca56d8..59df517058910f 100644
--- a/libc/src/string/strncasecmp.h
+++ b/libc/src/strings/strncasecmp.h
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIBC_SRC_STRING_STRNCASECMP_H
-#define LLVM_LIBC_SRC_STRING_STRNCASECMP_H
+#ifndef LLVM_LIBC_SRC_STRINGS_STRNCASECMP_H
+#define LLVM_LIBC_SRC_STRINGS_STRNCASECMP_H
 
 #include "src/__support/macros/config.h"
 #include <stddef.h>
@@ -18,4 +18,4 @@ int strncasecmp(const char *left, const char *right, size_t n);
 
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC_STRING_STRNCASECMP_H
+#endif // LLVM_LIBC_SRC_STRINGS_STRNCASECMP_H
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 8ac8f91e98d4cc..3e0bbc8a9406a7 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -58,6 +58,7 @@ add_subdirectory(stdfix)
 add_subdirectory(stdio)
 add_subdirectory(stdlib)
 add_subdirectory(string)
+add_subdirectory(strings)
 add_subdirectory(wchar)
 
 # Depends on utilities in stdlib
diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt
index b6b59a689cc8fa..a675373938e996 100644
--- a/libc/test/src/string/CMakeLists.txt
+++ b/libc/test/src/string/CMakeLists.txt
@@ -2,35 +2,12 @@ add_custom_target(libc-string-tests)
 
 add_subdirectory(memory_utils)
 
-add_libc_test(
-  bcopy_test
-  SUITE
-    libc-string-tests
-  SRCS
-    bcopy_test.cpp
-  DEPENDS
-    libc.src.string.bcopy
-  LINK_LIBRARIES
-    LibcMemoryHelpers
-)
-
 add_header_library(
   strchr_test_support
   HDRS
     StrchrTest.h
 )
 
-add_libc_test(
-  index_test
-  SUITE
-    libc-string-tests
-  SRCS
-    index_test.cpp
-  DEPENDS
-    libc.src.string.index
-    .strchr_test_support
-)
-
 add_libc_test(
   memccpy_test
   SUITE
@@ -81,17 +58,6 @@ add_libc_test(
     libc.src.string.memrchr
 )
 
-add_libc_test(
-  rindex_test
-  SUITE
-    libc-string-tests
-  SRCS
-    rindex_test.cpp
-  DEPENDS
-    libc.src.string.rindex
-    .strchr_test_support
-)
-
 add_libc_test(
   stpcpy_test
   SUITE
@@ -153,16 +119,6 @@ add_libc_test(
     libc.src.string.strcmp
 )
 
-add_libc_test(
-  strcasecmp_test
-  SUITE
-    libc-string-tests
-  SRCS
-    strcasecmp_test.cpp
-  DEPENDS
-    libc.src.string.strcasecmp
-)
-
 add_libc_test(
   strcasestr_test
   SUITE
@@ -287,16 +243,6 @@ add_libc_test(
     libc.src.string.strncmp
 )
 
-add_libc_test(
-  strncasecmp_test
-  SUITE
-    libc-string-tests
-  SRCS
-    strncasecmp_test.cpp
-  DEPENDS
-    libc.src.string.strncasecmp
-)
-
 add_libc_test(
   strncpy_test
   SUITE
@@ -428,39 +374,7 @@ add_libc_test(
     libc.src.string.memset_explicit
 )
 
-# Tests all implementations that can run on the target CPU.
-function(add_libc_multi_impl_test name)
-  get_property(fq_implementations GLOBAL PROPERTY ${name}_implementations)
-  foreach(fq_config_name IN LISTS fq_implementations)
-    get_target_property(required_cpu_features ${fq_config_name} REQUIRE_CPU_FEATURES)
-    cpu_supports(can_run "${required_cpu_features}")
-    if(can_run)
-      string(FIND ${fq_config_name} "." last_dot_loc REVERSE)
-      math(EXPR name_loc "${last_dot_loc} + 1")
-      string(SUBSTRING ${fq_config_name} ${name_loc} -1 target_name)
-      add_libc_test(
-        ${target_name}_test
-        SUITE
-          libc-string-tests
-        COMPILE_OPTIONS
-          ${LIBC_COMPILE_OPTIONS_NATIVE}
-        LINK_LIBRARIES
-          LibcMemoryHelpers
-        ${ARGN}
-        DEPENDS
-          ${fq_config_name}
-          libc.src.__support.macros.sanitizer
-      )
-      get_fq_target_name(${fq_config_name}_test fq_target_name)
-    else()
-      message(STATUS "Skipping test for '${fq_config_name}' insufficient host cpu features '${required_cpu_features}'")
-    endif()
-  endforeach()
-endfunction()
-
-add_libc_multi_impl_test(bcmp SRCS bcmp_test.cpp)
-add_libc_multi_impl_test(bzero SRCS bzero_test.cpp)
-add_libc_multi_impl_test(memcmp SRCS memcmp_test.cpp)
-add_libc_multi_impl_test(memcpy SRCS memcpy_test.cpp)
-add_libc_multi_impl_test(memmove SRCS memmove_test.cpp)
-add_libc_multi_impl_test(memset SRCS memset_test.cpp)
+add_libc_multi_impl_test(memcmp libc-string-tests SRCS memcmp_test.cpp)
+add_libc_multi_impl_test(memcpy libc-string-tests SRCS memcpy_test.cpp)
+add_libc_multi_impl_test(memmove libc-string-tests SRCS memmove_test.cpp)
+add_libc_multi_impl_test(memset libc-string-tests SRCS memset_test.cpp)
diff --git a/libc/test/src/string/memory_utils/op_tests.cpp b/libc/test/src/string/memory_utils/op_tests.cpp
index c6197d1afa266b..fee0bca75ed05a 100644
--- a/libc/test/src/string/memory_utils/op_tests.cpp
+++ b/libc/test/src/string/memory_utils/op_tests.cpp
@@ -246,6 +246,7 @@ int CmpBlockAdaptor(cpp::span<char> p1, cpp::span<char> p2, size_t size) {
   return (int)FnImpl(as_byte(p1), as_byte(p2));
 }
 
+// TODO: should testing of bcmp be moved to libc/test/src/strings/ dir?
 TYPED_TEST(LlvmLibcOpTest, Bcmp, BcmpImplementations) {
   using Impl = ParamType;
   constexpr size_t kSize = Impl::SIZE;
diff --git a/libc/test/src/string/bcmp_test.cpp b/libc/test/src/strings/bcmp_test.cpp
similarity index 95%
rename from libc/test/src/string/bcmp_test.cpp
rename to libc/test/src/strings/bcmp_test.cpp
index c639040685e191..794f9a1b8bd9de 100644
--- a/libc/test/src/string/bcmp_test.cpp
+++ b/libc/test/src/strings/bcmp_test.cpp
@@ -6,11 +6,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "memory_utils/memory_check_utils.h"
 #include "src/__support/macros/config.h"
-#include "src/string/bcmp.h"
+#include "src/strings/bcmp.h"
 #include "test/UnitTest/Test.h"
 #include "test/UnitTest/TestLogger.h"
+#include "test/src/string/memory_utils/memory_check_utils.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/test/src/string/bcopy_test.cpp b/libc/test/src/strings/bcopy_test.cpp
similarity index 97%
rename from libc/test/src/string/bcopy_test.cpp
rename to libc/test/src/strings/bcopy_test.cpp
index 04772bb5d8ad76..f6bb859b4ae9f8 100644
--- a/libc/test/src/string/bcopy_test.cpp
+++ b/libc/test/src/strings/bcopy_test.cpp
@@ -6,13 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/__support/macros/config.h"
-#include "src/string/bcopy.h"
+#include "src/strings/bcopy.h"
 
-#include "memory_utils/memory_check_utils.h"
 #include "src/__support/CPP/span.h"
+#include "src/__support/macros/config.h"
 #include "test/UnitTest/MemoryMatcher.h"
 #include "test/UnitTest/Test.h"
+#include "test/src/string/memory_utils/memory_check_utils.h"
 
 using LIBC_NAMESPACE::cpp::array;
 using LIBC_NAMESPACE::cpp::span;
diff --git a/libc/test/src/string/bzero_test.cpp b/libc/test/src/strings/bzero_test.cpp
similarity index 91%
rename from libc/test/src/string/bzero_test.cpp
rename to libc/test/src/strings/bzero_test.cpp
index a24043613bed7b..4d4112f4be8ee1 100644
--- a/libc/test/src/string/bzero_test.cpp
+++ b/libc/test/src/strings/bzero_test.cpp
@@ -6,10 +6,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "memory_utils/memory_check_utils.h"
 #include "src/__support/macros/config.h"
-#include "src/string/bzero.h"
+#include "src/strings/bzero.h"
 #include "test/UnitTest/Test.h"
+#include "test/src/string/memory_utils/memory_check_utils.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
diff --git a/libc/test/src/string/index_test.cpp b/libc/test/src/strings/index_test.cpp
similarity index 100%
rename from libc/test/src/string/index_test.cpp
rename to libc/test/src/strings/index_test.cpp
diff --git a/libc/test/src/string/rindex_test.cpp b/libc/test/src/strings/rindex_test.cpp
similarity index 100%
rename from libc/test/src/string/rindex_test.cpp
rename to libc/test/src/strings/rindex_test.cpp
diff --git a/libc/test/src/string/strcasecmp_test.cpp b/libc/test/src/strings/strcasecmp_test.cpp
similarity index 97%
rename from libc/test/src/string/strcasecmp_test.cpp
rename to libc/test/src/strings/strcasecmp_test.cpp
index df7888168c69e0..cd29c213a73249 100644
--- a/libc/test/src/string/strcasecmp_test.cpp
+++ b/libc/test/src/strings/strcasecmp_test.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/strcasecmp.h"
+#include "src/strings/strcasecmp.h"
 #include "test/UnitTest/Test.h"
 
 TEST(LlvmLibcStrCaseCmpTest, EmptyStringsShouldReturnZero) {
diff --git a/libc/test/src/string/strncasecmp_test.cpp b/libc/test/src/strings/strncasecmp_test.cpp
similarity index 97%
rename from libc/test/src/string/strncasecmp_test.cpp
rename to libc/test/src/strings/strncasecmp_test.cpp
index b4173c455de91b..870574ed9507ca 100644
--- a/libc/test/src/string/strncasecmp_test.cpp
+++ b/libc/test/src/strings/strncasecmp_test.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "src/string/strncasecmp.h"
+#include "src/strings/strncasecmp.h"
 #include "test/UnitTest/Test.h"
 
 TEST(LlvmLibcStrNCaseCmpTest,

>From 9bf601fb32f8a0e882b3d0edd53c9e66657182b4 Mon Sep 17 00:00:00 2001
From: Nick Desaulniers <ndesaulniers at google.com>
Date: Mon, 9 Dec 2024 10:09:38 -0800
Subject: [PATCH 2/2] git add file I forgot

---
 libc/test/src/strings/CMakeLists.txt | 58 ++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 libc/test/src/strings/CMakeLists.txt

diff --git a/libc/test/src/strings/CMakeLists.txt b/libc/test/src/strings/CMakeLists.txt
new file mode 100644
index 00000000000000..963a1d6d6d60c0
--- /dev/null
+++ b/libc/test/src/strings/CMakeLists.txt
@@ -0,0 +1,58 @@
+add_custom_target(libc-strings-tests)
+
+add_libc_test(
+  bcopy_test
+  SUITE
+    libc-strings-tests
+  SRCS
+    bcopy_test.cpp
+  DEPENDS
+    libc.src.strings.bcopy
+  LINK_LIBRARIES
+    LibcMemoryHelpers
+)
+
+add_libc_test(
+  index_test
+  SUITE
+    libc-strings-tests
+  SRCS
+    index_test.cpp
+  DEPENDS
+    libc.src.strings.index
+    libc.test.src.strchr_test_support
+)
+
+add_libc_test(
+  rindex_test
+  SUITE
+    libc-strings-tests
+  SRCS
+    rindex_test.cpp
+  DEPENDS
+    libc.src.strings.rindex
+    libc.test.src.strchr_test_support
+)
+
+add_libc_test(
+  strcasecmp_test
+  SUITE
+    libc-strings-tests
+  SRCS
+    strcasecmp_test.cpp
+  DEPENDS
+    libc.src.strings.strcasecmp
+)
+
+add_libc_test(
+  strncasecmp_test
+  SUITE
+    libc-strings-tests
+  SRCS
+    strncasecmp_test.cpp
+  DEPENDS
+    libc.src.strings.strncasecmp
+)
+
+add_libc_multi_impl_test(bcmp libc-strings-tests SRCS bcmp_test.cpp)
+add_libc_multi_impl_test(bzero libc-strings-tests SRCS bzero_test.cpp)



More information about the libc-commits mailing list