Skip to content

Commit 25bf1ae

Browse files
authored
[libc] Enable remaining string functions on the GPU (#68346)
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.
1 parent fe92977 commit 25bf1ae

File tree

3 files changed

+97
-11
lines changed

3 files changed

+97
-11
lines changed

clang/lib/Headers/llvm_libc_wrappers/string.h

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
#error "This file is for GPU offloading compilation only"
1414
#endif
1515

16-
// FIXME: The GNU headers provide C++ standard compliant headers when in C++
17-
// mode and the LLVM libc does not. We cannot enable memchr, strchr, strchrnul,
18-
// strpbrk, strrchr, strstr, or strcasestr until this is addressed.
1916
#include_next <string.h>
2017

2118
#if __has_include(<llvm-libc-decls/string.h>)
@@ -26,8 +23,70 @@
2623

2724
#pragma omp begin declare target
2825

26+
// The GNU headers provide C++ standard compliant headers when in C++ mode and
27+
// the LLVM libc does not. We need to manually provide the definitions using the
28+
// same prototypes.
29+
#if defined(__cplusplus) && defined(__GLIBC__) && \
30+
defined(__CORRECT_ISO_CPP_STRING_H_PROTO)
31+
32+
#ifndef __LIBC_ATTRS
33+
#define __LIBC_ATTRS
34+
#endif
35+
36+
extern "C" {
37+
void *memccpy(void *__restrict, const void *__restrict, int,
38+
size_t) __LIBC_ATTRS;
39+
int memcmp(const void *, const void *, size_t) __LIBC_ATTRS;
40+
void *memcpy(void *__restrict, const void *__restrict, size_t) __LIBC_ATTRS;
41+
void *memmem(const void *, size_t, const void *, size_t) __LIBC_ATTRS;
42+
void *memmove(void *, const void *, size_t) __LIBC_ATTRS;
43+
void *mempcpy(void *__restrict, const void *__restrict, size_t) __LIBC_ATTRS;
44+
void *memset(void *, int, size_t) __LIBC_ATTRS;
45+
char *stpcpy(char *__restrict, const char *__restrict) __LIBC_ATTRS;
46+
char *stpncpy(char *__restrict, const char *__restrict, size_t) __LIBC_ATTRS;
47+
char *strcat(char *__restrict, const char *__restrict) __LIBC_ATTRS;
48+
int strcmp(const char *, const char *) __LIBC_ATTRS;
49+
int strcoll(const char *, const char *) __LIBC_ATTRS;
50+
char *strcpy(char *__restrict, const char *__restrict) __LIBC_ATTRS;
51+
size_t strcspn(const char *, const char *) __LIBC_ATTRS;
52+
char *strdup(const char *) __LIBC_ATTRS;
53+
size_t strlen(const char *) __LIBC_ATTRS;
54+
char *strncat(char *, const char *, size_t) __LIBC_ATTRS;
55+
int strncmp(const char *, const char *, size_t) __LIBC_ATTRS;
56+
char *strncpy(char *__restrict, const char *__restrict, size_t) __LIBC_ATTRS;
57+
char *strndup(const char *, size_t) __LIBC_ATTRS;
58+
size_t strnlen(const char *, size_t) __LIBC_ATTRS;
59+
size_t strspn(const char *, const char *) __LIBC_ATTRS;
60+
char *strtok(char *__restrict, const char *) __LIBC_ATTRS;
61+
char *strtok_r(char *__restrict, const char *__restrict,
62+
char **__restrict) __LIBC_ATTRS;
63+
size_t strxfrm(char *__restrict, const char *__restrict, size_t) __LIBC_ATTRS;
64+
}
65+
66+
extern "C++" {
67+
char *strstr(char *, const char *) noexcept __LIBC_ATTRS;
68+
const char *strstr(const char *, const char *) noexcept __LIBC_ATTRS;
69+
char *strpbrk(char *, const char *) noexcept __LIBC_ATTRS;
70+
const char *strpbrk(const char *, const char *) noexcept __LIBC_ATTRS;
71+
char *strrchr(char *, int) noexcept __LIBC_ATTRS;
72+
const char *strrchr(const char *, int) noexcept __LIBC_ATTRS;
73+
char *strchr(char *, int) noexcept __LIBC_ATTRS;
74+
const char *strchr(const char *, int) noexcept __LIBC_ATTRS;
75+
char *strchrnul(char *, int) noexcept __LIBC_ATTRS;
76+
const char *strchrnul(const char *, int) noexcept __LIBC_ATTRS;
77+
char *strcasestr(char *, const char *) noexcept __LIBC_ATTRS;
78+
const char *strcasestr(const char *, const char *) noexcept __LIBC_ATTRS;
79+
void *memrchr(void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
80+
const void *memrchr(const void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
81+
void *memchr(void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
82+
const void *memchr(const void *__s, int __c, size_t __n) noexcept __LIBC_ATTRS;
83+
}
84+
85+
#else
2986
#include <llvm-libc-decls/string.h>
3087

88+
#endif
89+
3190
#pragma omp end declare target
3291

3392
#undef __LIBC_ATTRS

libc/config/gpu/entrypoints.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,48 @@ set(TARGET_LIBC_ENTRYPOINTS
2222

2323
# string.h entrypoints
2424
libc.src.string.bcmp
25+
libc.src.string.bcopy
2526
libc.src.string.bzero
27+
libc.src.string.index
2628
libc.src.string.memccpy
29+
libc.src.string.memchr
2730
libc.src.string.memcmp
2831
libc.src.string.memcpy
2932
libc.src.string.memmem
3033
libc.src.string.memmove
3134
libc.src.string.mempcpy
35+
libc.src.string.memrchr
3236
libc.src.string.memset
37+
libc.src.string.rindex
3338
libc.src.string.stpcpy
3439
libc.src.string.stpncpy
3540
libc.src.string.strcasecmp
41+
libc.src.string.strcasestr
3642
libc.src.string.strcat
43+
libc.src.string.strchr
44+
libc.src.string.strchrnul
3745
libc.src.string.strcmp
46+
libc.src.string.strcoll
3847
libc.src.string.strcpy
3948
libc.src.string.strcspn
49+
libc.src.string.strdup
4050
libc.src.string.strlcat
4151
libc.src.string.strlcpy
4252
libc.src.string.strlen
4353
libc.src.string.strncasecmp
4454
libc.src.string.strncat
4555
libc.src.string.strncmp
4656
libc.src.string.strncpy
57+
libc.src.string.strndup
4758
libc.src.string.strnlen
59+
libc.src.string.strpbrk
60+
libc.src.string.strrchr
61+
libc.src.string.strsep
4862
libc.src.string.strspn
63+
libc.src.string.strstr
4964
libc.src.string.strtok
5065
libc.src.string.strtok_r
66+
libc.src.string.strxfrm
5167

5268
# stdlib.h entrypoints
5369
libc.src.stdlib.abs

libc/docs/gpu/support.rst

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,37 +45,48 @@ string.h
4545
Function Name Available RPC Required
4646
============= ========= ============
4747
bcmp |check|
48+
bcopy |check|
4849
bzero |check|
50+
index |check|
4951
memccpy |check|
50-
memchr
52+
memchr |check|
5153
memcmp |check|
5254
memcpy |check|
55+
memmem |check|
5356
memmove |check|
5457
mempcpy |check|
55-
memrchr
58+
memrchr |check|
5659
memset |check|
60+
rindex |check|
5761
stpcpy |check|
5862
stpncpy |check|
63+
strcasecmp |check|
64+
strcasestr |check|
5965
strcat |check|
60-
strchr
66+
strchr |check|
67+
strchrnul |check|
6168
strcmp |check|
69+
strcoll |check|
6270
strcpy |check|
6371
strcspn |check|
72+
strdup |check|
6473
strlcat |check|
6574
strlcpy |check|
6675
strlen |check|
76+
strncasecmp |check|
6777
strncat |check|
6878
strncmp |check|
6979
strncpy |check|
80+
strndup |check|
7081
strnlen |check|
71-
strpbrk
72-
strrchr
82+
strpbrk |check|
83+
strrchr |check|
84+
strsep |check|
7385
strspn |check|
74-
strstr
86+
strstr |check|
7587
strtok |check|
7688
strtok_r |check|
77-
strdup
78-
strndup
89+
strxfrm |check|
7990
============= ========= ============
8091

8192
stdlib.h

0 commit comments

Comments
 (0)