rs6000: Inefficient vector splat of small V2DI constants [PR107757] On P8, for vector splat of double word constants, specifically -1 and 1, gcc generates inefficient code. For -1, gcc generates two instructions (vspltisw and vupkhsw) whereas only one instruction (vspltisw) is sufficient. For constant 1, gcc generates a load of the constant from .rodata instead of the instructions vspltisw and vupkhsw.
The routine vspltisw_vupkhsw_constant_p() returns true if the constant can be synthesized with instructions vspltisw and vupkhsw. However, for constant 1, this routine returns false. For constant -1, this routine returns true. Vector splat of -1 can be done with only one instruction, i.e., vspltisw. We do not need two instructions. Hence this routine should return false for -1. With this patch, gcc generates only one instruction (vspltisw) for -1. And for constant 1, this patch generates two instructions (vspltisw and vupkhsw). 2024-11-20 Surya Kumari Jangala <jskum...@linux.ibm.com> gcc/ PR target/107757 * config/rs6000/rs6000.cc (vspltisw_vupkhsw_constant_p): Return false for -1 and return true for 1. gcc/testsuite/ PR target/107757 * gcc.target/powerpc/pr107757-1.c: New. * gcc.target/powerpc/pr107757-2.c: New. --- diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 0d7ee1e5bdf..4de527e12eb 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -6651,7 +6651,7 @@ vspltisw_vupkhsw_constant_p (rtx op, machine_mode mode, int *constant_ptr) return false; value = INTVAL (elt); - if (value == 0 || value == 1 + if (value == 0 || value == -1 || !EASY_VECTOR_15 (value)) return false; diff --git a/gcc/testsuite/gcc.target/powerpc/pr107757-1.c b/gcc/testsuite/gcc.target/powerpc/pr107757-1.c new file mode 100644 index 00000000000..e0a75f82bd2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr107757-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power8 -mvsx -O2" } */ +/* { dg-require-effective-target powerpc_vsx } */ +/* { dg-final { scan-assembler {\mvspltisw\M} } } */ +/* { dg-final { scan-assembler {\mvupkhsw\M} } } */ +/* { dg-final { scan-assembler-not {\mlvx\M} } } */ + +#include <altivec.h> + +vector long long +foo () +{ + return vec_splats (1LL); +} diff --git a/gcc/testsuite/gcc.target/powerpc/pr107757-2.c b/gcc/testsuite/gcc.target/powerpc/pr107757-2.c new file mode 100644 index 00000000000..4ed8053f853 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr107757-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power8 -mvsx -O2" } */ +/* { dg-require-effective-target powerpc_vsx } */ +/* { dg-final { scan-assembler {\mvspltisw\M} } } */ +/* { dg-final { scan-assembler-not {\mvupkhsw\M} } } */ + +#include <altivec.h> + +vector long long +foo () +{ + return vec_splats (~0LL); +}