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

--- Comment #13 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:a1ff104826c59ead40f8e864cd1aa1ce2e5fc6ba

commit r17-2323-ga1ff104826c59ead40f8e864cd1aa1ce2e5fc6ba
Author: Roger Sayle <[email protected]>
Date:   Fri Jul 10 23:04:03 2026 +0100

    PR target/48609: Improve RTL expansion of complex value return.

    This patch address the inefficient return of complex values (with the x86
    ABI) where the result is returned to the caller in an integer register.
    Currently this results in RTL expansion spilling the value to memory
    and reloading it in an integer register.  The patch below recognizes
    this case, and composes the real and imaginary parts using shifts and
    addition.  The real part always appears first in memory, so is lowpart
    on little-endian targets, and the highpart on big-endian targets.

    Consider the new test case:

    _Complex float mem;
    _Complex float foo(_Complex float x) { return x; }
    _Complex float bar() { return mem; }

    Currently, with -O2 GCC generates:

    foo:    movss   %xmm0, -8(%rsp)
            shufps  $85, %xmm0, %xmm0
            movss   %xmm0, -4(%rsp)
            movq    -8(%rsp), %xmm0
            ret

    bar:    movss   mem(%rip), %xmm0
            movss   %xmm0, -8(%rsp)
            movss   mem+4(%rip), %xmm0
            movss   %xmm0, -4(%rsp)
            movq    -8(%rsp), %xmm0
            ret

    With this patch, we now generate:

    foo:    ret

    bar:    movl    mem+4(%rip), %edx
            movl    mem(%rip), %eax
            salq    $32, %rdx
            addq    %rdx, %rax
            movq    %rax, %xmm0
            ret

    For those folks noticing that bar could be improved further, I've
    a follow-up patch to the i386's STV2 pass, to perform concatsidi2 in
    SSE registers.

    2026-07-10  Roger Sayle  <[email protected]>

    gcc/ChangeLog
            PR target/48609
            * expr.cc (emit_group_load_1): When passing a complex value in an
            integer mode of the same size, explicitly construct (hi<<N)+lo to
            avoid spilling to memory before reload.

    gcc/testsuite/ChangeLog
            PR target/48609
            * gcc.target/i386/pr48609-2.c: New test case.

Reply via email to