]> git.ipfire.org Git - thirdparty/gcc.git/commit
i386: Double-word sign-extension missed-optimization [PR110717]
authorUros Bizjak <ubizjak@gmail.com>
Thu, 20 Jul 2023 18:54:51 +0000 (20:54 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 20 Jul 2023 18:56:19 +0000 (20:56 +0200)
commitb50a851eef4b70aabf28fa875d9b2a302d17b66a
tree8c3f51fc31de58182883d6ee23c7a1299189f532
parent4b8878fbf7b74ea5c3405c9f558df0517036f131
i386: Double-word sign-extension missed-optimization [PR110717]

When sign-extending the value in a double-word register pair using shift and
ashiftrt sequence with the same count immediate value less than word width,
there is no need to shift the lower word of the value. The sign-extension
could be limited to the upper word, but we uselessly shift the lower word
with it as well:
movq %rdi, %rax
movq %rsi, %rdx
shldq $59, %rdi, %rdx
salq $59, %rax
shrdq $59, %rdx, %rax
sarq $59, %rdx
ret
for -m64 and
movl 4(%esp), %eax
movl 8(%esp), %edx
shldl $27, %eax, %edx
sall $27, %eax
shrdl $27, %edx, %eax
sarl $27, %edx
ret
for -m32.

The patch introduces a new post-reload splitter to provide the combined
ASHIFTRT/SHIFT instruction pattern.  The instruction is split to a sequence
of SAL and SAR insns with the same count immediate operand:
movq    %rsi, %rdx
movq    %rdi, %rax
salq    $59, %rdx
sarq    $59, %rdx
ret

Some complication is required to properly handle STV transform, where we
emit a sequence with DImode PSLLQ and PSRAQ insns for 32-bit AVX512VL
targets when profitable.

The patch also fixes a small oversight and enables STV transform of SImode
ASHIFTRT to PSRAD also for SSE2 targets.

PR target/110717

gcc/ChangeLog:

* config/i386/i386-features.cc
(general_scalar_chain::compute_convert_gain): Calculate gain
for extend higpart case.
(general_scalar_chain::convert_op): Handle
ASHIFTRT/ASHIFT combined RTX.
(general_scalar_to_vector_candidate_p): Enable ASHIFTRT for
SImode for SSE2 targets.  Handle ASHIFTRT/ASHIFT combined RTX.
* config/i386/i386.md (*extend<dwi>2_doubleword_highpart):
New define_insn_and_split pattern.
(*extendv2di2_highpart_stv): Ditto.

gcc/testsuite/ChangeLog:

* gcc.target/i386/pr110717.c: New test.
gcc/config/i386/i386-features.cc
gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/pr110717.c [new file with mode: 0644]