]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
s390: fix vec_extract_plus define insn
authorMaximilian Immanuel Brandtner <maxbr@linux.ibm.com>
Tue, 9 Sep 2025 14:21:14 +0000 (16:21 +0200)
committerStefan Schulze Frielinghaus <stefansf@gcc.gnu.org>
Wed, 10 Sep 2025 08:14:46 +0000 (10:14 +0200)
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 <maxbr@linux.ibm.com>
gcc/config/s390/vector.md
gcc/testsuite/gcc.target/s390/vector/vec-extract-3.c [new file with mode: 0644]

index 745634edf57bc854e74180de80008d65ea8f7afa..205ead2ca9d8fb81fb143116f708197e48efd16e 100644 (file)
 
 ; 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>"
   [(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 (file)
index 0000000..01030cc
--- /dev/null
@@ -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];
+}