On Wed, Jul 1, 2026 at 1:07 PM Roger Sayle <[email protected]> wrote: > > > 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. > > This patch has been tested on x86_64-pc-linux-gnu with make bootstrap > and make -k check, both with and without --target_board=unix{-m32} > with no new failures. Ok for mainline?
Seeing a GET_CODE (src) == CONCAT case after the new block I wonder if that's more specific and should be handled first? Or would that be always worse when SCALAR_INT_MODE_P (mode) in which case we possibly want to add a comment reflecting this. Can expand_shift fail? I would expect it might be quite expensive, like on AVR which IIRC can only shift by a single bit at a time. That said, I wonder why emit_group_load_1 is the correct place to fix, is it that the very CONCAT path performs assign_stack_temp ()? > > 2026-07-01 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. > > > Thanks in advance, > Roger > -- >
