From f296dce763f99beb6c23f05ea8f7480515b5f6a9 Mon Sep 17 00:00:00 2001 From: Alex Brachet Date: Tue, 10 Jan 2023 15:37:58 +0000 Subject: [PATCH] Reland: "[libc] Templatize str{,n}cmp" This will be used to implement the case insensitive str{,n}casecmp This was initially reverted because it broke tests on arm platforms. Unfortunately, it didn't break on my arm machine, but I suspect the problem was the old comparator returned char and not int. Differential Revision: https://reviews.llvm.org/D141235 --- libc/src/string/CMakeLists.txt | 4 ++ libc/src/string/memory_utils/CMakeLists.txt | 6 +++ .../string/memory_utils/strcmp_implementations.h | 44 ++++++++++++++++++++++ libc/src/string/strcmp.cpp | 8 ++-- libc/src/string/strncmp.cpp | 16 ++------ utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 2 + 6 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 libc/src/string/memory_utils/strcmp_implementations.h diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 0faa1db..cdce0bc 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -111,6 +111,8 @@ add_entrypoint_object( strcmp.cpp HDRS strcmp.h + DEPENDS + .memory_utils.strcmp_implementation ) add_entrypoint_object( @@ -226,6 +228,8 @@ add_entrypoint_object( strncmp.cpp HDRS strncmp.h + DEPENDS + .memory_utils.strcmp_implementation ) add_entrypoint_object( diff --git a/libc/src/string/memory_utils/CMakeLists.txt b/libc/src/string/memory_utils/CMakeLists.txt index 3bf81e9..10e14e1 100644 --- a/libc/src/string/memory_utils/CMakeLists.txt +++ b/libc/src/string/memory_utils/CMakeLists.txt @@ -60,3 +60,9 @@ add_header_library( DEPS .memset_implementation ) + +add_header_library( + strcmp_implementation + HDRS + strcmp_implementations.h +) diff --git a/libc/src/string/memory_utils/strcmp_implementations.h b/libc/src/string/memory_utils/strcmp_implementations.h new file mode 100644 index 0000000..3a7caee --- /dev/null +++ b/libc/src/string/memory_utils/strcmp_implementations.h @@ -0,0 +1,44 @@ +//===-- str{,case}cmp implementation ----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H +#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H + +#include + +namespace __llvm_libc { + +template +constexpr static int strcmp_implementation(const char *left, const char *right, + Comp &&comp) { + // TODO: Look at benefits for comparing words at a time. + for (; *left && !comp(*left, *right); ++left, ++right) + ; + return comp(*reinterpret_cast(left), + *reinterpret_cast(right)); +} + +template +constexpr static int strncmp_implementation(const char *left, const char *right, + size_t n, Comp &&comp) { + if (n == 0) + return 0; + + // TODO: Look at benefits for comparing words at a time. + for (; n > 1; --n, ++left, ++right) { + char lc = *left; + if (!comp(lc, '\0') || comp(lc, *right)) + break; + } + return comp(*reinterpret_cast(left), + *reinterpret_cast(right)); +} + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H diff --git a/libc/src/string/strcmp.cpp b/libc/src/string/strcmp.cpp index 8468b3c..72a490c 100644 --- a/libc/src/string/strcmp.cpp +++ b/libc/src/string/strcmp.cpp @@ -9,15 +9,13 @@ #include "src/string/strcmp.h" #include "src/__support/common.h" +#include "src/string/memory_utils/strcmp_implementations.h" namespace __llvm_libc { -// TODO: Look at benefits for comparing words at a time. LLVM_LIBC_FUNCTION(int, strcmp, (const char *left, const char *right)) { - for (; *left && *left == *right; ++left, ++right) - ; - return *reinterpret_cast(left) - - *reinterpret_cast(right); + auto comp = [](char l, char r) -> int { return l - r; }; + return strcmp_implementation(left, right, comp); } } // namespace __llvm_libc diff --git a/libc/src/string/strncmp.cpp b/libc/src/string/strncmp.cpp index 94960e5..b850663 100644 --- a/libc/src/string/strncmp.cpp +++ b/libc/src/string/strncmp.cpp @@ -9,24 +9,16 @@ #include "src/string/strncmp.h" #include "src/__support/common.h" +#include "src/string/memory_utils/strcmp_implementations.h" + #include namespace __llvm_libc { -// TODO: Look at benefits for comparing words at a time. LLVM_LIBC_FUNCTION(int, strncmp, (const char *left, const char *right, size_t n)) { - - if (n == 0) - return 0; - - for (; n > 1; --n, ++left, ++right) { - char lc = *left; - if (lc == '\0' || lc != *right) - break; - } - return *reinterpret_cast(left) - - *reinterpret_cast(right); + auto comp = [](char l, char r) -> int { return l - r; }; + return strncmp_implementation(left, right, n, comp); } } // namespace __llvm_libc diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index d75e578..534ecfd 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -1089,6 +1089,7 @@ libc_support_library( "src/string/memory_utils/memcpy_implementations.h", "src/string/memory_utils/memmove_implementations.h", "src/string/memory_utils/memset_implementations.h", + "src/string/memory_utils/strcmp_implementations.h", ], deps = [ ":__support_common", @@ -1270,6 +1271,7 @@ libc_function( hdrs = ["src/string/strcmp.h"], deps = [ ":__support_common", + ":string_memory_utils", ":string_utils", ], ) -- 2.7.4