[libc-commits] [libc] [libc] Enable remaining string functions on the GPU (PR #68346)
Joseph Huber via libc-commits
libc-commits at lists.llvm.org
Mon Oct 23 10:08:11 PDT 2023
https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/68346
>From 28dec98632ace2e48d57736bb9eb9db311f46aaf Mon Sep 17 00:00:00 2001
From: Joseph Huber <jhuber6 at vols.utk.edu>
Date: Fri, 29 Sep 2023 18:50:10 -0500
Subject: [PATCH] [libc] Enable remaining string functions on the GPU
Summary:
We previously had to disable these string functions because they were
not compatible with the definitions coming from the GNU / host
environment. The GPU, when exporting its declarations, has a very
difficult requirement that it be compatible with the host environment as
both sides of the compilation need to agree on definitions and what's
present.
This patch more or less gives up an just copies the definitions as
expected by `glibc` if they are provided that way, otherwise we fall
back to the accepted way. This is the alternative solution to an
existing PR which instead disable's GCC's handling.
---
clang/lib/Headers/llvm_libc_wrappers/string.h | 65 ++++++++++++++++++-
libc/config/gpu/entrypoints.txt | 16 +++++
libc/docs/gpu/support.rst | 27 +++++---
3 files changed, 97 insertions(+), 11 deletions(-)
diff --git a/clang/lib/Headers/llvm_libc_wrappers/string.h b/clang/lib/Headers/llvm_libc_wrappers/string.h
index 027c415c1d0f8f3..b4fbf17c7e421f7 100644
--- a/clang/lib/Headers/llvm_libc_wrappers/string.h
+++ b/clang/lib/Headers/llvm_libc_wrappers/string.h
@@ -13,9 +13,6 @@
#error "This file is for GPU offloading compilation only"
#endif
-// FIXME: The GNU headers provide C++ standard compliant headers when in C++
-// mode and the LLVM libc does not. We cannot enable memchr, strchr, strchrnul,
-// strpbrk, strrchr, strstr, or strcasestr until this is addressed.
#include_next <string.h>
#if __has_include(<llvm-libc-decls/string.h>)
@@ -26,8 +23,70 @@
#pragma omp begin declare target
+// The GNU headers provide C++ standard compliant headers when in C++ mode and
+// the LLVM libc does not. We need to manually provide the definitions using the
+// same prototypes.
+#if defined(__cplusplus) && defined(__GLIBC__) && \
+ defined(__CORRECT_ISO_CPP_STRING_H_PROTO)
+
+#ifndef __LIBC_ATTRS
+#define __LIBC_ATTRS
+#endif
+
+extern "C" {
+void *memccpy(void *__restrict, const void *__restrict, int,
+ size_t) __LIBC_ATTRS;
+int memcmp(const void *, const void *, size_t) __LIBC_ATTRS;
+void *memcpy(void *__restrict, const void *__restrict, size_t) __LIBC_ATTRS;
+void *memmem(const void *, size_t, const void *, size_t) __LIBC_ATTRS;
+void *memmove(void *, const void *, size_t) __LIBC_ATTRS;
+void *mempcpy(void *__restrict, const void *__restrict, size_t) __LIBC_ATTRS;
+void *memset(void *, int, size_t) __LIBC_ATTRS;
+char *stpcpy(char *__restrict, const char *__restrict) __LIBC_ATTRS;
+char *stpncpy(char *__restrict, const char *__restrict, size_t) __LIBC_ATTRS;
+char *strcat(char *__restrict, const char *__restrict) __LIBC_ATTRS;
+int strcmp(const char *, const char *) __LIBC_ATTRS;
+int strcoll(const char *, const char *) __LIBC_ATTRS;
+char *strcpy(char *__restrict, const char *__restrict) __LIBC_ATTRS;
+size_t strcspn(const char *, const char *) __LIBC_ATTRS;
+char *strdup(const char *) __LIBC_ATTRS;
+size_t strlen(const char *) __LIBC_ATTRS;
+char *strncat(char *, const char *, size_t) __LIBC_ATTRS;
+int strncmp(const char *, const char *, size_t) __LIBC_ATTRS;
+char *strncpy(char *__restrict, const char *__restrict, size_t) __LIBC_ATTRS;
+char *strndup(const char *, size_t) __LIBC_ATTRS;
+size_t strnlen(const char *, size_t) __LIBC_ATTRS;
+size_t strspn(const char *, const char *) __LIBC_ATTRS;
+char *strtok(char *__restrict, const char *) __LIBC_ATTRS;
+char *strtok_r(char *__restrict, const char *__restrict,
+ char **__restrict) __LIBC_ATTRS;
+size_t strxfrm(char *__restrict, const char *__restrict, size_t) __LIBC_ATTRS;
+}
+
+extern "C++" {
+char *strstr(char *, const char *) noexcept __LIBC_ATTRS;
+const char *strstr(const char *, const char *) noexcept __LIBC_ATTRS;
+char *strpbrk(char *, const char *) noexcept __LIBC_ATTRS;
+const char *strpbrk(const char *, const char *) noexcept __LIBC_ATTRS;
+char *strrchr(char *, int) noexcept __LIBC_ATTRS;
+const char *strrchr(const char *, int) noexcept __LIBC_ATTRS;
+char *strchr(char *, int) noexcept __LIBC_ATTRS;
+const char *strchr(const char *, int) noexcept __LIBC_ATTRS;
+char *strchrnul(char *, int) noexcept __LIBC_ATTRS;
+const char *strchrnul(const char *, int) noexcept __LIBC_ATTRS;
+char *strcasestr(char *, const char *) noexcept __LIBC_ATTRS;
+const char *strcasestr(const char *, const char *) noexcept __LIBC_ATTRS;
+void *memrchr(void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
+const void *memrchr(const void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
+void *memchr(void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
+const void *memchr(const void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
+}
+
+#else
#include <llvm-libc-decls/string.h>
+#endif
+
#pragma omp end declare target
#undef __LIBC_ATTRS
diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt
index 756cddb0e8e5287..5dda6aa71d36f81 100644
--- a/libc/config/gpu/entrypoints.txt
+++ b/libc/config/gpu/entrypoints.txt
@@ -22,21 +22,31 @@ set(TARGET_LIBC_ENTRYPOINTS
# 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
libc.src.string.memcpy
libc.src.string.memmem
libc.src.string.memmove
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
+ libc.src.string.strchrnul
libc.src.string.strcmp
+ libc.src.string.strcoll
libc.src.string.strcpy
libc.src.string.strcspn
+ libc.src.string.strdup
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
@@ -44,10 +54,16 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
+ libc.src.string.strndup
libc.src.string.strnlen
+ libc.src.string.strpbrk
+ libc.src.string.strrchr
+ libc.src.string.strsep
libc.src.string.strspn
+ libc.src.string.strstr
libc.src.string.strtok
libc.src.string.strtok_r
+ libc.src.string.strxfrm
# stdlib.h entrypoints
libc.src.stdlib.abs
diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst
index 806af5f219dfb43..250f0a7794de3cf 100644
--- a/libc/docs/gpu/support.rst
+++ b/libc/docs/gpu/support.rst
@@ -45,37 +45,48 @@ string.h
Function Name Available RPC Required
============= ========= ============
bcmp |check|
+bcopy |check|
bzero |check|
+index |check|
memccpy |check|
-memchr
+memchr |check|
memcmp |check|
memcpy |check|
+memmem |check|
memmove |check|
mempcpy |check|
-memrchr
+memrchr |check|
memset |check|
+rindex |check|
stpcpy |check|
stpncpy |check|
+strcasecmp |check|
+strcasestr |check|
strcat |check|
-strchr
+strchr |check|
+strchrnul |check|
strcmp |check|
+strcoll |check|
strcpy |check|
strcspn |check|
+strdup |check|
strlcat |check|
strlcpy |check|
strlen |check|
+strncasecmp |check|
strncat |check|
strncmp |check|
strncpy |check|
+strndup |check|
strnlen |check|
-strpbrk
-strrchr
+strpbrk |check|
+strrchr |check|
+strsep |check|
strspn |check|
-strstr
+strstr |check|
strtok |check|
strtok_r |check|
-strdup
-strndup
+strxfrm |check|
============= ========= ============
stdlib.h
More information about the libc-commits
mailing list