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

            Bug ID: 92149
           Summary: Enefficient x86_64 code
           Product: gcc
           Version: 9.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: maxim.yegorushkin at gmail dot com
  Target Milestone: ---

The following code:

    #include <array>
    #include <cstring>
    #include <cstdint>

    using std::uint64_t;
    using A = std::array<unsigned char, 6>;

    template<class T>
    constexpr A pack(T v) {
        using C = unsigned char;
        return {C(v), C(v >> 8), C(v >> 16), C(v >> 24), C(v >> 32), C(v >>
40)};
    }

    template<class T>
    constexpr A pack2(T v) {
        A r{};
        std::memcpy(r.data(), &v, 6);
        return r;
    }

    A f(uint64_t a) { return pack(a); }
    A f2(uint64_t a) { return pack2(a); }

When compiled with `clang++-9.0 -std=gnu++17 -O3 -march=skylake` produces the
most efficient assembly:

    f(unsigned long):
            mov     rax, rdi
            ret
    f2(unsigned long):
            mov     rax, rdi
            ret

Whereas when compiled with `g++-9.2 -std=gnu++17 -O3 -march=skylake` the
assembly is inefficient:

    f(unsigned long):
            mov     rax, rdi
            shr     rax, 32
            mov     BYTE PTR [rsp-2], al
            mov     rax, rdi
            shr     rax, 40
            mov     BYTE PTR [rsp-1], al
            movzx   eax, WORD PTR [rsp-2]
            sal     rax, 32
            mov     rdx, rax
            mov     eax, edi
            or      rax, rdx
            ret
    f2(unsigned long):
            movabs  rax, 281474976710655
            and     rax, rdi
            ret

Why does g++ emit such verbose code please?

Reply via email to