ping?
On Fri, 30 Apr 2021 at 16:09, Christophe Lyon <christophe.l...@linaro.org> wrote: > > This patch enables MVE vld2/vst2 instructions for auto-vectorization. > We move the existing expanders from neon.md and enable them for MVE, > calling the respective emitter. > > 2021-03-12 Christophe Lyon <christophe.l...@linaro.org> > > gcc/ > * config/arm/neon.md (vec_load_lanesoi<mode>) > (vec_store_lanesoi<mode>): Move ... > * config/arm/vec-common.md: here. > > gcc/testsuite/ > * gcc.target/arm/simd/mve-vld2.c: New test, derived from > slp-perm-2.c > --- > gcc/config/arm/neon.md | 14 ---- > gcc/config/arm/vec-common.md | 27 ++++++++ > gcc/testsuite/gcc.target/arm/simd/mve-vld2.c | 96 > ++++++++++++++++++++++++++++ > 3 files changed, 123 insertions(+), 14 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/arm/simd/mve-vld2.c > > diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md > index 6660846..bc8775c 100644 > --- a/gcc/config/arm/neon.md > +++ b/gcc/config/arm/neon.md > @@ -5063,13 +5063,6 @@ (define_insn "neon_vld2<mode>" > (const_string "neon_load2_2reg<q>")))] > ) > > -(define_expand "vec_load_lanesoi<mode>" > - [(set (match_operand:OI 0 "s_register_operand") > - (unspec:OI [(match_operand:OI 1 "neon_struct_operand") > - (unspec:VQ2 [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] > - UNSPEC_VLD2))] > - "TARGET_NEON") > - > (define_insn "neon_vld2<mode>" > [(set (match_operand:OI 0 "s_register_operand" "=w") > (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um") > @@ -5197,13 +5190,6 @@ (define_insn "neon_vst2<mode>" > (const_string "neon_store2_one_lane<q>")))] > ) > > -(define_expand "vec_store_lanesoi<mode>" > - [(set (match_operand:OI 0 "neon_struct_operand") > - (unspec:OI [(match_operand:OI 1 "s_register_operand") > - (unspec:VQ2 [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] > - UNSPEC_VST2))] > - "TARGET_NEON") > - > (define_insn "neon_vst2<mode>" > [(set (match_operand:OI 0 "neon_struct_operand" "=Um") > (unspec:OI [(match_operand:OI 1 "s_register_operand" "w") > diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md > index 3fd341c..7abefea 100644 > --- a/gcc/config/arm/vec-common.md > +++ b/gcc/config/arm/vec-common.md > @@ -482,6 +482,33 @@ (define_expand "vcond_mask_<mode><v_cmp_result>" > } > else > gcc_unreachable (); > + DONE; > +}) > > +(define_expand "vec_load_lanesoi<mode>" > + [(set (match_operand:OI 0 "s_register_operand") > + (unspec:OI [(match_operand:OI 1 "neon_struct_operand") > + (unspec:VQ2 [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] > + UNSPEC_VLD2))] > + "TARGET_NEON || TARGET_HAVE_MVE" > +{ > + if (TARGET_NEON) > + emit_insn (gen_neon_vld2<mode> (operands[0], operands[1])); > + else > + emit_insn (gen_mve_vld2q<mode> (operands[0], operands[1])); > + DONE; > +}) > + > +(define_expand "vec_store_lanesoi<mode>" > + [(set (match_operand:OI 0 "neon_struct_operand") > + (unspec:OI [(match_operand:OI 1 "s_register_operand") > + (unspec:VQ2 [(const_int 0)] UNSPEC_VSTRUCTDUMMY)] > + UNSPEC_VST2))] > + "TARGET_NEON || TARGET_HAVE_MVE" > +{ > + if (TARGET_NEON) > + emit_insn (gen_neon_vst2<mode> (operands[0], operands[1])); > + else > + emit_insn (gen_mve_vst2q<mode> (operands[0], operands[1])); > DONE; > }) > diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vld2.c > b/gcc/testsuite/gcc.target/arm/simd/mve-vld2.c > new file mode 100644 > index 0000000..9c7c3f5 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vld2.c > @@ -0,0 +1,96 @@ > +/* { dg-do assemble } */ > +/* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */ > +/* { dg-add-options arm_v8_1m_mve_fp } */ > +/* { dg-additional-options "-O3" } */ > + > +#include <stdint.h> > + > +#define M00 100 > +#define M10 216 > +#define M01 1322 > +#define M11 13 > + > +#define N 128 > + > + > +/* Integer tests. */ > +#define FUNC(SIGN, TYPE, BITS) \ > + void foo_##SIGN##BITS##x (TYPE##BITS##_t *__restrict__ pInput, \ > + TYPE##BITS##_t *__restrict__ pOutput) \ > + { \ > + unsigned int i; \ > + TYPE##BITS##_t a, b; \ > + \ > + for (i = 0; i < N / BITS; i++) \ > + { > \ > + a = *pInput++; \ > + b = *pInput++; \ > + \ > + *pOutput++ = M00 * a + M01 * b; \ > + *pOutput++ = M10 * a + M11 * b; \ > + } > \ > + } > + > +FUNC(s, int, 8) > +FUNC(u, uint, 8) > +FUNC(s, int, 16) > +FUNC(u, uint, 16) > +FUNC(s, int, 32) > +FUNC(u, uint, 32) > + > +/* float test, keep the macro because it's similar to the above, but does not > + need the ##BITS##_t. */ > +#define FUNC_FLOAT(SIGN, TYPE, BITS) \ > + void foo_##SIGN##BITS##x (TYPE *__restrict__ pInput, \ > + TYPE *__restrict__ pOutput) \ > + { \ > + unsigned int i; \ > + TYPE a, b; \ > + \ > + for (i = 0; i < N / BITS; i++) \ > + { > \ > + a = *pInput++; \ > + b = *pInput++; \ > + \ > + *pOutput++ = M00 * a + M01 * b; \ > + *pOutput++ = M10 * a + M11 * b; \ > + } > \ > + } > + > +FUNC_FLOAT(f, float, 32) > + > +/* __fp16 test, needs explicit casts to avoid conversions to floating-point > and > + failure to vectorize. */ > +__fp16 M00_fp16 = 100.0f16; > +__fp16 M10_fp16 = 216.0f16; > +__fp16 M01_fp16 = 1322.0f16; > +__fp16 M11_fp16 = 13.0f16; > + > +#define FUNC_FLOAT_FP16(SIGN, TYPE, BITS) \ > + void foo_##SIGN##BITS##x (TYPE *__restrict__ pInput, \ > + TYPE *__restrict__ pOutput) \ > + { \ > + unsigned int i; \ > + TYPE a, b; \ > + \ > + for (i = 0; i < N / BITS; i++) \ > + { > \ > + a = *pInput++; \ > + b = *pInput++; \ > + \ > + *pOutput++ = (__fp16)(M00_fp16 * a) + (__fp16)(M01_fp16 * b); \ > + *pOutput++ = (__fp16)(M10_fp16 * a) + (__fp16)(M11_fp16 * b); \ > + } > \ > + } > + > +FUNC_FLOAT_FP16(f, __fp16, 16) > + > +/* vld2X.8 is used for signed and unsigned chars: 2 pairs. */ > +/* vld2X.16 is used for signed and unsigned shorts and __fp16: 3 pairs. */ > +/* vld2X.32 is used for signed and unsigned ints and float: 3 pairs. */ > +/* { dg-final { scan-assembler-times {vld2[01].8\t.q[0-9]+, q[0-9]+., } 4 } > } */ > +/* { dg-final { scan-assembler-times {vld2[01].16\t.q[0-9]+, q[0-9]+., } 6 } > } */ > +/* { dg-final { scan-assembler-times {vld2[01].32\t.q[0-9]+, q[0-9]+., } 6 } > } */ > +/* { dg-final { scan-assembler-times {vst2[01].8\t.q[0-9]+, q[0-9]+., } 4 } > } */ > +/* { dg-final { scan-assembler-times {vst2[01].16\t.q[0-9]+, q[0-9]+., } 6 } > } */ > +/* { dg-final { scan-assembler-times {vst2[01].32\t.q[0-9]+, q[0-9]+., } 6 } > } */ > -- > 2.7.4 >