Richard Biener <[email protected]> writes: > On Sat, Jun 27, 2026 at 8:00 PM Roger Sayle <[email protected]> > wrote: >> >> >> >> This patch adds an RTL simplification to simplify-rtx.cc to resolve >> >> PR target/48609, inefficient passing of complex values on x86. >> >> >> >> The motivating example, for the bugzilla PR, is: >> >> >> >> typedef _Complex float SCtype; >> >> extern SCtype bar; >> >> void foo (SCtype x) >> >> { >> >> bar = x; >> >> } >> >> >> >> which currently with -O2 generates some spurious instructions: >> >> >> >> foo: movdqa %xmm0, %xmm1 >> >> shufps $85, %xmm0, %xmm0 >> >> unpcklps %xmm0, %xmm1 >> >> movlps %xmm1, bar(%rip) >> >> ret >> >> >> >> with this patch we now generate (the optimal): >> >> >> >> foo: movlps %xmm0, bar(%rip) >> >> ret >> >> >> >> The insight is that combine reports these attempts: >> >> >> >> Trying 7, 4 -> 14: >> >> 7: {r111:SI#0=r105:DI 0>>0x20;clobber flags:CC;} >> >> REG_UNUSED flags:CC >> >> REG_DEAD r105:DI >> >> 4: r108:SI=r105:DI#0 >> >> 14: r112:V2SF=vec_concat(r108:SI#0,r111:SI#0) >> >> REG_DEAD r111:SI >> >> REG_DEAD r108:SI >> >> Failed to match this instruction: >> >> (set (reg:V2SF 112 [ _7 ]) >> >> (vec_concat:V2SF (subreg:SF (subreg:SI (reg:DI 105 [ xD.2967 ]) 0) 0) >> >> (subreg:SF (subreg:SI (zero_extract:DI (reg:DI 105 [ xD.2967 ]) >> >> (const_int 32 [0x20]) >> >> (const_int 32 [0x20])) 0) 0))) >> >> Failed to match this instruction: >> >> (set (reg:V2SF 112 [ _7 ]) >> >> (vec_concat:V2SF (subreg:SF (subreg:SI (reg:DI 105 [ xD.2967 ]) 0) 0) >> >> (subreg:SF (subreg:SI (lshiftrt:DI (reg:DI 105 [ xD.2967 ]) >> >> (const_int 32 [0x20])) 0) 0))) >> >> >> >> Conceptually, this pattern is the equivalent of the RTL expression >> >> (vec_concat (subreg_lowpart (reg X)) (subreg_highpart (reg X)) which >> >> of course is equal to the original (reg X). The ABI splits the >> >> complex argument into __real__ and __imag__ parts, which it then >> >> tries to recombine with vec_concat, resulting in this strange no-op. >> >> >> >> 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? > > Thanks for catching - I wonder whether vector lane endianess can play > a role here and be different from word endianess?
Yeah, I think endianness is a concern. vec_concat operates in memory order, so element 0 is always the first in memory. Similarly, subreg offsets operate in memory order, so SUBREG_BYTE 0 is always first in memory. So I think it's not: (vec_concat (subreg lowpart (subreg highpart)) but rather: (vec_concat (subreg at offset 0) (subreg at offset N/2)) Richard > I suppose there must be similar simplifications around, so you're > conviced this is fine? > > ISTR both arm and powerpc have/had their "difficulties" with vectors > and big-endian operation. > > Richard? > >> >> >> >> >> >> 2026-06-27 Roger Sayle <[email protected]> >> >> >> >> gcc/ChangeLog >> >> PR target/48609 >> >> * simplify-rtx.cc (simplify_binary_operation_1) <case VEC_CONCAT>: >> >> Optimize VEC_CONCAT of a low-part with a high-part as a no-op. >> >> >> >> gcc/testsuite/ChangeLog >> >> PR target/48609 >> >> * gcc.target/i386/pr48609.c: New test case. >> >> >> >> >> >> Thanks in advance, >> >> Roger >> >> -- >> >>
