Because of a wrong define_insn for vec_extract_plus a vector access wasn't
combined with a preceeding plus operation which set the offset at which
to perform the vector access even though the instruction offers that capability.

Bootstrapped and regtested on s390x.

gcc/ChangeLog:

        * config/s390/vector.md (*vec_extract<mode>_plus_zero_extend):
        Fix define insn.

gcc/testsuite/ChangeLog:

        * gcc.target/s390/vector/vec-extract-3.c: New test.

Signed-off-by: Maximilian Immanuel Brandtner <ma...@linux.ibm.com>
---
 gcc/config/s390/vector.md                     |  27 +++-
 .../gcc.target/s390/vector/vec-extract-3.c    | 141 ++++++++++++++++++
 2 files changed, 162 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/vector/vec-extract-3.c

diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 745634edf57..f7f95b493ab 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -697,13 +697,15 @@
 
 ; vlgvb, vlgvh, vlgvf, vlgvg
 (define_insn "*vec_extract<mode>_plus"
-  [(set (match_operand:<non_vec>       0 "nonimmediate_operand" "=d")
+  [(set (match_operand:<non_vec>  0 "register_operand" "=d")
        (vec_select:<non_vec>
-        (match_operand:V              1 "register_operand"      "v")
-        (plus:SI (match_operand:SI    2 "nonmemory_operand"     "a")
-         (parallel [(match_operand:SI 3 "const_int_operand"     "n")]))))]
-  "TARGET_VX"
-  "vlgv<bhfgq>\t%0,%v1,%Y3(%2)"
+         (match_operand:V        1 "register_operand"  "v")
+           (parallel
+             [(plus:SI
+               (match_operand:SI 2 "register_operand"  "a")
+               (match_operand:SI 3 "const_int_operand" "J"))])))]
+  "TARGET_VX && UINTVAL (operands[3]) < 4096"
+  "vlgv<bhfgq>\t%0,%v1,%3(%2)"
   [(set_attr "op_type" "VRS")])
 
 (define_expand "vec_init<mode><non_vec_l>"
@@ -751,6 +753,19 @@
   [(set_attr "op_type" "VRS")
    (set_attr "mnemonic" "vlgv<bhfgq>")])
 
+(define_insn "*vec_extract<mode>_plus_zero_extend"
+  [(set (match_operand:DI            0 "register_operand" "=d")
+       (zero_extend:DI
+         (vec_select:<non_vec>
+           (match_operand:VLGV_DI   1 "register_operand"  "v")
+             (parallel
+               [(plus:SI
+                 (match_operand:SI  2 "register_operand"  "a")
+                 (match_operand:SI  3 "const_int_operand" "J"))]))))]
+  "TARGET_VX && UINTVAL (operands[3]) < 4096"
+  "vlgv<bhfgq>\t%0,%v1,%3(%2)"
+  [(set_attr "op_type" "VRS")])
+
 (define_insn "*vec_vllezlf<mode>"
   [(set (match_operand:V_HW_4              0 "register_operand" "=v")
        (vec_concat:V_HW_4
diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-extract-3.c 
b/gcc/testsuite/gcc.target/s390/vector/vec-extract-3.c
new file mode 100644
index 00000000000..01030cce778
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/vec-extract-3.c
@@ -0,0 +1,141 @@
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -march=z13 -mzarch" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+typedef unsigned char uv16qi __attribute__ ((vector_size (16)));
+typedef signed char v16qi __attribute__ ((vector_size (16)));
+typedef unsigned short uv8hi __attribute__ ((vector_size (16)));
+typedef signed short v8hi __attribute__ ((vector_size (16)));
+typedef unsigned int uv4si __attribute__ ((vector_size (16)));
+typedef signed int v4si __attribute__ ((vector_size (16)));
+typedef unsigned long uv2di __attribute__ ((vector_size (16)));
+typedef signed long v2di __attribute__ ((vector_size (16)));
+typedef float v4sf __attribute__ ((vector_size (16)));
+typedef double v2df __attribute__ ((vector_size (16)));
+
+/*
+** extractnthuchar:
+**     vlgvb   %r2,%v24,3\(%r2\)
+**     br      %r14
+*/
+unsigned char
+extractnthuchar (uv16qi in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthchar:
+**     vlgvb   %r2,%v24,3\(%r2\)
+**     lgbr    %r2,%r2
+**     br      %r14
+*/
+signed char
+extractnthchar (v16qi in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthushort:
+**     vlgvh   %r2,%v24,3\(%r2\)
+**     br      %r14
+*/
+unsigned short
+extractnthushort (uv8hi in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthshort:
+**     vlgvh   %r2,%v24,3\(%r2\)
+**     lghr    %r2,%r2
+**     br      %r14
+*/
+short
+extractnthshort (v8hi in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthuint:
+**     vlgvf   %r2,%v24,3\(%r2\)
+**     br      %r14
+*/
+unsigned int
+extractnthuint (uv4si in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthint:
+**     vlgvf   %r2,%v24,3\(%r2\)
+**     lgfr    %r2,%r2
+**     br      %r14
+*/
+int
+extractnthint (v4si in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthulong:
+**     vlgvg   %r2,%v24,1\(%r2\)
+**     br      %r14
+*/
+unsigned long
+extractnthulong (uv2di in, int n)
+{
+  return in[n + 1];
+}
+
+/*
+** extractnthlong:
+**     vlgvg   %r2,%v24,1\(%r2\)
+**     br      %r14
+*/
+long
+extractnthlong (v2di in, int n)
+{
+  return in[n + 1];
+}
+
+/*
+** extractnthfloat:
+**     vlgvf   %r1,%v24,3\(%r2\)
+**     vlvgf   %v0,%r1,0
+**     br      %r14
+*/
+float
+extractnthfloat (v4sf in, int n)
+{
+  return in[n + 3];
+}
+
+/*
+** extractnthdouble:
+**     vlgvg   %r1,%v24,1\(%r2\)
+**     ldgr    %f0,%r1
+**     br      %r14
+*/
+double
+extractnthdouble (v2df in, int n)
+{
+  return in[n + 1];
+}
+
+/*
+** extractnthuintm1displacement:
+**     ahi     %r2,-1
+**     vlgvf   %r2,%v24,0\(%r2\)
+**     br      %r14
+*/
+unsigned int
+extractnthuintm1displacement (uv4si in, int n)
+{
+  return in[n - 1];
+}
-- 
2.50.1

Reply via email to