https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93059

--- Comment #50 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <r...@gcc.gnu.org>:

https://gcc.gnu.org/g:308d19c11e119b2c5abf67778dd0ac8a370e5df7

commit r15-4320-g308d19c11e119b2c5abf67778dd0ac8a370e5df7
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Oct 10 13:36:33 2024 +0100

    libstdc++: Enable memcpy optimizations for distinct integral types
[PR93059]

    Currently we only optimize std::copy, std::copy_n etc. to memmove when
    the source and destination types are the same. This means that we fail
    to optimize copying between distinct 1-byte types, e.g. copying from a
    buffer of unsigned char to a buffer of char8_t or vice versa.

    This patch adds more partial specializations of the __memcpyable trait
    so that we allow memcpy between integers of equal widths. This will
    enable memmove for copies between narrow character types and also
    between same-width types like int and unsigned.

    Enabling the optimization needs to be based on the width of the integer
    type, not just the size in bytes. This is because some targets define
    non-standard integral types such as __int20 in msp430, which has padding
    bits. It would not be safe to memcpy between e.g. __int20 and int32_t,
    even though sizeof(__int20) == sizeof(int32_t). A new trait is
    introduced to define the width, __memcpyable_integer, and then the
    __memcpyable trait compares the widths.

    It's safe to copy between signed and unsigned integers of the same
    width, because GCC only supports two's complement integers.

    I initially though it would be useful to define the specialization
    __memcpyable_integer<byte> to enable copying between narrow character
    types and std::byte. But that isn't possible with std::copy, because
    is_assignable<char&, std::byte> is false. Optimized copies using memmove
    will already happen for copying std::byte to std::byte, because
    __memcpyable<T*, T*> is true.

    libstdc++-v3/ChangeLog:

            PR libstdc++/93059
            * include/bits/cpp_type_traits.h (__memcpyable): Add partial
            specialization for pointers to distinct types.
            (__memcpyable_integer): New trait to control which types can use
            cross-type memcpy optimizations.

--- Comment #51 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <r...@gcc.gnu.org>:

https://gcc.gnu.org/g:d8ef4471cb9c9f86784b62424a215ea42173bfe1

commit r15-4321-gd8ef4471cb9c9f86784b62424a215ea42173bfe1
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Oct 10 13:36:33 2024 +0100

    libstdc++: Enable memset optimizations for distinct character types
[PR93059]

    Currently we only optimize std::fill to memset when the source and
    destination types are the same byte-sized type. This means that we fail
    to optimize cases like std::fill(buf. buf+n, 0) because the literal 0 is
    not the same type as the character buffer.

    Such cases can safely be optimized to use memset, because assigning an
    int (or other integer) to a narrow character type has the same effects
    as converting the integer to unsigned char then copying it with memset.

    This patch enables the optimized code path when the fill character is a
    memcpy-able integer (using the new __memcpyable_integer trait). We still
    need to check is_same<U, T> to enable the memset optimization for
    filling a range of std::byte with a std::byte value, because that isn't
    a memcpyable integer.

    libstdc++-v3/ChangeLog:

            PR libstdc++/93059
            * include/bits/stl_algobase.h (__fill_a1(T*, T*, const T&)):
            Change template parameters and enable_if condition to allow the
            fill value to be an integer.

Reply via email to