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 >