Issue |
146484
|
Summary |
Efficient memcpy when src or dest can be nullptr
|
Labels |
new issue
|
Assignees |
|
Reporter |
QrczakMK
|
How to obtain efficient `memcpy()` when src or dest can be `nullptr` (when the size is 0)?
`memcpy(_, nullptr, 0)` and `memcpy(nullptr, _, 0)` have UB according to C and C++ standards, except that https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3322.pdf has been accepted for the next C standard; I could find nothing for C++.
GCC makes use of that UB, e.g. by skipping explicit `nullptr` checks after `memcpy()`. Clang does not. Sanitizers are consistent with that.
In GCC, `__builtin_memcpy()` behaves like `memcpy()` in this respect, i.e. does not allow `nullptr`. This suggests that portable code (at least including GCC) one should not blindly issue `memcpy()` nor `__builtin_memcpy()` if null pointers are possible.
According to https://github.com/llvm/llvm-project/issues/49459, `llvm.memcpy` is safe to call with some null pointers and zero size, but I could not find a documentation that `__builtin_memcpy()` has this property too. The issue concludes with 'I think we can safely close this, with the answer being "yes, you can pass null pointer arguments"', but I feel uneasy relying on that comment without a more official documentation.
Clang nor GCC do not optimize portable `if (len != 0) memcpy(dest, src, len)` to a plain call to `memcpy()`, even though Clang could if it indeed assumes that actual `memcpy()` in the runtime library is valid with some null pointers and zero size.
Explicit zero checks slow down my implementation of joining a bunch of string_views by 14%.
What should I do, so that this is efficient at least on Clang?
In practice using `__builtin_memcpy()` or even `memcpy()` inside `#ifdef __clang__` should work, but I would like to have a more official guarantee that this must work. And perhaps this requires some version check if the behavior changed in Clang in the past.
The same applies to `memset()`.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs