From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1652) id 97CF83887009; Fri, 25 Mar 2022 17:27:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 97CF83887009 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Christophe Lyon To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-7818] arm: Revert Auto-vectorization for MVE: add pack/unpack patterns PR target/104882 X-Act-Checkin: gcc X-Git-Author: Christophe Lyon X-Git-Refname: refs/heads/master X-Git-Oldrev: 25725506b85f478076770942d76799c54310c696 X-Git-Newrev: 3ab5c8cd03d92bf4ec41e351820349d92fbc40c4 Message-Id: <20220325172741.97CF83887009@sourceware.org> Date: Fri, 25 Mar 2022 17:27:41 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Mar 2022 17:27:41 -0000 https://gcc.gnu.org/g:3ab5c8cd03d92bf4ec41e351820349d92fbc40c4 commit r12-7818-g3ab5c8cd03d92bf4ec41e351820349d92fbc40c4 Author: Christophe Lyon Date: Fri Mar 18 08:30:00 2022 +0000 arm: Revert Auto-vectorization for MVE: add pack/unpack patterns PR target/104882 This reverts commit r12-1434-g046a3beb1673bf to fix PR target/104882. As discussed in the PR, it turns out that the MVE ISA has no natural mapping with GCC's vec_pack_trunc / vec_unpack standard patterns, unlike Neon or SVE for instance. This patch also adds the executable testcase provided in the PR. This test passes at -O3 because the generated code does not need to use the pack/unpack patterns, hence the use of -O2 which now triggers vectorization since a few months ago. 2022-03-18 Christophe Lyon PR target/104882 Revert 2021-06-11 Christophe Lyon gcc/ * config/arm/mve.md (mve_vec_unpack_lo_): Delete. (mve_vec_unpack_hi_): Delete. (@mve_vec_pack_trunc_lo_): Delete. (mve_vmovntq_): Remove '@' prefix. * config/arm/neon.md (vec_unpack_hi_): Move back from vec-common.md. (vec_unpack_lo_): Likewise. (vec_pack_trunc_): Rename from neon_quad_vec_pack_trunc_. * config/arm/vec-common.md (vec_unpack_hi_): Delete. (vec_unpack_lo_): Delete. (vec_pack_trunc_): Delete. PR target/104882 gcc/testsuite/ * gcc.target/arm/simd/mve-vclz.c: Update expected results. * gcc.target/arm/simd/mve-vshl.c: Likewise. * gcc.target/arm/simd/mve-vec-pack.c: Delete. * gcc.target/arm/simd/mve-vec-unpack.c: Delete. * gcc.target/arm/simd/pr104882.c: New test. Diff: --- gcc/config/arm/mve.md | 35 +---------- gcc/config/arm/neon.md | 39 +++++++++++- gcc/config/arm/vec-common.md | 71 ---------------------- gcc/testsuite/gcc.target/arm/simd/mve-vclz.c | 7 +-- gcc/testsuite/gcc.target/arm/simd/mve-vec-pack.c | 26 -------- gcc/testsuite/gcc.target/arm/simd/mve-vec-unpack.c | 29 --------- gcc/testsuite/gcc.target/arm/simd/mve-vshl.c | 5 +- gcc/testsuite/gcc.target/arm/simd/pr104882.c | 16 +++++ 8 files changed, 59 insertions(+), 169 deletions(-) diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md index 908bedc9254..369d7a79f6c 100644 --- a/gcc/config/arm/mve.md +++ b/gcc/config/arm/mve.md @@ -535,26 +535,6 @@ [(set_attr "type" "mve_move") ]) -(define_insn "mve_vec_unpack_lo_" - [(set (match_operand: 0 "register_operand" "=w") - (SE: (vec_select: - (match_operand:MVE_3 1 "register_operand" "w") - (match_operand:MVE_3 2 "vect_par_constant_low" ""))))] - "TARGET_HAVE_MVE" - "vmovlb.%# %q0, %q1" - [(set_attr "type" "mve_move")] -) - -(define_insn "mve_vec_unpack_hi_" - [(set (match_operand: 0 "register_operand" "=w") - (SE: (vec_select: - (match_operand:MVE_3 1 "register_operand" "w") - (match_operand:MVE_3 2 "vect_par_constant_high" ""))))] - "TARGET_HAVE_MVE" - "vmovlt.%# %q0, %q1" - [(set_attr "type" "mve_move")] -) - ;; ;; [vcvtpq_s, vcvtpq_u]) ;; @@ -2219,23 +2199,10 @@ [(set_attr "type" "mve_move") ]) -;; vmovnb pattern used by the vec_pack_trunc expander to avoid the -;; need for an uninitialized input operand. -(define_insn "@mve_vec_pack_trunc_lo_" - [ - (set (match_operand: 0 "s_register_operand" "=w") - (unspec: [(match_operand:MVE_5 1 "s_register_operand" "w")] - VMOVNBQ_S)) - ] - "TARGET_HAVE_MVE" - "vmovnb.i%# %q0, %q1" - [(set_attr "type" "mve_move") -]) - ;; ;; [vmovntq_s, vmovntq_u]) ;; -(define_insn "@mve_vmovntq_" +(define_insn "mve_vmovntq_" [ (set (match_operand: 0 "s_register_operand" "=w") (unspec: [(match_operand: 1 "s_register_operand" "0") diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index f270ded4978..275bcc1435e 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -6005,6 +6005,43 @@ if (BYTES_BIG_ENDIAN) [(set_attr "type" "neon_shift_imm_long")] ) +(define_expand "vec_unpack_hi_" + [(match_operand: 0 "register_operand") + (SE: (match_operand:VU 1 "register_operand"))] + "TARGET_NEON && !BYTES_BIG_ENDIAN" + { + rtvec v = rtvec_alloc (/2) ; + rtx t1; + int i; + for (i = 0; i < (/2); i++) + RTVEC_ELT (v, i) = GEN_INT ((/2) + i); + + t1 = gen_rtx_PARALLEL (mode, v); + emit_insn (gen_neon_vec_unpack_hi_ (operands[0], + operands[1], + t1)); + DONE; + } +) + +(define_expand "vec_unpack_lo_" + [(match_operand: 0 "register_operand") + (SE: (match_operand:VU 1 "register_operand"))] + "TARGET_NEON && !BYTES_BIG_ENDIAN" + { + rtvec v = rtvec_alloc (/2) ; + rtx t1; + int i; + for (i = 0; i < (/2) ; i++) + RTVEC_ELT (v, i) = GEN_INT (i); + t1 = gen_rtx_PARALLEL (mode, v); + emit_insn (gen_neon_vec_unpack_lo_ (operands[0], + operands[1], + t1)); + DONE; + } +) + (define_insn "neon_vec_mult_lo_" [(set (match_operand: 0 "register_operand" "=w") (mult: (SE: (vec_select: @@ -6220,7 +6257,7 @@ if (BYTES_BIG_ENDIAN) ; because the ordering of vector elements in Q registers is different from what ; the semantics of the instructions require. -(define_insn "neon_quad_vec_pack_trunc_" +(define_insn "vec_pack_trunc_" [(set (match_operand: 0 "register_operand" "=&w") (vec_concat: (truncate: diff --git a/gcc/config/arm/vec-common.md b/gcc/config/arm/vec-common.md index f13009090af..fd878cba22d 100644 --- a/gcc/config/arm/vec-common.md +++ b/gcc/config/arm/vec-common.md @@ -580,77 +580,6 @@ "ARM_HAVE__ARITH && !TARGET_REALLY_IWMMXT" ) - -;; vmovl[tb] are not available for V4SI on MVE -(define_expand "vec_unpack_hi_" - [(set (match_operand: 0 "register_operand") - (SE: (vec_select: - (match_operand:VU 1 "register_operand") - (match_dup 2))))] - "ARM_HAVE__ARITH - && !TARGET_REALLY_IWMMXT - && ! (mode == V4SImode && TARGET_HAVE_MVE) - && !BYTES_BIG_ENDIAN" - { - rtvec v = rtvec_alloc (/2); - int i; - for (i = 0; i < (/2); i++) - RTVEC_ELT (v, i) = GEN_INT ((/2) + i); - - operands[2] = gen_rtx_PARALLEL (mode, v); - } -) - -;; vmovl[tb] are not available for V4SI on MVE -(define_expand "vec_unpack_lo_" - [(set (match_operand: 0 "register_operand") - (SE: (vec_select: - (match_operand:VU 1 "register_operand") - (match_dup 2))))] - "ARM_HAVE__ARITH - && !TARGET_REALLY_IWMMXT - && ! (mode == V4SImode && TARGET_HAVE_MVE) - && !BYTES_BIG_ENDIAN" - { - rtvec v = rtvec_alloc (/2); - int i; - for (i = 0; i < (/2) ; i++) - RTVEC_ELT (v, i) = GEN_INT (i); - - operands[2] = gen_rtx_PARALLEL (mode, v); - - } -) - -;; vmovn[tb] are not available for V2DI on MVE -(define_expand "vec_pack_trunc_" - [(set (match_operand: 0 "register_operand") - (vec_concat: - (truncate: - (match_operand:VN 1 "register_operand")) - (truncate: - (match_operand:VN 2 "register_operand"))))] - "ARM_HAVE__ARITH - && !TARGET_REALLY_IWMMXT - && ! (mode == V2DImode && TARGET_HAVE_MVE) - && !BYTES_BIG_ENDIAN" - { - if (TARGET_NEON) - { - emit_insn (gen_neon_quad_vec_pack_trunc_ (operands[0], operands[1], - operands[2])); - } - else - { - rtx tmpreg = gen_reg_rtx (mode); - emit_insn (gen_mve_vec_pack_trunc_lo (mode, tmpreg, operands[1])); - emit_insn (gen_mve_vmovntq (VMOVNTQ_S, mode, - operands[0], tmpreg, operands[2])); - } - DONE; - } -) - (define_expand "vec_init" [(match_operand:VDQX 0 "s_register_operand") (match_operand 1 "" "")] diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vclz.c b/gcc/testsuite/gcc.target/arm/simd/mve-vclz.c index 5d6e991cfc6..7068736bc28 100644 --- a/gcc/testsuite/gcc.target/arm/simd/mve-vclz.c +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vclz.c @@ -21,9 +21,8 @@ FUNC(u, uint, 16, clz) FUNC(s, int, 8, clz) FUNC(u, uint, 8, clz) -/* 16 and 8-bit versions still use 32-bit intermediate temporaries, so for - instance instead of using vclz.i8, we need 4 vclz.i32, leading to a total of - 14 vclz.i32 expected in this testcase. */ -/* { dg-final { scan-assembler-times {vclz\.i32 q[0-9]+, q[0-9]+} 14 } } */ +/* 16 and 8-bit versions are not vectorized because they need pack/unpack + patterns since __builtin_clz uses 32-bit parameter and return value. */ +/* { dg-final { scan-assembler-times {vclz\.i32 q[0-9]+, q[0-9]+} 2 } } */ /* { dg-final { scan-assembler-times {vclz\.i16 q[0-9]+, q[0-9]+} 2 { xfail *-*-* } } } */ /* { dg-final { scan-assembler-times {vclz\.i8 q[0-9]+, q[0-9]+} 2 { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vec-pack.c b/gcc/testsuite/gcc.target/arm/simd/mve-vec-pack.c deleted file mode 100644 index 43642b2fec5..00000000000 --- a/gcc/testsuite/gcc.target/arm/simd/mve-vec-pack.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-do compile } */ -/* { dg-require-effective-target arm_v8_1m_mve_ok } */ -/* { dg-add-options arm_v8_1m_mve } */ -/* { dg-additional-options "-O3" } */ - -#include - -#define FUNC(SIGN, TYPE, DSTBITS, BITS, NAME) \ - void test_ ## NAME ##_ ## SIGN ## BITS (TYPE##DSTBITS##_t * __restrict__ dest, \ - TYPE##BITS##_t *a) { \ - int i; \ - for (i=0; i < (256 / BITS); i++) { \ - dest[i] = a[i]; \ - } \ - } - -FUNC(s, int, 16, 32, pack) -FUNC(u, uint, 16, 32, pack) -FUNC(s, int, 8, 16, pack) -FUNC(u, uint, 8, 16, pack) - -/* { dg-final { scan-assembler-times {vmovnt\.i32\tq[0-9]+, q[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {vmovnb\.i32\tq[0-9]+, q[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {vmovnt\.i16\tq[0-9]+, q[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-times {vmovnb\.i16\tq[0-9]+, q[0-9]+} 2 } } */ -/* { dg-final { scan-assembler-not {vldr\.64\td[0-9]+, \.L} } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vec-unpack.c b/gcc/testsuite/gcc.target/arm/simd/mve-vec-unpack.c deleted file mode 100644 index cdc62f854ad..00000000000 --- a/gcc/testsuite/gcc.target/arm/simd/mve-vec-unpack.c +++ /dev/null @@ -1,29 +0,0 @@ -/* { dg-do compile } */ -/* { dg-require-effective-target arm_v8_1m_mve_ok } */ -/* { dg-add-options arm_v8_1m_mve } */ -/* { dg-additional-options "-O3" } */ - -#include - -#define FUNC(SIGN, TYPE, DSTBITS, BITS, NAME) \ - void test_ ## NAME ##_ ## SIGN ## BITS (TYPE##DSTBITS##_t * __restrict__ dest, \ - TYPE##BITS##_t *a) { \ - int i; \ - for (i=0; i < (128 / BITS); i++) { \ - dest[i] = a[i]; \ - } \ - } - -FUNC(s, int, 32, 16, unpack) -FUNC(u, uint, 32, 16, unpack) -FUNC(s, int, 16, 8, unpack) -FUNC(u, uint, 16, 8, unpack) - -/* { dg-final { scan-assembler-times {vmovlt\.s16 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlb\.s16 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlt\.u16 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlb\.u16 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlt\.s8 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlb\.s8 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlt\.u8 q[0-9]+, q[0-9]+} 1 } } */ -/* { dg-final { scan-assembler-times {vmovlb\.u8 q[0-9]+, q[0-9]+} 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c b/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c index 91dd942d818..7a0644997c8 100644 --- a/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c +++ b/gcc/testsuite/gcc.target/arm/simd/mve-vshl.c @@ -56,10 +56,7 @@ 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. */ -/* 16 and 8-bit versions still use 32-bit intermediate temporaries, so for - instance instead of using vshl.u8, we need 4 vshl.i32, leading to a total of - 14 vshl.i32 expected in this testcase. */ -/* { dg-final { scan-assembler-times {vshl.u[0-9]+\tq[0-9]+, q[0-9]+} 14 } } */ +/* { 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 } } */ diff --git a/gcc/testsuite/gcc.target/arm/simd/pr104882.c b/gcc/testsuite/gcc.target/arm/simd/pr104882.c new file mode 100644 index 00000000000..ae9709af42f --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/simd/pr104882.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O2" } */ + +int i; +char src[1072]; +char dst[72]; +int main() { + for (i = 0; i < 128; i++) + src[i] = i; + __builtin_memcpy(dst, src, 7); + for (i = 0; i < 7; i++) + if (dst[i] != i) + __builtin_abort(); +}