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