Hi!
On Tue, Jun 08, 2021 at 09:11:33AM +0800, Xionghu Luo wrote:
> On P8LE, extra rot64+rot64 load or store instructions are generated
> in float128 to vector __int128 conversion.
>
> This patch teaches pass swaps to also handle such pattens to remove
> extra swap instructions.
> +/* Return 1 iff PAT is a rotate 64 bit expression; else return 0. */
> +
> +static bool
> +pattern_is_rotate64_p (rtx pat)
You already have a verb in the name, don't use _p please (and preferably
just don't use it at all, "pattern_is_rotate64" is much better than
"pattern_rotate64_p").
> +{
> + rtx rot = SET_SRC (pat);
So this is assuming PAT is a SINGLE_SET. Please say that in the
function comment.
/* Return 1 iff PAT (a SINGLE_SET) is a rotate 64 bit expression; else
return 0. */
You can do an assert for that as well, but I wouldn't bother.
> @@ -266,6 +280,9 @@ insn_is_load_p (rtx insn)
(I do realise you just copied existing naming, don't worry :-) )
> @@ -392,7 +411,8 @@ quad_aligned_load_p (swap_web_entry *insn_entry, rtx_insn
> *insn)
> false. */
> rtx body = PATTERN (def_insn);
> if (GET_CODE (body) != SET
> - || GET_CODE (SET_SRC (body)) != VEC_SELECT
> + || !(GET_CODE (SET_SRC (body)) == VEC_SELECT
> + || pattern_is_rotate64_p (body))
Broken indentation: the || should align with "pattern...".
> @@ -2223,9 +2246,9 @@ static void
> recombine_stvx_pattern (rtx_insn *insn, del_info *to_delete)
> {
> rtx body = PATTERN (insn);
> - gcc_assert (GET_CODE (body) == SET
> - && MEM_P (SET_DEST (body))
> - && GET_CODE (SET_SRC (body)) == VEC_SELECT);
> + gcc_assert (GET_CODE (body) == SET && MEM_P (SET_DEST (body))
> + && (GET_CODE (SET_SRC (body)) == VEC_SELECT
> + || pattern_is_rotate64_p (body)));
Please start a new line for every "&&" here. The way it was was more
readable.
It often is nice to keep things one one line, if it fits on one line.
If it does not, make a new line for every phrase. This is more readable
because you can then just scan down the line of "&&" and see the start
of every phrase without actually having to read it all.
> diff --git a/gcc/testsuite/gcc.target/powerpc/float128-call.c
> b/gcc/testsuite/gcc.target/powerpc/float128-call.c
> index 5895416e985..a1f09df8a57 100644
> --- a/gcc/testsuite/gcc.target/powerpc/float128-call.c
> +++ b/gcc/testsuite/gcc.target/powerpc/float128-call.c
> @@ -21,5 +21,5 @@
> TYPE one (void) { return ONE; }
> void store (TYPE a, TYPE *p) { *p = a; }
>
> -/* { dg-final { scan-assembler "lxvd2x 34" } } */
> -/* { dg-final { scan-assembler "stxvd2x 34" } } */
> +/* { dg-final { scan-assembler "lvx 2" } } */
> +/* { dg-final { scan-assembler "stvx 2" } } */
Huh. Is that correct? Where did the other 32 loads and stores go? Are
there now other insns generated that you should scan for?
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/pr100085.c
> @@ -0,0 +1,24 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target powerpc_float128_sw_ok } */
> +/* { dg-options "-O2 -mdejagnu-cpu=power8" } */
If you use float128_ok you should use -mfloat128 (or this is very
surprising and is worth an explanation itself :-) )
But, you do not need it, since you use -mcpu=power8 already (which
implicitly sets this). So just remove that dg-require please.
> +/* { dg-final { scan-assembler-not "xxpermdi" } } */
> +/* { dg-final { scan-assembler-not "stxvd2x" } } */
> +/* { dg-final { scan-assembler-not "lxvd2x" } } */
It is a good habit to use \m and \M in the scans where you can (those
are the same as \< and \> are in some other regexp dialects). They
aren't absolutely necessary here of course.
Okay for trunk with those fixes. Thanks!
Segher