We currently use subst definitions to handle the different variants of shift count operands. Unfortunately, in the vector shift pattern the shift count operand is used directly. Without it being adjusted for the 'subst' variants the displacement value is omitted resulting in a wrong shift count being applied.
This patch needs to be applied to older branches as well. Bootstrapped and regression tested on s390x (IBM z14). Committed to mainline gcc/ChangeLog: 2019-07-01 Andreas Krebbel <kreb...@linux.ibm.com> * config/s390/vector.md: gcc/testsuite/ChangeLog: 2019-07-01 Andreas Krebbel <kreb...@linux.ibm.com> * gcc.target/s390/vector/vec-shift-2.c: New test. --- gcc/config/s390/vector.md | 2 +- gcc/testsuite/gcc.target/s390/vector/vec-shift-2.c | 24 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/s390/vector/vec-shift-2.c diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index a2c1012..140ef47 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -981,7 +981,7 @@ (VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v") (match_operand:SI 2 "nonmemory_operand" "an")))] "TARGET_VX" - "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2" + "<vec_shifts_mnem><bhfgq>\t%v0,%v1,<addr_style_op_ops>" [(set_attr "op_type" "VRS")]) ; Shift each element by corresponding vector element diff --git a/gcc/testsuite/gcc.target/s390/vector/vec-shift-2.c b/gcc/testsuite/gcc.target/s390/vector/vec-shift-2.c new file mode 100644 index 0000000..c7a1d93 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/vec-shift-2.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -march=z13 --save-temps" } */ + +/* { dg-final { scan-assembler-times "veslf" 1 } } */ + +typedef __attribute__((vector_size(16))) signed int v4si; + +v4si __attribute__((noinline,noclone)) +shift_left_by_scalar (v4si in, int shift_count) +{ + return in << (3 + shift_count); +} + +int +main () +{ + v4si a = { 1, 2, 3, 4 }; + v4si result = shift_left_by_scalar (a, 1); + + if (result[1] != 32) + __builtin_abort (); + + return 0; +} -- 2.7.4