https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116754
Bug ID: 116754 Summary: libstdc++ std::ranges::copy performance issue Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: addmlbx at gmail dot com Target Milestone: --- Created attachment 59130 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59130&action=edit struct __memcpyable definition libstdc++ std::ranges::copy implementation has bug which prevents calling memmove in case iterators are pointers: there is an `if constexpr (__memcpyable<_Iter, _Out>::__value)` statement used to determine whether memmove should be called and _Iter and _Out template parameters are swapped (__memcpyable expects output iterator to be given first). Therefore this statement evaluates to false and memmove is not called. I noticed this bug when I was comparing the assembly produced for copying some containers like std::vector, std::array and C-style array in the std::copy and std::ranges::copy: When calling std::copy on these containers, it's inlined down to the memmove call. But for the std::ranges::copy the assembly is different: it fallback to the generic cycle-based implementation. Definition of the struct __memcpyable is shown on the attached picture in order to demonstrate that it (and it's specializations) expect output iterator to be passed first