On Tue, Sep 09, 2025 at 04:21:14PM +0200, Maximilian Immanuel Brandtner wrote: > 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.
Committed as r16-3735-g7a49952100f. Thanks, Stefan > > 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 >