]> git.ipfire.org Git - thirdparty/gcc.git/commit
i386: Convert ptestz of pandn into ptestc.
authorRoger Sayle <roger@nextmovesoftware.com>
Thu, 22 Jun 2023 06:43:07 +0000 (07:43 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Thu, 22 Jun 2023 06:43:07 +0000 (07:43 +0100)
commit5322f009e8f7d1c7a1c9aab7cb4c90c433398fdd
tree20ae588d4907aa2e9653450075e0782eea06676f
parent0e466e978c728697f18c67c4eace9ba4633f9ef5
i386: Convert ptestz of pandn into ptestc.

This patch is the next installment in a set of backend patches around
improvements to ptest/vptest.  A previous patch optimized the sequence
t=pand(x,y); ptestz(t,t) into the equivalent ptestz(x,y), using the
property that ZF is set to (X&Y) == 0.  This patch performs a similar
transformation, converting t=pandn(x,y); ptestz(t,t) into the (almost)
equivalent ptestc(y,x), using the property that the CF flags is set to
(~X&Y) == 0.  The tricky bit is that this sets the CF flag instead of
the ZF flag, so we can only perform this transformation when we can
also convert the flags consumer, as well as the producer.

For the test case:

int foo (__m128i x, __m128i y)
{
  __m128i a = x & ~y;
  return __builtin_ia32_ptestz128 (a, a);
}

With -O2 -msse4.1 we previously generated:

foo: pandn   %xmm0, %xmm1
        xorl    %eax, %eax
        ptest   %xmm1, %xmm1
        sete    %al
        ret

with this patch we now generate:

foo: xorl    %eax, %eax
        ptest   %xmm0, %xmm1
        setc    %al
        ret

At the same time, this patch also provides alternative fixes for
PR target/109973 and PR target/110118, by recognizing that ptestc(x,x)
always sets the carry flag (X&~X is always zero).  This is achieved
both by recognizing the special case in ix86_expand_sse_ptest and with
a splitter to convert an eligible ptest into an stc.

2023-06-22  Roger Sayle  <roger@nextmovesoftware.com>
    Uros Bizjak  <ubizjak@gmail.com>

gcc/ChangeLog
* config/i386/i386-expand.cc (ix86_expand_sse_ptest): Recognize
expansion of ptestc with equal operands as producing const1_rtx.
* config/i386/i386.cc (ix86_rtx_costs): Provide accurate cost
estimates of UNSPEC_PTEST, where the ptest performs the PAND
or PAND of its operands.
* config/i386/sse.md (define_split): Transform CCCmode UNSPEC_PTEST
of reg_equal_p operands into an x86_stc instruction.
(define_split): Split pandn/ptestz/set{n?}e into ptestc/set{n?}c.
(define_split): Similar to above for strict_low_part destinations.
(define_split): Split pandn/ptestz/j{n?}e into ptestc/j{n?}c.

gcc/testsuite/ChangeLog
* gcc.target/i386/avx-vptest-4.c: New test case.
* gcc.target/i386/avx-vptest-5.c: Likewise.
* gcc.target/i386/avx-vptest-6.c: Likewise.
* gcc.target/i386/pr109973-1.c: Update test case.
* gcc.target/i386/pr109973-2.c: Likewise.
* gcc.target/i386/sse4_1-ptest-4.c: New test case.
* gcc.target/i386/sse4_1-ptest-5.c: Likewise.
* gcc.target/i386/sse4_1-ptest-6.c: Likewise.
gcc/config/i386/i386-expand.cc
gcc/config/i386/i386.cc
gcc/config/i386/sse.md
gcc/testsuite/gcc.target/i386/avx-vptest-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-vptest-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/avx-vptest-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr109973-1.c
gcc/testsuite/gcc.target/i386/pr109973-2.c
gcc/testsuite/gcc.target/i386/sse4_1-ptest-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-ptest-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/sse4_1-ptest-6.c [new file with mode: 0644]