Skip to content

Commit

Permalink
Reland: "[libc] Templatize str{,n}cmp"
Browse files Browse the repository at this point in the history
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
  • Loading branch information
abrachet committed Jan 10, 2023
1 parent 44a080e commit f296dce
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 17 deletions.
4 changes: 4 additions & 0 deletions libc/src/string/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ add_entrypoint_object(
strcmp.cpp
HDRS
strcmp.h
DEPENDS
.memory_utils.strcmp_implementation
)

add_entrypoint_object(
Expand Down Expand Up @@ -226,6 +228,8 @@ add_entrypoint_object(
strncmp.cpp
HDRS
strncmp.h
DEPENDS
.memory_utils.strcmp_implementation
)

add_entrypoint_object(
Expand Down
6 changes: 6 additions & 0 deletions libc/src/string/memory_utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,9 @@ add_header_library(
DEPS
.memset_implementation
)

add_header_library(
strcmp_implementation
HDRS
strcmp_implementations.h
)
44 changes: 44 additions & 0 deletions libc/src/string/memory_utils/strcmp_implementations.h
Original file line number Diff line number Diff line change
@@ -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 <stddef.h>

namespace __llvm_libc {

template <typename Comp>
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<const unsigned char *>(left),
*reinterpret_cast<const unsigned char *>(right));
}

template <typename Comp>
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<const unsigned char *>(left),
*reinterpret_cast<const unsigned char *>(right));
}

} // namespace __llvm_libc

#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H
8 changes: 3 additions & 5 deletions libc/src/string/strcmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<const unsigned char *>(left) -
*reinterpret_cast<const unsigned char *>(right);
auto comp = [](char l, char r) -> int { return l - r; };
return strcmp_implementation(left, right, comp);
}

} // namespace __llvm_libc
16 changes: 4 additions & 12 deletions libc/src/string/strncmp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,16 @@
#include "src/string/strncmp.h"

#include "src/__support/common.h"
#include "src/string/memory_utils/strcmp_implementations.h"

#include <stddef.h>

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<const unsigned char *>(left) -
*reinterpret_cast<const unsigned char *>(right);
auto comp = [](char l, char r) -> int { return l - r; };
return strncmp_implementation(left, right, n, comp);
}

} // namespace __llvm_libc
2 changes: 2 additions & 0 deletions utils/bazel/llvm-project-overlay/libc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -1270,6 +1271,7 @@ libc_function(
hdrs = ["src/string/strcmp.h"],
deps = [
":__support_common",
":string_memory_utils",
":string_utils",
],
)
Expand Down

0 comments on commit f296dce

Please sign in to comment.