]> git.ipfire.org Git - thirdparty/gcc.git/commit
LoongArch: Accept ADD, IOR or XOR when combining objects with no bits in common ...
authorXi Ruoyao <xry111@xry111.site>
Mon, 10 Feb 2025 15:39:24 +0000 (23:39 +0800)
committerXi Ruoyao <xry111@xry111.site>
Wed, 19 Feb 2025 06:34:25 +0000 (14:34 +0800)
commitea3ebe48150d2109845f2c4622ebff182f618d97
tree626f80e1bb4ea663db30627f567706359a5c750e
parent3e93035fcc9247928b58443e37fbf844278b7ac7
LoongArch: Accept ADD, IOR or XOR when combining objects with no bits in common [PR115478]

Since r15-1120, multi-word shifts/rotates produces PLUS instead of IOR.
It's generally a good thing (allowing to use our alsl instruction or
similar instrunction on other architectures), but it's preventing us
from using bytepick.  For example, if we shift a __int128 by 16 bits,
the higher word can be produced via a single bytepick.d instruction with
immediate 2, but we got:

srli.d $r12,$r4,48
slli.d $r5,$r5,16
slli.d $r4,$r4,16
add.d $r5,$r12,$r5
jr $r1

This wasn't work with GCC 14, but after r15-6490 it's supposed to work
if IOR was used instead of PLUS.

To fix this, add a code iterator to match IOR, XOR, and PLUS and use it
instead of just IOR if we know the operands have no overlapping bits.

gcc/ChangeLog:

PR target/115478
* config/loongarch/loongarch.md (any_or_plus): New
define_code_iterator.
(bstrins_<mode>_for_ior_mask): Use any_or_plus instead of ior.
(bytepick_w_<bytepick_imm>): Likewise.
(bytepick_d_<bytepick_imm>): Likewise.
(bytepick_d_<bytepick_imm>_rev): Likewise.

gcc/testsuite/ChangeLog:

PR target/115478
* gcc.target/loongarch/bytepick_shift_128.c: New test.
gcc/config/loongarch/loongarch.md
gcc/testsuite/gcc.target/loongarch/bytepick_shift_128.c [new file with mode: 0644]