rs6000: Use rldimi for vec init instead of shift + ior
authorKewen Lin <linkw@linux.ibm.com>
Mon, 14 Dec 2020 09:38:49 +0000 (03:38 -0600)
committerKewen Lin <linkw@linux.ibm.com>
Tue, 23 Feb 2021 05:44:05 +0000 (23:44 -0600)
commitf4a3cea3fb025735c09af5c7f14d61152c4c5794
treef10489743af87916b6d41e35713c1d74c436bff4
parent198c56052ea8cce4196e60c0dc3187bf3d67a786
rs6000: Use rldimi for vec init instead of shift + ior

This patch is to teach unsigned int vector init to use rldimi to
merge two integers instead of shift and ior.  It also adds one
required splitter made by Segher.

An rl*imi is usually written as an IOR of an ASHIFT or similar, and
an AND of a register with a constant mask.  In some cases combine
knows that that AND doesn't do anything (because all zero bits in
that mask correspond to bits known to be already zero), and then no
pattern matches.  This patch adds a define_split for such cases.

It uses nonzero_bits in the condition of the splitter, but does not
need it afterwards for the instruction to be recognised.  This is
necessary because later passes can see fewer nonzero_bits.

Because it is a splitter, combine will only use it when starting with
three insns (or more), even though the result is just one.  This isn't
a huge problem in practice, but some possible combinations still won't
happen.

Bootstrapped/regtested on powerpc64le-linux-gnu P9 and
powerpc64-linux-gnu P8, also SPEC2017 build/run passed on P9.

gcc/ChangeLog:

2020-02-23  Segher Boessenkool  <segher@kernel.crashing.org>
    Kewen Lin  <linkw@gcc.gnu.org>

* config/rs6000/rs6000.md (*rotl<mode>3_insert_3): Renamed to...
(rotl<mode>3_insert_3): ...this.
(plus_ior_xor): New code_iterator.
(define_split for GPR rl*imi): New splitter.
* config/rs6000/vsx.md (vsx_init_v4si): Use gen_rotldi3_insert_3
for integer merging.

gcc/testsuite/ChangeLog:

* gcc.target/powerpc/vec-init-10.c: New test.
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/vsx.md
gcc/testsuite/gcc.target/powerpc/vec-init-10.c [new file with mode: 0644]