Hi, This is the third version of the patch proposed for master aiming to fix PR119702. Requesting review of this patch.
The following sequence of assembly in powerpc64le vspltisw 0,1 vsld 2,2,0 is replaced by this vaddudm 2,2,2 whenever there is a vector left shift by a constant value 1. Added the pattern in altivec.md to recognize a vector left shift by a constant value, and generate add instructions if constant is 1. PR target/119702 gcc: * config/rs6000/altivec.md: Added a define_insn to recognize left shift by constant 1 for vector instructions. * config/rs6000/predicates.md(shift_constant_1): Added a predicate for detecting if all values in a const_vector are 1. gcc/testsuite: * gcc.target/powerpc/pr119702-1.c: New test for (check generation of vadd for different integer types) Changes made in v3: Incorporated review comments made for patch v2 1. Indentation fixes in the commit message 2. define_insn has the name *altivec_vsl<VI_char>_const_1 3. Iterate starting from 0 for checking vector constant = 1 and fixed source code formatting for the for loop. 4. Removed unused macro in pr119702-1.c test file --- gcc/config/rs6000/altivec.md | 8 +++ gcc/config/rs6000/predicates.md | 11 ++++ gcc/testsuite/gcc.target/powerpc/pr119702-1.c | 53 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr119702-1.c diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 7edc288a656..e9e9c9dd554 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -2107,6 +2107,14 @@ "vsrv %0,%1,%2" [(set_attr "type" "vecsimple")]) +(define_insn "*altivec_vsl<VI_char>_const_1" + [(set (match_operand:VI2 0 "register_operand" "=v") + (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") + (match_operand:VI2 2 "shift_constant_1" "")))] + "<VI_unit>" + "vaddu<VI_char>m %0,%1,%1" +) + (define_insn "*altivec_vsl<VI_char>" [(set (match_operand:VI2 0 "register_operand" "=v") (ashift:VI2 (match_operand:VI2 1 "register_operand" "v") diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 647e89afb6a..50e423d2514 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -924,6 +924,17 @@ } }) +(define_predicate "shift_constant_1" + (match_code "const_vector") +{ + unsigned nunits = GET_MODE_NUNITS (mode), i; + for (i = 0; i < nunits; i++) + if (INTVAL (CONST_VECTOR_ELT(op, i)) != 1) + return 0; + + return 1; +}) + ;; Return 1 if operand is 0.0. (define_predicate "zero_fp_constant" (and (match_code "const_double") diff --git a/gcc/testsuite/gcc.target/powerpc/pr119702-1.c b/gcc/testsuite/gcc.target/powerpc/pr119702-1.c new file mode 100644 index 00000000000..2f23ae20084 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr119702-1.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power8 -O2" } */ + +#include <inttypes.h> + +void lshift1_64(uint64_t *a) { + a[0] <<= 1; + a[1] <<= 1; +} + +void lshift1_32(unsigned int *a) { + a[0] <<= 1; + a[1] <<= 1; + a[2] <<= 1; + a[3] <<= 1; +} + +void lshift1_16(uint16_t *a) { + a[0] <<= 1; + a[1] <<= 1; + a[2] <<= 1; + a[3] <<= 1; + a[4] <<= 1; + a[5] <<= 1; + a[6] <<= 1; + a[7] <<= 1; +} + +void lshift1_8(uint8_t *a) { + a[0] <<= 1; + a[1] <<= 1; + a[2] <<= 1; + a[3] <<= 1; + a[4] <<= 1; + a[5] <<= 1; + a[6] <<= 1; + a[7] <<= 1; + a[8] <<= 1; + a[9] <<= 1; + a[10] <<= 1; + a[11] <<= 1; + a[12] <<= 1; + a[13] <<= 1; + a[14] <<= 1; + a[15] <<= 1; +} + + +/* { dg-final { scan-assembler-times {\mvaddudm\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvadduwm\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvadduhm\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvaddubm\M} 1 } } */ + -- 2.47.3