]> git.ipfire.org Git - thirdparty/gcc.git/commit
i386: Refactor V2DI arithmetic right shift expansion for STV.
authorRoger Sayle <roger@nextmovesoftware.com>
Tue, 6 Aug 2024 16:19:29 +0000 (17:19 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Tue, 6 Aug 2024 16:21:31 +0000 (17:21 +0100)
commit2f759fa9f4dd78ae8d86482ccda72a335aaac404
treeebb32c2ab162215d12cf41b480e2549f6dcdeb0d
parent4c3f476e55149f542de538e97dd9800ec9bd1011
i386: Refactor V2DI arithmetic right shift expansion for STV.

This patch refactors ashrv2di RTL expansion into a function so that it may
be reused by a pre-reload splitter, such that DImode right shifts may be
considered candidates during the Scalar-To-Vector (STV) pass.  Currently
DImode arithmetic right shifts are not considered potential candidates
during STV, so for the following testcase:

long long m;
typedef long long v2di __attribute__((vector_size (16)));
void foo(v2di x) { m = x[0]>>63; }

We currently see the following warning/error during STV2
>  r101 use in insn 7 isn't convertible

And end up generating scalar code with an interunit move:

foo: movq    %xmm0, %rax
        sarq    $63, %rax
        movq    %rax, m(%rip)
        ret

With this patch, we can reuse the RTL expansion logic and produce:

foo: psrad   $31, %xmm0
        pshufd  $245, %xmm0, %xmm0
        movq    %xmm0, m(%rip)
        ret

Or with the addition of -mavx2, the equivalent:

foo:    vpxor   %xmm1, %xmm1, %xmm1
        vpcmpgtq        %xmm0, %xmm1, %xmm0
        vmovq   %xmm0, m(%rip)
        ret

The only design decision of note is the choice to continue lowering V2DI
into vector sequences during RTL expansion, to enable combine to optimize
things if possible.  Using just define_insn_and_split potentially misses
optimizations, such as reusing the zero vector produced by vpxor above.
It may be necessary to tweak STV's compute gain at some point, but this
patch controls what's possible (rather than what's beneficial).

2024-08-06  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
* config/i386/i386-expand.cc (ix86_expand_v2di_ashiftrt): New
function refactored from define_expand ashrv2di3.
* config/i386/i386-features.cc (general_scalar_to_vector_candidate_p)
<case ASHIFTRT>: Handle like other shifts and rotates.
* config/i386/i386-protos.h (ix86_expand_v2di_ashiftrt): Prototype.
* config/i386/sse.md (ashrv2di3): Call ix86_expand_v2di_ashiftrt.
(*ashrv2di3): New define_insn_and_split to enable creation by stv2
pass, and splitting during split1 reusing ix86_expand_v2di_ashiftrt.

gcc/testsuite/ChangeLog
* gcc.target/i386/sse2-stv-2.c: New test case.
gcc/config/i386/i386-expand.cc
gcc/config/i386/i386-features.cc
gcc/config/i386/i386-protos.h
gcc/config/i386/sse.md
gcc/testsuite/gcc.target/i386/sse2-stv-2.c [new file with mode: 0644]