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.