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

Reply via email to