On Mon, Jul 20, 2026 at 12:38 AM Roger Sayle <[email protected]> wrote:
>
>
> This patch teaches the x86 backend that the SSE4.1 insertps instruction
> can be used/abused to clear one or more elements of a V4SI or V4SF vector
> in a single instruction (i.e. without requiring xor to clear a second
> register).
>
> Consider the test case
>
> typedef int v4si __attribute__ ((__vector_size__ (16)));
> v4si foo(v4si x) { x[2]=0; return x; }
>
> Currently with -O2 -mavx2, we generate:
>
> foo: xorl %eax, %eax
> vpinsrd $2, %eax, %xmm0, %xmm0
> ret
>
> with this patch we now generate:
>
> foo: vinsertps $4, %xmm0, %xmm0, %xmm0
> ret
Ha, interesting detail. I guess for CTOR expansion with
element zero being zero (plus possibly some others), it's
still beneficial to use a dependency breaking pxor to populate
the zero elements rather than combining it with setting of
the first non-zero element.
> For the more complicated example:
>
> v4si bar(v4si x) { x[1]=0; x[3]=0; return x; }
>
> previously, we'd generate:
>
> bar: xorl %eax, %eax
> vpinsrd $1, %eax, %xmm0, %xmm0
> vpinsrd $3, %eax, %xmm0, %xmm0
> ret
>
> with this patch we now generate:
>
> bar: vinsertps $10, %xmm0, %xmm0, %xmm0
> ret
>
>
> One improvement that I'll leave to an i386/SSE expert, is that setting
> elements 1, 2 and 3 [i.e. zero extending element 0] still falls back
> to the existing patterns (and tests for this are commented out in the
> new test cases). Tweaking sse_movss_v4si to consider using insertps
> requires expertise in register preferencing and instruction attributes
> that I'm happy to leave to someone else.
>
> 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?
>
>
> 2026-07-19 Roger Sayle <[email protected]>
>
> gcc/ChangeLog
> * config/i386/i386-expand.cc (ix86_expand_vec_set_builtin): Don't
> force op1 to a register when it is CONST0_RTX (mode1).
> (ix86_expand_vector_set_var): For now, force VAL to a register.
> (ix86_expand_vector_set): If val is CONST0_RTX, expand using
> the new sse4_1_insertps_v4s[if]_zero patterns on TARGET_SSE4_1.
> Otherwise, force val to a register (restoring previous behaviour).
> * config/i386/sse.md (sse4_1_insertps_<mode>_zero): New insn
> with using vec_merge to select which elements to clear.
> (*sse4_1_insertps_<mode>_zero): Likewise, a variant with the
> const0_operand second, and operand3 selecting elements to preserve.
> (vec_set<mode>): Tweak operand 1 to allow both REGs and CONST0_RTX.
>
> gcc/testsuite/ChangeLog
> * gcc.target/i386/sse4_1-insertps-6.c: New test case.
> * gcc.target/i386/sse4_1-insertps-7.c: Likewise.
>
>
> Thanks in advance,
> Roger
> --
>