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

Reply via email to