Issue |
73516
|
Summary |
llvm libc (and musl) are incompatible with llvm memcpy assumptions
|
Labels |
libc
|
Assignees |
|
Reporter |
RalfJung
|
The libc llvm seems to declare its `memcpy` with the `restrict` qualifier, matching the signature in the C standard:
https://github.com/llvm/llvm-project/blob/cb112eb16cff222d8fbe7cfd3cb0834f538a691d/libc/src/string/memcpy.cpp#L15-L17
This means it will be compiled in a way such that when the two pointers are used to access the same memory, and at least one access is a write, there is UB. This is UB both in the C source semantics and in LLVM IR (via `noalias`).
However, LLVM itself assumes that the libc `memcpy` is always defined behavior when `dst==src`. (This comes up frequently on this issue tracker, e.g. at https://github.com/llvm/llvm-project/issues/60734, https://github.com/llvm/llvm-project/issues/55399. But as far as I know it is not mentioned in the LLVM documentation.)
Reading the llvm-libc sources, I did not find any guards that would short-circuit the function when `dst==src`. It seems very much like the usual copy loop will be executed, loading from `src` and storing to `dst`. This is UB due to the `restrict` keyword, making LLVM incompatible with its own libc even when said libc is compiled with LLVM -- unless I misunderstood something. (There are so many macros in the libc it's very hard to be sure what the actually compiled code will be.^^)
musl also [uses `restrict`](https://git.musl-libc.org/cgit/musl/tree/src/string/memcpy.c#n5) in its `memcpy`, so it is likewise incompatible with LLVM.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs