From 2b6fb4aa47e25c530ee97c4354896443403da585 Mon Sep 17 00:00:00 2001 From: Pat Haugen Date: Thu, 27 Aug 2015 18:20:45 +0000 Subject: [PATCH] vector.md (vec_shr_): Fix to do a shift instead of a rotate. * config/rs6000/vector.md (vec_shr_): Fix to do a shift instead of a rotate. * gcc.target/powerpc/vec-shr.c: New. From-SVN: r227270 --- gcc/ChangeLog | 5 ++++ gcc/config/rs6000/vector.md | 23 +++++++++++---- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.target/powerpc/vec-shr.c | 34 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-shr.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9b3c3a51e2..0cf325faf99 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2015-08-27 Pat Haugen + + * config/rs6000/vector.md (vec_shr_): Fix to do a shift + instead of a rotate. + 2015-08-27 Marek Polacek PR middle-end/67005 diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md index 4a62fbbbdd4..8821dec5989 100644 --- a/gcc/config/rs6000/vector.md +++ b/gcc/config/rs6000/vector.md @@ -977,6 +977,8 @@ ;; General shift amounts can be supported using vsro + vsr. We're ;; not expecting to see these yet (the vectorizer currently ;; generates only shifts by a whole number of vector elements). +;; Note that the vec_shr operation is actually defined as +;; 'shift toward element 0' so is a shr for LE and shl for BE. (define_expand "vec_shr_" [(match_operand:VEC_L 0 "vlogical_operand" "") (match_operand:VEC_L 1 "vlogical_operand" "") @@ -987,6 +989,7 @@ rtx bitshift = operands[2]; rtx shift; rtx insn; + rtx zero_reg, op1, op2; HOST_WIDE_INT bitshift_val; HOST_WIDE_INT byteshift_val; @@ -996,19 +999,29 @@ if (bitshift_val & 0x7) FAIL; byteshift_val = (bitshift_val >> 3); + zero_reg = gen_reg_rtx (mode); + emit_move_insn (zero_reg, CONST0_RTX (mode)); if (!BYTES_BIG_ENDIAN) - byteshift_val = 16 - byteshift_val; + { + byteshift_val = 16 - byteshift_val; + op1 = zero_reg; + op2 = operands[1]; + } + else + { + op1 = operands[1]; + op2 = zero_reg; + } + if (TARGET_VSX && (byteshift_val & 0x3) == 0) { shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); - insn = gen_vsx_xxsldwi_ (operands[0], operands[1], operands[1], - shift); + insn = gen_vsx_xxsldwi_ (operands[0], op1, op2, shift); } else { shift = gen_rtx_CONST_INT (QImode, byteshift_val); - insn = gen_altivec_vsldoi_ (operands[0], operands[1], operands[1], - shift); + insn = gen_altivec_vsldoi_ (operands[0], op1, op2, shift); } emit_insn (insn); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef3ada08e0a..8f1e24ca692 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2015-08-27 Pat Haugen + + * gcc.target/powerpc/vec-shr.c: New. + 2015-08-27 Marek Polacek PR middle-end/67005 diff --git a/gcc/testsuite/gcc.target/powerpc/vec-shr.c b/gcc/testsuite/gcc.target/powerpc/vec-shr.c new file mode 100644 index 00000000000..31a27c8832d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-shr.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -fno-inline" } */ + +#include + +typedef struct { double r, i; } complex; +#define LEN 30 +complex c[LEN]; +double d[LEN]; + +void +foo (complex *c, double *d, int len1) +{ + int i; + for (i = 0; i < len1; i++) + { + c[i].r = d[i]; + c[i].i = 0.0; + } +} + +int +main (void) +{ + int i; + for (i = 0; i < LEN; i++) + d[i] = (double) i; + foo (c, d, LEN); + for (i=0;i