[PATCH 2/3] arm: Auto-vectorization for MVE: vshl
Christophe Lyon
christophe.lyon@linaro.org
Fri Jan 15 10:45:48 GMT 2021
On Fri, 15 Jan 2021 at 10:42, Kyrylo Tkachov <Kyrylo.Tkachov@arm.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Gcc-patches <gcc-patches-bounces@gcc.gnu.org> On Behalf Of
> > Christophe Lyon via Gcc-patches
> > Sent: 17 December 2020 17:48
> > To: gcc-patches@gcc.gnu.org
> > Subject: [PATCH 2/3] arm: Auto-vectorization for MVE: vshl
> >
> > 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
> >
>
> Can you file a bug report once this is committed so we can revisit in the future please.
OK, I filed: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98697
>
> > 2020-12-03 Christophe Lyon <christophe.lyon@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 ();
>
> I know this is copied code, but let's clean it up by removing the switch and using the "*" syntax for the C code in alternative 1.
> Ok with those changes.
Thanks, now pushed as r11-6707
Christophe
> Thanks,
> Kyrill
>
> > + }
> > +}
> > + [(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
>
More information about the Gcc-patches
mailing list