]> git.ipfire.org Git - thirdparty/gcc.git/commit
x86 SSE: Improve vector increment/decrement on x86.
authorRoger Sayle <roger@nextmovesoftware.com>
Thu, 28 May 2026 19:46:04 +0000 (20:46 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Thu, 28 May 2026 19:47:46 +0000 (20:47 +0100)
commit84e5bd1e7dbdd106956ed0f5d8ddee7bf7b3be7c
tree58a0f1897da28548e481fbfdfada4790ba5ec018
parenta33b41d895f55fd95f8c9f486f6ef23c71a7a1e5
x86 SSE: Improve vector increment/decrement on x86.

This patch improves the code generated by the i386 backend for incrementing
(adding one to) and decrementing (subtracting one from) a vector.  With SSE
materializing the vector -1 is more efficient than materializing the
vector +1, hence x + 1 (increment) is better expressed as x - (-1), and
x - 1 (decrement) is better expressed as x + (-1).  Conveniently the
relevant additions and subtractions are specified as a single pattern,
using a plusminus iterator, in the machine description.

For the four example functions:

typedef char v16sqi __attribute__ ((vector_size(16)));
typedef unsigned char v16uqi __attribute__ ((vector_size(16)));

v16sqi sadd1(v16sqi x) { return x+1; }
v16uqi uadd1(v16uqi x) { return x+1; }
v16sqi saddm1(v16sqi x) { return x-1; }
v16uqi uaddm1(v16uqi x) { return x-1; }

GCC with -O2 -mavx2 previously generated:

sadd1: vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpabsb  %xmm1, %xmm1
        vpaddb  %xmm1, %xmm0, %xmm0
        ret

uadd1: vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpabsb  %xmm1, %xmm1
        vpaddb  %xmm1, %xmm0, %xmm0
        ret

saddm1: vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpabsb  %xmm1, %xmm1
        vpsubb  %xmm1, %xmm0, %xmm0
        ret

uaddm1: vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpaddb  %xmm1, %xmm0, %xmm0
        ret

With this patch, we now consistently generate:

sadd1:  vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpsubb  %xmm1, %xmm0, %xmm0
        ret

uadd1:  vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpsubb  %xmm1, %xmm0, %xmm0
        ret

saddm1: vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpaddb  %xmm1, %xmm0, %xmm0
        ret

uaddm1: vpcmpeqd        %xmm1, %xmm1, %xmm1
        vpaddb  %xmm1, %xmm0, %xmm0
        ret

2026-05-28  Roger Sayle  <roger@nextmovesoftware.com>
    Hongtao Liu  <hongtao.liu@intel.com>
    Uros Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog
* config/i386/i386.md (inv_insn): New define_code_attr.
* config/i386/sse.md (<plusminus><mode>3): Accept a CONST_VECTOR
as the second operand.  If the second operand is CONST1_RTX,
canonicalize to use CONSTM1_RTX instead.
(*add<mode>3_one): New define_insn_and_split to convert padd +1
to psub -1.
(*sub<mode>3_one): Likewise, a new define_insn_and_split to
convert psub +1 to padd -1.

gcc/testsuite/ChangeLog
* gcc.target/i386/avx512f-simd-1.c: Tweak test case.
* gcc.target/i386/sse2-paddb-2.c: New test case.
* gcc.target/i386/sse2-paddd-2.c: Likewise.
* gcc.target/i386/sse2-paddw-2.c: Likewise.
* gcc.target/i386/sse2-psubb-2.c: Likewise.
* gcc.target/i386/sse2-psubd-2.c: Likewise.
* gcc.target/i386/sse2-psubw-2.c: Likewise.
gcc/config/i386/i386.md
gcc/config/i386/sse.md
gcc/testsuite/gcc.target/i386/avx512f-simd-1.c
gcc/testsuite/gcc.target/i386/sse2-paddb-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-paddd-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-paddw-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-psubb-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-psubd-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse2-psubw-2.c [new file with mode: 0644]