i386: Optimize abs expansion [PR97873]
authorUros Bizjak <ubizjak@gmail.com>
Fri, 20 Nov 2020 09:26:34 +0000 (10:26 +0100)
committerUros Bizjak <ubizjak@gmail.com>
Fri, 20 Nov 2020 09:29:35 +0000 (10:29 +0100)
commitfdace7584056de2f63bde2e3087f26beb6b0f97d
treeb9cb3d204fe6f58c6aa1d60ae5d71ed1b46543fc
parenta774a6a2fbeaf7cbcb7a7afe433418f2d740b45b
i386: Optimize abs expansion [PR97873]

The patch introduces absM named pattern to generate optimal insn sequence
for CMOVE_TARGET targets.  Currently, the expansion goes through neg+max
optabs, and the following code is generated:

movl    %edi, %eax
negl    %eax
cmpl    %edi, %eax
cmovl   %edi, %eax

This sequence is unoptimal in two ways.  a) The compare instruction is
not needed, since NEG insn sets the sign flag based on the result.
The CMOV can use sign flag to select between negated and original value:

movl    %edi, %eax
negl    %eax
cmovs   %edi, %eax

b) On some targets, CMOV is undesirable due to its performance issues.
In addition to TARGET_EXPAND_ABS bypass, the patch introduces STV
conversion of abs RTX to use PABS SSE insn:

vmovd   %edi, %xmm0
vpabsd  %xmm0, %xmm0
vmovd   %xmm0, %eax

The patch changes compare mode of NEG instruction to CCGOCmode,
which is the same mode as the mode of SUB instruction. IOW, sign bit
becomes usable.

Also, the mode iterator of <maxmin:code><mode>3 pattern is changed
to SWI48x instead of SWI248. The purpose of maxmin expander is to
prepare max/min RTX for STV to eventually convert them to SSE PMAX/PMIN
instructions, in order to *avoid* CMOV insns with general registers.

2020-11-20  Uroš Bizjak  <ubizjak@gmail.com>

gcc/
PR target/97873
* config/i386/i386.md (*neg<mode>2_2): Rename from
"*neg<mode>2_cmpz".  Use CCGOCmode instead of CCZmode.
(*negsi2_zext): Rename from *negsi2_cmpz_zext.
Use CCGOCmode instead of CCZmode.
(*neg<mode>_ccc_1): New insn pattern.
(*neg<dwi>2_doubleword): Use *neg<mode>_ccc_1.

(abs<mode>2): Add FLAGS_REG clobber.
Use TARGET_CMOVE insn predicate.
(*abs<mode>2_1): New insn_and_split pattern.
(*absdi2_doubleword): Ditto.

(<maxmin:code><mode>3): Use SWI48x mode iterator.
(*<maxmin:code><mode>3): Use SWI48 mode iterator.

* config/i386/i386-features.c
(general_scalar_chain::compute_convert_gain): Handle ABS code.
(general_scalar_chain::convert_insn): Ditto.
(general_scalar_to_vector_candidate_p): Ditto.

gcc/testsuite/
PR target/97873
* gcc.target/i386/pr97873.c: New test.
* gcc.target/i386/pr97873-1.c: New test.
gcc/config/i386/i386-features.c
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr97873-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr97873.c [new file with mode: 0644]