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

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Roger Sayle <[email protected]>:

https://gcc.gnu.org/g:6b1ffdc831718b1e7639d25c37ea1cdef48e1b53

commit r17-4566-g6b1ffdc831718b1e7639d25c37ea1cdef48e1b53
Author: Roger Sayle <[email protected]>
Date:   Tue Sep 22 15:57:40 2026 +0100

    x86_64: Improved 128-bit TImode moves from SSE to GPRs with SSE2.

    This patch improves TImode moves on x86_64 between SSE and general
registers
    with SSE2.   This is a partial solution for PR target/114544.
    Consider the following simple function:

    typedef __int128 v1ti __attribute__((vector_size(16)));
    __int128 foo(v1ti x) { return x[0]; }

    Currently, with default -O2 (-msse2) the 128-bit value is moved
    via the stack:

    foo:    movaps  %xmm0, -24(%rsp)        // 5 bytes
            movq    -24(%rsp), %rax         // 5 bytes
            movq    -16(%rsp), %rdx         // 5 bytes
            ret

    Though with -O2 -msse4.1, the transfers can be done directly.

    foo:    movq    %xmm0, %rax
            pextrq  $1, %xmm0, %rdx
            ret

    With this patch, we make use of SSE2's shuffle functionality
    to avoid the transfers to and from memory:

    foo:    movq    %xmm0, %rax             // 5 bytes
            shufpd  $1, %xmm0, %xmm0        // 5 bytes
            movq    %xmm0, %rdx             // 5 bytes
            ret

    Technically, to avoid using a second register we swap/rotate the
    high and low lanes between movq instructions, and (not shown above)
    also swap/rotate the lanes back again (so the source register remains
    unchanged if the value is still live).  This second (restoring) shufpd
    is eliminated by later RTL passes if it's discovered to be dead code.

    To make this possible, the Yd constraint that enables allows
    *movti_internal to match on SSE4_1, is tweaked to form a new YD
    constraint that allows *movti_internal to match on SSE2.

    2026-09-22  Roger Sayle  <[email protected]>
                Hongtao Liu  <[email protected]>

    gcc/ChangeLog
            PR target/114544
            * config/i386/constraints.md (YD): New constraint, like Yd but
            allows SSE_REGS on TARGET_SSE2.
            * config/i386/i386.cc (inline_secondary_memory_needed): Update
            that TImode moves to GENERAL_REGS don't need to use memory.
            * config/i386/i386.md (*movti_internal): Change Yd constraint to
YD.
            (define_split): On TARGET_64BIT && TARGET_SSE2 && !TARGET_SSE4_1,
            split *movti_internal into movq+shufpd+movq+shufpd.

    gcc/testsuite/ChangeLog
            * gcc.target/i386/pr126293-15.c: Update test case.
            * gcc.target/i386/pr126293-5.c: Likewise.

Reply via email to