ping^2?
On Wed, 30 Dec 2020 at 11:34, Christophe Lyon <christophe.l...@linaro.org> wrote: > > ping? > > On Thu, 17 Dec 2020 at 18:48, Christophe Lyon > <christophe.l...@linaro.org> wrote: > > > > This patch enables MVE vshlq instructions for auto-vectorization. > > > > The existing mve_vshlq_n_<supf><mode> is kept, as it takes a single > > immediate as second operand, and is used by arm_mve.h. > > > > We move the vashl<mode>3 insn from neon.md to an expander in > > vec-common.md, and the mve_vshlq_<supf><mode> insn from mve.md to > > vec-common.md, adding the second alternative fron neon.md. > > > > mve_vshlq_<supf><mode> will be used by a later patch enabling > > vectorization for vshr, as a unified version of > > ashl3<mode3>_[signed|unsigned] from neon.md. Keeping the use of unspec > > VSHLQ enables to generate both 's' and 'u' variants. > > > > It is not clear whether the neon_shift_[reg|imm]<q> attribute is still > > suitable, since this insn is also used for MVE. > > > > I kept the mve_vshlq_<supf><mode> naming instead of renaming it to > > ashl3_<supf>_<mode> as discussed because the reference in > > arm_mve_builtins.def automatically inserts the "mve_" prefix and I > > didn't want to make a special case for this. > > > > I haven't yet found why the v16qi and v8hi tests are not vectorized. > > With dest[i] = a[i] << b[i] and: > > { > > int i; > > unsigned int i.24_1; > > unsigned int _2; > > int16_t * _3; > > short int _4; > > int _5; > > int16_t * _6; > > short int _7; > > int _8; > > int _9; > > int16_t * _10; > > short int _11; > > unsigned int ivtmp_42; > > unsigned int ivtmp_43; > > > > <bb 2> [local count: 119292720]: > > > > <bb 3> [local count: 954449105]: > > i.24_1 = (unsigned int) i_23; > > _2 = i.24_1 * 2; > > _3 = a_15(D) + _2; > > _4 = *_3; > > _5 = (int) _4; > > _6 = b_16(D) + _2; > > _7 = *_6; > > _8 = (int) _7; > > _9 = _5 << _8; > > _10 = dest_17(D) + _2; > > _11 = (short int) _9; > > *_10 = _11; > > i_19 = i_23 + 1; > > ivtmp_42 = ivtmp_43 - 1; > > if (ivtmp_42 != 0) > > goto <bb 5>; [87.50%] > > else > > goto <bb 4>; [12.50%] > > > > <bb 5> [local count: 835156386]: > > goto <bb 3>; [100.00%] > > > > <bb 4> [local count: 119292720]: > > return; > > > > } > > the vectorizer says: > > mve-vshl.c:37:96: note: ==> examining statement: _5 = (int) _4; > > mve-vshl.c:37:96: note: vect_is_simple_use: operand *_3, type of def: > > internal > > mve-vshl.c:37:96: note: vect_is_simple_use: vectype vector(8) short int > > mve-vshl.c:37:96: missed: conversion not supported by target. > > mve-vshl.c:37:96: note: vect_is_simple_use: operand *_3, type of def: > > internal > > mve-vshl.c:37:96: note: vect_is_simple_use: vectype vector(8) short int > > mve-vshl.c:37:96: note: vect_is_simple_use: operand *_3, type of def: > > internal > > mve-vshl.c:37:96: note: vect_is_simple_use: vectype vector(8) short int > > mve-vshl.c:37:117: missed: not vectorized: relevant stmt not supported: > > _5 = (int) _4; > > mve-vshl.c:37:96: missed: bad operation or unsupported loop bound. > > mve-vshl.c:37:96: note: ***** Analysis failed with vector mode V8HI > > > > 2020-12-03 Christophe Lyon <christophe.l...@linaro.org> > > > > gcc/ > > * config/arm/mve.md (mve_vshlq_<supf><mode>): Move to > > vec-commond.md. > > * config/arm/neon.md (vashl<mode>3): Delete. > > * config/arm/vec-common.md (mve_vshlq_<supf><mode>): New. > > (vasl<mode>3): New expander. > > > > gcc/testsuite/ > > * gcc.target/arm/simd/mve-vshl.c: Add tests for vshl. > > --- > > gcc/config/arm/mve.md | 13 +----- > > gcc/config/arm/neon.md | 19 --------- > > gcc/config/arm/vec-common.md | 30 ++++++++++++++ > > gcc/testsuite/gcc.target/arm/simd/mve-vshl.c | 62 > > ++++++++++++++++++++++++++++ > > 4 files changed, 93 insertions(+), 31 deletions(-) > > create mode 100644 gcc/testsuite/gcc.target/arm/simd/mve-vshl.c > > > > diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md > > index 673a83c..8bdb451 100644 > > --- a/gcc/config/arm/mve.md > > +++ b/gcc/config/arm/mve.md > > @@ -822,18 +822,7 @@ (define_insn "mve_vcmpneq_<supf><mode>" > > > > ;; > > ;; [vshlq_s, vshlq_u]) > > -;; > > -(define_insn "mve_vshlq_<supf><mode>" > > - [ > > - (set (match_operand:MVE_2 0 "s_register_operand" "=w") > > - (unspec:MVE_2 [(match_operand:MVE_2 1 "s_register_operand" "w") > > - (match_operand:MVE_2 2 "s_register_operand" "w")] > > - VSHLQ)) > > - ] > > - "TARGET_HAVE_MVE" > > - "vshl.<supf>%#<V_sz_elem>\t%q0, %q1, %q2" > > - [(set_attr "type" "mve_move") > > -]) > > +;; See vec-common.md > > > > ;; > > ;; [vabdq_s, vabdq_u]) > > diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md > > index 50220be..ac9bf74 100644 > > --- a/gcc/config/arm/neon.md > > +++ b/gcc/config/arm/neon.md > > @@ -845,25 +845,6 @@ (define_insn "*smax<mode>3_neon" > > ; generic vectorizer code. It ends up creating a V2DI constructor with > > ; SImode elements. > > > > -(define_insn "vashl<mode>3" > > - [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w") > > - (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w,w") > > - (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" > > "w,Dm")))] > > - "TARGET_NEON" > > - { > > - switch (which_alternative) > > - { > > - case 0: return "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"; > > - case 1: return neon_output_shift_immediate ("vshl", 'i', > > &operands[2], > > - <MODE>mode, > > - VALID_NEON_QREG_MODE > > (<MODE>mode), > > - true); > > - default: gcc_unreachable (); > > - } > > - } > > - [(set_attr "type" "neon_shift_reg<q>, neon_shift_imm<q>")] > > -) > > - > > (define_insn "vashr<mode>3_imm" > > [(set (match_operand:VDQIW 0 "s_register_operand" "=w") > > (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w") > > diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md > > index f6a79e2..3a282f0 100644 > > --- a/gcc/config/arm/vec-common.md > > +++ b/gcc/config/arm/vec-common.md > > @@ -229,3 +229,33 @@ (define_expand "movmisalign<mode>" > > if (!neon_vector_mem_operand (adjust_mem, 2, true)) > > XEXP (adjust_mem, 0) = force_reg (Pmode, XEXP (adjust_mem, 0)); > > }) > > + > > +(define_insn "mve_vshlq_<supf><mode>" > > + [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w") > > + (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w,w") > > + (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" > > "w,Dm")] > > + VSHLQ))] > > + "ARM_HAVE_<MODE>_ARITH" > > +{ > > + switch (which_alternative) > > + { > > + case 0: return "vshl.<supf>%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, > > %<V_reg>2"; > > + case 1: return neon_output_shift_immediate ("vshl", 'i', > > &operands[2], > > + <MODE>mode, > > + VALID_NEON_QREG_MODE > > (<MODE>mode), > > + true); > > + default: gcc_unreachable (); > > + } > > +} > > + [(set_attr "type" "neon_shift_reg<q>, neon_shift_imm<q>")] > > +) > > + > > +(define_expand "vashl<mode>3" > > + [(set (match_operand:VDQIW 0 "s_register_operand" "") > > + (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "") > > + (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "")))] > > + "ARM_HAVE_<MODE>_ARITH" > > +{ > > + emit_insn (gen_mve_vshlq_u<mode> (operands[0], operands[1], > > operands[2])); > > + DONE; > > +}) > > \ No newline at end of file > > diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c > > b/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c > > new file mode 100644 > > index 0000000..7a06449 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c > > @@ -0,0 +1,62 @@ > > +/* { dg-do assemble } */ > > +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ > > +/* { dg-add-options arm_v8_1m_mve } */ > > +/* { dg-additional-options "-O3" } */ > > + > > +#include <stdint.h> > > + > > +#define FUNC(SIGN, TYPE, BITS, NB, OP, NAME) \ > > + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * > > __restrict__ dest, TYPE##BITS##_t *a, TYPE##BITS##_t *b) { \ > > + int i; \ > > + for (i=0; i<NB; i++) { \ > > + dest[i] = a[i] OP b[i]; \ > > + } \ > > +} > > + > > +#define FUNC_IMM(SIGN, TYPE, BITS, NB, OP, NAME) > > \ > > + void test_ ## NAME ##_ ## SIGN ## BITS ## x ## NB (TYPE##BITS##_t * > > __restrict__ dest, TYPE##BITS##_t *a) { \ > > + int i; \ > > + for (i=0; i<NB; i++) { \ > > + dest[i] = a[i] OP 5; \ > > + } \ > > +} > > + > > +/* 64-bit vectors. */ > > +FUNC(s, int, 32, 2, <<, vshl) > > +FUNC(u, uint, 32, 2, <<, vshl) > > +FUNC(s, int, 16, 4, <<, vshl) > > +FUNC(u, uint, 16, 4, <<, vshl) > > +FUNC(s, int, 8, 8, <<, vshl) > > +FUNC(u, uint, 8, 8, <<, vshl) > > + > > +/* 128-bit vectors. */ > > +FUNC(s, int, 32, 4, <<, vshl) > > +FUNC(u, uint, 32, 4, <<, vshl) > > +FUNC(s, int, 16, 8, <<, vshl) /* FIXME: not vectorized */ > > +FUNC(u, uint, 16, 8, <<, vshl) /* FIXME: not vectorized */ > > +FUNC(s, int, 8, 16, <<, vshl) /* FIXME: not vectorized */ > > +FUNC(u, uint, 8, 16, <<, vshl) /* FIXME: not vectorized */ > > + > > +/* 64-bit vectors. */ > > +FUNC_IMM(s, int, 32, 2, <<, vshlimm) > > +FUNC_IMM(u, uint, 32, 2, <<, vshlimm) > > +FUNC_IMM(s, int, 16, 4, <<, vshlimm) > > +FUNC_IMM(u, uint, 16, 4, <<, vshlimm) > > +FUNC_IMM(s, int, 8, 8, <<, vshlimm) > > +FUNC_IMM(u, uint, 8, 8, <<, vshlimm) > > + > > +/* 128-bit vectors. */ > > +FUNC_IMM(s, int, 32, 4, <<, vshlimm) > > +FUNC_IMM(u, uint, 32, 4, <<, vshlimm) > > +FUNC_IMM(s, int, 16, 8, <<, vshlimm) > > +FUNC_IMM(u, uint, 16, 8, <<, vshlimm) > > +FUNC_IMM(s, int, 8, 16, <<, vshlimm) > > +FUNC_IMM(u, uint, 8, 16, <<, vshlimm) > > + > > +/* MVE has only 128-bit vectors, so we can vectorize only half of the > > + functions above. */ > > +/* We only emit vshl.u, which is equivalent to vshl.s anyway. */ > > +/* { dg-final { scan-assembler-times {vshl.u[0-9]+\tq[0-9]+, q[0-9]+} 2 } > > } */ > > + > > +/* We emit vshl.i when the shift amount is an immediate. */ > > +/* { dg-final { scan-assembler-times {vshl.i[0-9]+\tq[0-9]+, q[0-9]+} 6 } > > } */ > > -- > > 2.7.4 > >