From fe5788862ba8d5ac4551658d842f2d038bd8d363 Mon Sep 17 00:00:00 2001 From: Juzhe-Zhong Date: Wed, 16 Aug 2023 09:45:19 +0800 Subject: [PATCH] RISC-V: Support MASK_LEN_{LOAD_LANES,STORE_LANES} This patch allow us auto-vectorize this following case: void __attribute__ ((noinline, noclone)) \ NAME##_8 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ MASKTYPE *__restrict cond, intptr_t n) \ { \ for (intptr_t i = 0; i < n; ++i) \ if (cond[i]) \ dest[i] = (src[i * 8] + src[i * 8 + 1] + src[i * 8 + 2] \ + src[i * 8 + 3] + src[i * 8 + 4] + src[i * 8 + 5] \ + src[i * 8 + 6] + src[i * 8 + 7]); \ } TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, int32_t) \ TEST2 (NAME##_i32, OUTTYPE, int32_t) \ TEST1 (NAME##_i32, int32_t) \ TEST (test) ASM: test_i32_i32_f32_8: ble a3,zero,.L5 .L3: vsetvli a4,a3,e8,mf4,ta,ma vle32.v v0,0(a2) vsetvli a5,zero,e32,m1,ta,ma vmsne.vi v0,v0,0 vsetvli zero,a4,e32,m1,ta,ma vlseg8e32.v v8,(a1),v0.t vsetvli a5,zero,e32,m1,ta,ma slli a6,a4,2 vadd.vv v1,v9,v8 slli a7,a4,5 vadd.vv v1,v1,v10 sub a3,a3,a4 vadd.vv v1,v1,v11 vadd.vv v1,v1,v12 vadd.vv v1,v1,v13 vadd.vv v1,v1,v14 vadd.vv v1,v1,v15 vsetvli zero,a4,e32,m1,ta,ma vse32.v v1,0(a0),v0.t add a2,a2,a6 add a1,a1,a7 add a0,a0,a6 bne a3,zero,.L3 .L5: ret gcc/ChangeLog: * config/riscv/autovec.md (vec_mask_len_load_lanes): New pattern. (vec_mask_len_store_lanes): Ditto. * config/riscv/riscv-protos.h (expand_lanes_load_store): New function. * config/riscv/riscv-v.cc (get_mask_mode): Add tuple mask mode. (expand_lanes_load_store): New function. * config/riscv/vector-iterators.md: New iterator. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c: Adapt test. * gcc.target/riscv/rvv/autovec/partial/slp-1.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-16.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-17.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-18.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-19.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-2.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-3.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-4.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-5.c: Ditto. * gcc.target/riscv/rvv/autovec/partial/slp-6.c: Ditto. * gcc.target/riscv/rvv/rvv.exp: Add lanes tests. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c: New test. * gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c: New test. * gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c: New test. --- gcc/config/riscv/autovec.md | 30 +++ gcc/config/riscv/riscv-protos.h | 1 + gcc/config/riscv/riscv-v.cc | 52 +++- gcc/config/riscv/vector-iterators.md | 95 +++++++ .../autovec/gather-scatter/strided_load-2.c | 2 +- .../riscv/rvv/autovec/partial/slp-1.c | 7 +- .../riscv/rvv/autovec/partial/slp-16.c | 5 +- .../riscv/rvv/autovec/partial/slp-17.c | 5 +- .../riscv/rvv/autovec/partial/slp-18.c | 5 +- .../riscv/rvv/autovec/partial/slp-19.c | 4 +- .../riscv/rvv/autovec/partial/slp-2.c | 5 +- .../riscv/rvv/autovec/partial/slp-3.c | 3 +- .../riscv/rvv/autovec/partial/slp-4.c | 5 +- .../riscv/rvv/autovec/partial/slp-5.c | 3 +- .../riscv/rvv/autovec/partial/slp-6.c | 5 +- .../rvv/autovec/struct/mask_struct_load-1.c | 42 ++++ .../rvv/autovec/struct/mask_struct_load-2.c | 44 ++++ .../rvv/autovec/struct/mask_struct_load-3.c | 45 ++++ .../rvv/autovec/struct/mask_struct_load-4.c | 43 ++++ .../rvv/autovec/struct/mask_struct_load-5.c | 43 ++++ .../rvv/autovec/struct/mask_struct_load-6.c | 44 ++++ .../rvv/autovec/struct/mask_struct_load-7.c | 44 ++++ .../autovec/struct/mask_struct_load_run-1.c | 38 +++ .../autovec/struct/mask_struct_load_run-2.c | 40 +++ .../autovec/struct/mask_struct_load_run-3.c | 41 ++++ .../autovec/struct/mask_struct_load_run-4.c | 42 ++++ .../autovec/struct/mask_struct_load_run-5.c | 43 ++++ .../autovec/struct/mask_struct_load_run-6.c | 44 ++++ .../autovec/struct/mask_struct_load_run-7.c | 45 ++++ .../rvv/autovec/struct/mask_struct_store-1.c | 48 ++++ .../rvv/autovec/struct/mask_struct_store-2.c | 49 ++++ .../rvv/autovec/struct/mask_struct_store-3.c | 50 ++++ .../rvv/autovec/struct/mask_struct_store-4.c | 51 ++++ .../rvv/autovec/struct/mask_struct_store-5.c | 52 ++++ .../rvv/autovec/struct/mask_struct_store-6.c | 53 ++++ .../rvv/autovec/struct/mask_struct_store-7.c | 54 ++++ .../autovec/struct/mask_struct_store_run-1.c | 38 +++ .../autovec/struct/mask_struct_store_run-2.c | 38 +++ .../autovec/struct/mask_struct_store_run-3.c | 38 +++ .../autovec/struct/mask_struct_store_run-4.c | 38 +++ .../autovec/struct/mask_struct_store_run-5.c | 38 +++ .../autovec/struct/mask_struct_store_run-6.c | 38 +++ .../autovec/struct/mask_struct_store_run-7.c | 38 +++ .../riscv/rvv/autovec/struct/struct_vect-1.c | 232 ++++++++++++++++++ .../riscv/rvv/autovec/struct/struct_vect-10.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-11.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-12.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-13.c | 27 ++ .../riscv/rvv/autovec/struct/struct_vect-14.c | 25 ++ .../riscv/rvv/autovec/struct/struct_vect-15.c | 27 ++ .../riscv/rvv/autovec/struct/struct_vect-16.c | 25 ++ .../riscv/rvv/autovec/struct/struct_vect-17.c | 27 ++ .../riscv/rvv/autovec/struct/struct_vect-18.c | 25 ++ .../riscv/rvv/autovec/struct/struct_vect-2.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-3.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-4.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-5.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-6.c | 225 +++++++++++++++++ .../riscv/rvv/autovec/struct/struct_vect-7.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-8.c | 22 ++ .../riscv/rvv/autovec/struct/struct_vect-9.c | 22 ++ .../rvv/autovec/struct/struct_vect_run-1.c | 139 +++++++++++ .../rvv/autovec/struct/struct_vect_run-10.c | 6 + .../rvv/autovec/struct/struct_vect_run-11.c | 6 + .../rvv/autovec/struct/struct_vect_run-12.c | 6 + .../rvv/autovec/struct/struct_vect_run-13.c | 36 +++ .../rvv/autovec/struct/struct_vect_run-14.c | 45 ++++ .../rvv/autovec/struct/struct_vect_run-15.c | 36 +++ .../rvv/autovec/struct/struct_vect_run-16.c | 45 ++++ .../rvv/autovec/struct/struct_vect_run-17.c | 36 +++ .../rvv/autovec/struct/struct_vect_run-18.c | 45 ++++ .../rvv/autovec/struct/struct_vect_run-2.c | 5 + .../rvv/autovec/struct/struct_vect_run-3.c | 5 + .../rvv/autovec/struct/struct_vect_run-4.c | 5 + .../rvv/autovec/struct/struct_vect_run-5.c | 5 + .../rvv/autovec/struct/struct_vect_run-6.c | 141 +++++++++++ .../rvv/autovec/struct/struct_vect_run-7.c | 6 + .../rvv/autovec/struct/struct_vect_run-8.c | 6 + .../rvv/autovec/struct/struct_vect_run-9.c | 6 + gcc/testsuite/gcc.target/riscv/rvv/rvv.exp | 2 + 80 files changed, 2841 insertions(+), 21 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md index cf4efbae44fbb..21cf2ffaec59d 100644 --- a/gcc/config/riscv/autovec.md +++ b/gcc/config/riscv/autovec.md @@ -283,6 +283,36 @@ DONE; }) +;; ========================================================================= +;; == Array Load/Store +;; ========================================================================= + +(define_expand "vec_mask_len_load_lanes" + [(match_operand:VT 0 "register_operand") + (match_operand:VT 1 "memory_operand") + (match_operand: 2 "vector_mask_operand") + (match_operand 3 "autovec_length_operand") + (match_operand 4 "const_0_operand")] + "TARGET_VECTOR" + { + riscv_vector::expand_lanes_load_store (operands, true); + DONE; + } +) + +(define_expand "vec_mask_len_store_lanes" + [(match_operand:VT 0 "memory_operand") + (match_operand:VT 1 "register_operand") + (match_operand: 2 "vector_mask_operand") + (match_operand 3 "autovec_length_operand") + (match_operand 4 "const_0_operand")] + "TARGET_VECTOR" + { + riscv_vector::expand_lanes_load_store (operands, false); + DONE; + } +) + ;; ========================================================================= ;; == Vector creation ;; ========================================================================= diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 2fbed04ff84c8..472c00dc43954 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -325,6 +325,7 @@ void expand_load_store (rtx *, bool); void expand_gather_scatter (rtx *, bool); void expand_cond_len_ternop (unsigned, rtx *); void prepare_ternary_operands (rtx *, bool = false); +void expand_lanes_load_store (rtx *, bool); /* Rounding mode bitfield for fixed point VXRM. */ enum fixed_point_rounding_mode diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index 5f9b296c92e71..b01028c620138 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -1900,7 +1900,13 @@ get_avl_type_rtx (enum avl_type type) machine_mode get_mask_mode (machine_mode mode) { - return get_vector_mode (BImode, GET_MODE_NUNITS (mode)).require(); + poly_int64 nunits = GET_MODE_NUNITS (mode); + if (riscv_v_ext_tuple_mode_p (mode)) + { + unsigned int nf = get_nf (mode); + nunits = exact_div (nunits, nf); + } + return get_vector_mode (BImode, nunits).require (); } /* Return the appropriate M1 mode for MODE. */ @@ -3716,4 +3722,48 @@ prepare_ternary_operands (rtx *ops, bool split_p) } } +/* Expand VEC_MASK_LEN_{LOAD_LANES,STORE_LANES}. */ +void +expand_lanes_load_store (rtx *ops, bool is_load) +{ + poly_int64 value; + rtx mask = ops[2]; + rtx len = ops[3]; + rtx addr = is_load ? XEXP (ops[1], 0) : XEXP (ops[0], 0); + rtx reg = is_load ? ops[0] : ops[1]; + machine_mode mode = GET_MODE (ops[0]); + + if (poly_int_rtx_p (len, &value) && known_eq (value, GET_MODE_NUNITS (mode))) + { + /* If the length operand is equal to VF, it is VLMAX load/store. */ + if (is_load) + { + rtx m_ops[] = {reg, mask, RVV_VUNDEF (mode), addr}; + emit_vlmax_masked_insn (code_for_pred_unit_strided_load (mode), + RVV_UNOP_M, m_ops); + } + else + { + len = gen_reg_rtx (Pmode); + emit_vlmax_vsetvl (mode, len); + emit_insn (gen_pred_unit_strided_store (mode, mask, addr, reg, len, + get_avl_type_rtx (VLMAX))); + } + } + else + { + if (!satisfies_constraint_K (len)) + len = force_reg (Pmode, len); + if (is_load) + { + rtx m_ops[] = {reg, mask, RVV_VUNDEF (mode), addr}; + emit_nonvlmax_masked_insn (code_for_pred_unit_strided_load (mode), + RVV_UNOP_M, m_ops, len); + } + else + emit_insn (gen_pred_unit_strided_store (mode, mask, addr, reg, len, + get_avl_type_rtx (NONVLMAX))); + } +} + } // namespace riscv_vector diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 9dd611e254b8c..fc237ac330d7b 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -1417,6 +1417,101 @@ (V1DF "df") (V2DF "df") (V4DF "df") (V8DF "df") (V16DF "df") (V32DF "df") (V64DF "df") (V128DF "df") (V256DF "df") (V512DF "df") ]) +(define_mode_attr vsingle [ + (RVVM1x8QI "rvvm1qi") (RVVMF2x8QI "rvvmf2qi") (RVVMF4x8QI "rvvmf4qi") (RVVMF8x8QI "rvvmf8qi") + (RVVM1x7QI "rvvm1qi") (RVVMF2x7QI "rvvmf2qi") (RVVMF4x7QI "rvvmf4qi") (RVVMF8x7QI "rvvmf8qi") + (RVVM1x6QI "rvvm1qi") (RVVMF2x6QI "rvvmf2qi") (RVVMF4x6QI "rvvmf4qi") (RVVMF8x6QI "rvvmf8qi") + (RVVM1x5QI "rvvm1qi") (RVVMF2x5QI "rvvmf2qi") (RVVMF4x5QI "rvvmf4qi") (RVVMF8x5QI "rvvmf8qi") + (RVVM2x4QI "rvvm2qi") (RVVM1x4QI "rvvm1qi") (RVVMF2x4QI "rvvmf2qi") (RVVMF4x4QI "rvvmf4qi") (RVVMF8x4QI "rvvmf8qi") + (RVVM2x3QI "rvvm2qi") (RVVM1x3QI "rvvm1qi") (RVVMF2x3QI "rvvmf2qi") (RVVMF4x3QI "rvvmf4qi") (RVVMF8x3QI "rvvmf8qi") + (RVVM4x2QI "rvvm4qi") (RVVM2x2QI "rvvm1qi") (RVVM1x2QI "rvvm1qi") (RVVMF2x2QI "rvvmf2qi") (RVVMF4x2QI "rvvmf4qi") (RVVMF8x2QI "rvvmf8qi") + + (RVVM1x8HI "rvvm1hi") (RVVMF2x8HI "rvvmf2hi") (RVVMF4x8HI "rvvmf4hi") + (RVVM1x7HI "rvvm1hi") (RVVMF2x7HI "rvvmf2hi") (RVVMF4x7HI "rvvmf4hi") + (RVVM1x6HI "rvvm1hi") (RVVMF2x6HI "rvvmf2hi") (RVVMF4x6HI "rvvmf4hi") + (RVVM1x5HI "rvvm1hi") (RVVMF2x5HI "rvvmf2hi") (RVVMF4x5HI "rvvmf4hi") + (RVVM2x4HI "rvvm2hi") (RVVM1x4HI "rvvm1hi") (RVVMF2x4HI "rvvmf2hi") (RVVMF4x4HI "rvvmf4hi") + (RVVM2x3HI "rvvm2hi") (RVVM1x3HI "rvvm1hi") (RVVMF2x3HI "rvvmf2hi") (RVVMF4x3HI "rvvmf4hi") + (RVVM4x2HI "rvvm4hi") (RVVM2x2HI "rvvm2hi") (RVVM1x2HI "rvvm1hi") (RVVMF2x2HI "rvvmf2hi") (RVVMF4x2HI "rvvmf4hi") + + (RVVM1x8HF "rvvm1hf") + (RVVMF2x8HF "rvvmf2hf") + (RVVMF4x8HF "rvvmf4hf") + (RVVM1x7HF "rvvm1hf") + (RVVMF2x7HF "rvvmf2hf") + (RVVMF4x7HF "rvvmf4hf") + (RVVM1x6HF "rvvm1hf") + (RVVMF2x6HF "rvvmf2hf") + (RVVMF4x6HF "rvvmf4hf") + (RVVM1x5HF "rvvm1hf") + (RVVMF2x5HF "rvvmf2hf") + (RVVMF4x5HF "rvvmf4hf") + (RVVM2x4HF "rvvm2hf") + (RVVM1x4HF "rvvm1hf") + (RVVMF2x4HF "rvvmf2hf") + (RVVMF4x4HF "rvvmf4hf") + (RVVM2x3HF "rvvm2hf") + (RVVM1x3HF "rvvm1hf") + (RVVMF2x3HF "rvvmf2hf") + (RVVMF4x3HF "rvvmf4hf") + (RVVM4x2HF "rvvm4hf") + (RVVM2x2HF "rvvm2hf") + (RVVM1x2HF "rvvm1hf") + (RVVMF2x2HF "rvvmf2hf") + (RVVMF4x2HF "rvvmf4hf") + + (RVVM1x8SI "rvvm1si") (RVVMF2x8SI "rvvmf2si") + (RVVM1x7SI "rvvm1si") (RVVMF2x7SI "rvvmf2si") + (RVVM1x6SI "rvvm1si") (RVVMF2x6SI "rvvmf2si") + (RVVM1x5SI "rvvm1si") (RVVMF2x5SI "rvvmf2si") + (RVVM2x4SI "rvvm2si") (RVVM1x4SI "rvvm1si") (RVVMF2x4SI "rvvmf2si") + (RVVM2x3SI "rvvm2si") (RVVM1x3SI "rvvm1si") (RVVMF2x3SI "rvvmf2si") + (RVVM4x2SI "rvvm4si") (RVVM2x2SI "rvvm2si") (RVVM1x2SI "rvvm1si") (RVVMF2x2SI "rvvmf2si") + + (RVVM1x8SF "rvvm1sf") + (RVVMF2x8SF "rvvmf2sf") + (RVVM1x7SF "rvvm1sf") + (RVVMF2x7SF "rvvmf2sf") + (RVVM1x6SF "rvvm1sf") + (RVVMF2x6SF "rvvmf2sf") + (RVVM1x5SF "rvvm1sf") + (RVVMF2x5SF "rvvmf2sf") + (RVVM2x4SF "rvvm2sf") + (RVVM1x4SF "rvvm1sf") + (RVVMF2x4SF "rvvmf2sf") + (RVVM2x3SF "rvvm2sf") + (RVVM1x3SF "rvvm1sf") + (RVVMF2x3SF "rvvmf2sf") + (RVVM4x2SF "rvvm4sf") + (RVVM2x2SF "rvvm2sf") + (RVVM1x2SF "rvvm1sf") + (RVVMF2x2SF "rvvmf2sf") + + (RVVM1x8DI "rvvm1di") + (RVVM1x7DI "rvvm1di") + (RVVM1x6DI "rvvm1di") + (RVVM1x5DI "rvvm1di") + (RVVM2x4DI "rvvm2di") + (RVVM1x4DI "rvvm1di") + (RVVM2x3DI "rvvm2di") + (RVVM1x3DI "rvvm1di") + (RVVM4x2DI "rvvm4di") + (RVVM2x2DI "rvvm2di") + (RVVM1x2DI "rvvm1di") + + (RVVM1x8DF "rvvm1df") + (RVVM1x7DF "rvvm1df") + (RVVM1x6DF "rvvm1df") + (RVVM1x5DF "rvvm1df") + (RVVM2x4DF "rvvm2df") + (RVVM1x4DF "rvvm1df") + (RVVM2x3DF "rvvm2df") + (RVVM1x3DF "rvvm1df") + (RVVM4x2DF "rvvm4df") + (RVVM2x2DF "rvvm2df") + (RVVM1x2DF "rvvm1df") +]) + (define_mode_attr VSUBEL [ (RVVM8HI "QI") (RVVM4HI "QI") (RVVM2HI "QI") (RVVM1HI "QI") (RVVMF2HI "QI") (RVVMF4HI "QI") diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c index ee5f509b9ac92..2c9e7dd14a8f9 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/gather-scatter/strided_load-2.c @@ -40,6 +40,6 @@ TEST_ALL (TEST_LOOP) -/* { dg-final { scan-tree-dump-times " \.MASK_LEN_GATHER_LOAD" 46 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \.MASK_LEN_GATHER_LOAD" 33 "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.GATHER_LOAD" "optimized" } } */ /* { dg-final { scan-tree-dump-not " \.MASK_GATHER_LOAD" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c index 0bce83613271c..788e0450b47b8 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-1.c @@ -19,6 +19,7 @@ f (int8_t *restrict a, int8_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ -/* { dg-final { scan-assembler {\tvid\.v} } } */ -/* { dg-final { scan-assembler {\tvand} } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\tvand} { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c index 1a35bba013b15..b58e270eaa491 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-16.c @@ -19,6 +19,7 @@ f (uint8_t *restrict a, uint8_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ -/* { dg-final { scan-assembler {\tvid\.v} } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */ /* { dg-final { scan-assembler-not {\tvmul} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c index 2f2c3d11c2ae1..bccf3e6570a4e 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-17.c @@ -29,6 +29,7 @@ f (uint8_t *restrict a, uint8_t *restrict b, } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 2 "optimized" } } */ -/* { dg-final { scan-assembler {\tvid\.v} } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 2 "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */ /* { dg-final { scan-assembler-not {\tvmul} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c index 72103314b1ab2..f00bece141435 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-18.c @@ -21,6 +21,7 @@ f (float *restrict a, float *restrict b, } } -/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" } } */ -/* { dg-final { scan-assembler {\tvid\.v} } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */ /* { dg-final { scan-assembler-not {\tvmul} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c index 41ce0fc57675d..67db75517c348 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-19.c @@ -21,6 +21,6 @@ f (float *restrict a, float *restrict b, } } -/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" } } */ -/* { dg-final { scan-assembler {\tvid\.v} } } */ +/* { dg-final { scan-tree-dump "\.VEC_PERM" "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-assembler {\tvid\.v} { xfail *-*-* } } } */ /* { dg-final { scan-assembler-not {\tvmul} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c index ac817451295b1..ad60b11d81562 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */ #include @@ -19,4 +19,5 @@ f (int16_t *restrict a, int16_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c index 73962055b0324..088828f326fd0 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-3.c @@ -19,4 +19,5 @@ f (int8_t *restrict a, int8_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c index fa216fc8c400a..d56feeb8fdfb4 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fno-vect-cost-model -fdump-tree-optimized-details" } */ #include @@ -19,4 +19,5 @@ f (int16_t *restrict a, int16_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c index 899ed9e310be2..d825a257ccdc3 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-5.c @@ -19,4 +19,5 @@ f (int8_t *restrict a, int8_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c index fb87cc00ceada..160880c42b78f 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/partial/slp-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details" } */ +/* { dg-additional-options "-march=rv32gcv -mabi=ilp32d --param riscv-autovec-preference=scalable -fdump-tree-optimized-details -fno-vect-cost-model" } */ #include @@ -19,5 +19,6 @@ f (uint8_t *restrict a, uint8_t *restrict b, int n) } } -/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" } } */ +/* FIXME: Since we don't have VECT cost model yet, LOAD_LANES/STORE_LANES are chosen instead of SLP. */ +/* { dg-final { scan-tree-dump-times "\.VEC_PERM" 1 "optimized" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c new file mode 100644 index 0000000000000..e5dc10aea8816 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-1.c @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_2 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] = src[i * 2] + src[i * 2 + 1]; \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg2e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg2e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg2e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg2e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c new file mode 100644 index 0000000000000..9d61a85267af0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-2.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_3 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] = (src[i * 3] \ + + src[i * 3 + 1] \ + + src[i * 3 + 2]); \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg3e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg3e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg3e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c new file mode 100644 index 0000000000000..a686236793a36 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-3.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_4 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] = (src[i * 4] \ + + src[i * 4 + 1] \ + + src[i * 4 + 2] \ + + src[i * 4 + 3]); \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg4e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg4e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg4e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c new file mode 100644 index 0000000000000..e3c48df5d3bb0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-4.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_5 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] = (src[i * 5] + src[i * 5 + 1] + src[i * 5 + 2] \ + + src[i * 5 + 3] + src[i * 5 + 4]); \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg5e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg5e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg5e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg5e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c new file mode 100644 index 0000000000000..81f1a7a5ef4b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-5.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_6 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] = (src[i * 6] + src[i * 6 + 1] + src[i * 6 + 2] \ + + src[i * 6 + 3] + src[i * 6 + 4] + src[i * 6 + 5]); \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg6e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg6e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg6e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg6e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c new file mode 100644 index 0000000000000..911af2a853daa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-6.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_7 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] \ + = (src[i * 7] + src[i * 7 + 1] + src[i * 7 + 2] + src[i * 7 + 3] \ + + src[i * 7 + 4] + src[i * 7 + 5] + src[i * 7 + 6]); \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg7e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg7e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg7e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg7e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c new file mode 100644 index 0000000000000..112facee5ad42 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load-7.c @@ -0,0 +1,44 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_8 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + if (cond[i]) \ + dest[i] = (src[i * 8] + src[i * 8 + 1] + src[i * 8 + 2] \ + + src[i * 8 + 3] + src[i * 8 + 4] + src[i * 8 + 5] \ + + src[i * 8 + 6] + src[i * 8 + 7]); \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg8e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vlseg8e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg8e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vlseg8e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c new file mode 100644 index 0000000000000..232ebceb9fc23 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-1.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-1.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 2]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 2; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_2 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = in[i * 2] + in[i * 2 + 1]; \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c new file mode 100644 index 0000000000000..309baf32bc9e3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-2.c @@ -0,0 +1,40 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-2.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 3]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 3; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_3 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = (in[i * 3] \ + + in[i * 3 + 1] \ + + in[i * 3 + 2]); \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c new file mode 100644 index 0000000000000..2c818bbc1175a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-3.c @@ -0,0 +1,41 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-3.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 4]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 4; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_4 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = (in[i * 4] \ + + in[i * 4 + 1] \ + + in[i * 4 + 2] \ + + in[i * 4 + 3]); \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c new file mode 100644 index 0000000000000..c2135b8c452e1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-4.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-4.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 5]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 5; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_5 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = (in[i * 5] \ + + in[i * 5 + 1] \ + + in[i * 5 + 2] \ + + in[i * 5 + 3] \ + + in[i * 5 + 4]); \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c new file mode 100644 index 0000000000000..029769994aa81 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-5.c @@ -0,0 +1,43 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-5.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 6]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 6; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_6 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = (in[i * 6] \ + + in[i * 6 + 1] \ + + in[i * 6 + 2] \ + + in[i * 6 + 3] \ + + in[i * 6 + 4] \ + + in[i * 6 + 5]); \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c new file mode 100644 index 0000000000000..c24c6411d5cef --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-6.c @@ -0,0 +1,44 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-6.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 7]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 7; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_7 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = (in[i * 7] \ + + in[i * 7 + 1] \ + + in[i * 7 + 2] \ + + in[i * 7 + 3] \ + + in[i * 7 + 4] \ + + in[i * 7 + 5] \ + + in[i * 7 + 6]); \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c new file mode 100644 index 0000000000000..be65d948da5e9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_load_run-7.c @@ -0,0 +1,45 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_load-7.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N]; \ + INTYPE in[N * 8]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 8; ++i) \ + in[i] = i * 9 / 2; \ + NAME##_8 (out, in, mask, N); \ + for (int i = 0; i < N; ++i) \ + { \ + OUTTYPE if_true = (in[i * 8] \ + + in[i * 8 + 1] \ + + in[i * 8 + 2] \ + + in[i * 8 + 3] \ + + in[i * 8 + 4] \ + + in[i * 8 + 5] \ + + in[i * 8 + 6] \ + + in[i * 8 + 7]); \ + OUTTYPE if_false = i * 7 / 2; \ + if (out[i] != (mask[i] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c new file mode 100644 index 0000000000000..6df5f08dbc015 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-1.c @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_2 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 2] = value; \ + dest[i * 2 + 1] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg2e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg2e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg2e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg2e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c new file mode 100644 index 0000000000000..532b4580b2003 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-2.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_3 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 3] = value; \ + dest[i * 3 + 1] = value; \ + dest[i * 3 + 2] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg3e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg3e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg3e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg3e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c new file mode 100644 index 0000000000000..92ed2361e37cf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-3.c @@ -0,0 +1,50 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_4 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 4] = value; \ + dest[i * 4 + 1] = value; \ + dest[i * 4 + 2] = value; \ + dest[i * 4 + 3] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg4e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg4e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg4e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg4e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c new file mode 100644 index 0000000000000..4a4048f6921c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-4.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_5 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 5] = value; \ + dest[i * 5 + 1] = value; \ + dest[i * 5 + 2] = value; \ + dest[i * 5 + 3] = value; \ + dest[i * 5 + 4] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg5e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg5e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg5e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg5e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c new file mode 100644 index 0000000000000..eca8d5aa00305 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-5.c @@ -0,0 +1,52 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_6 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 6] = value; \ + dest[i * 6 + 1] = value; \ + dest[i * 6 + 2] = value; \ + dest[i * 6 + 3] = value; \ + dest[i * 6 + 4] = value; \ + dest[i * 6 + 5] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg6e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg6e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg6e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg6e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c new file mode 100644 index 0000000000000..3cce1620930d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-6.c @@ -0,0 +1,53 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_7 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 7] = value; \ + dest[i * 7 + 1] = value; \ + dest[i * 7 + 2] = value; \ + dest[i * 7 + 3] = value; \ + dest[i * 7 + 4] = value; \ + dest[i * 7 + 5] = value; \ + dest[i * 7 + 6] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg7e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg7e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg7e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg7e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c new file mode 100644 index 0000000000000..9d0073bcf0ef7 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store-7.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME##_8 (OUTTYPE *__restrict dest, INTYPE *__restrict src, \ + MASKTYPE *__restrict cond, INTYPE bias, intptr_t n) \ + { \ + for (intptr_t i = 0; i < n; ++i) \ + { \ + INTYPE value = src[i] + bias; \ + if (cond[i]) \ + { \ + dest[i * 8] = value; \ + dest[i * 8 + 1] = value; \ + dest[i * 8 + 2] = value; \ + dest[i * 8 + 3] = value; \ + dest[i * 8 + 4] = value; \ + dest[i * 8 + 5] = value; \ + dest[i * 8 + 6] = value; \ + dest[i * 8 + 7] = value; \ + } \ + } \ + } + +#define TEST2(NAME, OUTTYPE, INTYPE) \ + TEST_LOOP (NAME##_i8, OUTTYPE, INTYPE, int8_t) \ + TEST_LOOP (NAME##_i16, OUTTYPE, INTYPE, uint16_t) \ + TEST_LOOP (NAME##_f32, OUTTYPE, INTYPE, float) \ + TEST_LOOP (NAME##_f64, OUTTYPE, INTYPE, double) + +#define TEST1(NAME, OUTTYPE) \ + TEST2 (NAME##_i8, OUTTYPE, int8_t) \ + TEST2 (NAME##_i16, OUTTYPE, uint16_t) \ + TEST2 (NAME##_i32, OUTTYPE, int32_t) \ + TEST2 (NAME##_i64, OUTTYPE, uint64_t) + +#define TEST(NAME) \ + TEST1 (NAME##_i8, int8_t) \ + TEST1 (NAME##_i16, uint16_t) \ + TEST1 (NAME##_i32, int32_t) \ + TEST1 (NAME##_i64, uint64_t) \ + TEST2 (NAME##_f16_f16, _Float16, _Float16) \ + TEST2 (NAME##_f32_f32, float, float) \ + TEST2 (NAME##_f64_f64, double, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vsseg8e8\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 16 } } */ +/* { dg-final { scan-assembler-times {vsseg8e16\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg8e32\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ +/* { dg-final { scan-assembler-times {vsseg8e64\.v\s+v[0-9]+,\s*\([a-x0-9]+\),\s*v0.t} 20 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c new file mode 100644 index 0000000000000..1208ea7ad5884 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-1.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-1.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 2]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 2; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_2 (out, in, mask, 17, N); \ + for (int i = 0; i < N * 2; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 2] + 17); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 2] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c new file mode 100644 index 0000000000000..199402f596f11 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-2.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-2.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 3]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 3; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_3 (out, in, mask, 11, N); \ + for (int i = 0; i < N * 3; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 3] + 11); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 3] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c new file mode 100644 index 0000000000000..22fc0d5ac01fe --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-3.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-3.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 4]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 4; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_4 (out, in, mask, 42, N); \ + for (int i = 0; i < N * 4; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 4] + 42); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 4] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c new file mode 100644 index 0000000000000..807e06e552cb4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-4.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-4.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 5]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 5; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_5 (out, in, mask, 42, N); \ + for (int i = 0; i < N * 5; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 5] + 42); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 5] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c new file mode 100644 index 0000000000000..3ce3774fcc5c1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-5.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-5.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 6]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 6; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_6 (out, in, mask, 42, N); \ + for (int i = 0; i < N * 6; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 6] + 42); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 6] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c new file mode 100644 index 0000000000000..8a22844bbebad --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-6.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-6.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 7]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 7 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 7; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_7 (out, in, mask, 42, N); \ + for (int i = 0; i < N * 7; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 7] + 42); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 7] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c new file mode 100644 index 0000000000000..af80f30ec4c42 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/mask_struct_store_run-7.c @@ -0,0 +1,38 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "mask_struct_store-7.c" + +#define N 100 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, OUTTYPE, INTYPE, MASKTYPE) \ + { \ + OUTTYPE out[N * 8]; \ + INTYPE in[N]; \ + MASKTYPE mask[N]; \ + for (int i = 0; i < N; ++i) \ + { \ + in[i] = i * 8 / 2; \ + mask[i] = i % 5 <= i % 3; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 8; ++i) \ + out[i] = i * 9 / 2; \ + NAME##_8 (out, in, mask, 42, N); \ + for (int i = 0; i < N * 8; ++i) \ + { \ + OUTTYPE if_true = (INTYPE) (in[i / 8] + 42); \ + OUTTYPE if_false = i * 9 / 2; \ + if (out[i] != (mask[i / 8] ? if_true : if_false)) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c new file mode 100644 index 0000000000000..f49d92d74302b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-1.c @@ -0,0 +1,232 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#include +#ifndef TYPE +#define TYPE uint8_t +#endif + +#ifndef NAME +#define NAME(X) X +#endif + +#ifndef N +#define N 1024 +#endif + +void __attribute__ ((noinline, noclone)) +NAME(f2) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c) +{ + for (int i = 0; i < N; ++i) + { + a[i] = c[i * 2]; + b[i] = c[i * 2 + 1]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(f3) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d) +{ + for (int i = 0; i < N; ++i) + { + a[i] = d[i * 3]; + b[i] = d[i * 3 + 1]; + c[i] = d[i * 3 + 2]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(f4) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e) +{ + for (int i = 0; i < N; ++i) + { + a[i] = e[i * 4]; + b[i] = e[i * 4 + 1]; + c[i] = e[i * 4 + 2]; + d[i] = e[i * 4 + 3]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(f5) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f) +{ + for (int i = 0; i < N; ++i) + { + a[i] = f[i * 5]; + b[i] = f[i * 5 + 1]; + c[i] = f[i * 5 + 2]; + d[i] = f[i * 5 + 3]; + e[i] = f[i * 5 + 4]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(f6) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g) +{ + for (int i = 0; i < N; ++i) + { + a[i] = g[i * 6]; + b[i] = g[i * 6 + 1]; + c[i] = g[i * 6 + 2]; + d[i] = g[i * 6 + 3]; + e[i] = g[i * 6 + 4]; + f[i] = g[i * 6 + 5]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(f7) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h) +{ + for (int i = 0; i < N; ++i) + { + a[i] = h[i * 7]; + b[i] = h[i * 7 + 1]; + c[i] = h[i * 7 + 2]; + d[i] = h[i * 7 + 3]; + e[i] = h[i * 7 + 4]; + f[i] = h[i * 7 + 5]; + g[i] = h[i * 7 + 6]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(f8) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j) +{ + for (int i = 0; i < N; ++i) + { + a[i] = j[i * 8]; + b[i] = j[i * 8 + 1]; + c[i] = j[i * 8 + 2]; + d[i] = j[i * 8 + 3]; + e[i] = j[i * 8 + 4]; + f[i] = j[i * 8 + 5]; + g[i] = j[i * 8 + 6]; + h[i] = j[i * 8 + 7]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g2) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c) +{ + for (int i = 0; i < N; ++i) + { + c[i * 2] = a[i]; + c[i * 2 + 1] = b[i]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g3) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d) +{ + for (int i = 0; i < N; ++i) + { + d[i * 3] = a[i]; + d[i * 3 + 1] = b[i]; + d[i * 3 + 2] = c[i]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g4) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e) +{ + for (int i = 0; i < N; ++i) + { + e[i * 4] = a[i]; + e[i * 4 + 1] = b[i]; + e[i * 4 + 2] = c[i]; + e[i * 4 + 3] = d[i]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g5) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f) +{ + for (int i = 0; i < N; ++i) + { + f[i * 5] = a[i]; + f[i * 5 + 1] = b[i]; + f[i * 5 + 2] = c[i]; + f[i * 5 + 3] = d[i]; + f[i * 5 + 4] = e[i]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g6) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g) +{ + for (int i = 0; i < N; ++i) + { + g[i * 6] = a[i]; + g[i * 6 + 1] = b[i]; + g[i * 6 + 2] = c[i]; + g[i * 6 + 3] = d[i]; + g[i * 6 + 4] = e[i]; + g[i * 6 + 5] = f[i]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g7) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h) +{ + for (int i = 0; i < N; ++i) + { + h[i * 7] = a[i]; + h[i * 7 + 1] = b[i]; + h[i * 7 + 2] = c[i]; + h[i * 7 + 3] = d[i]; + h[i * 7 + 4] = e[i]; + h[i * 7 + 5] = f[i]; + h[i * 7 + 6] = g[i]; + } +} + +void __attribute__ ((noinline, noclone)) +NAME(g8) (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j) +{ + for (int i = 0; i < N; ++i) + { + j[i * 8] = a[i]; + j[i * 8 + 1] = b[i]; + j[i * 8 + 2] = c[i]; + j[i * 8 + 3] = d[i]; + j[i * 8 + 4] = e[i]; + j[i * 8 + 5] = f[i]; + j[i * 8 + 6] = g[i]; + j[i * 8 + 7] = h[i]; + } +} + +/* { dg-final { scan-assembler-times {vlseg2e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg3e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg4e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg5e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg6e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg7e8\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vlseg8e8\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg2e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg3e8\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg4e8\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg5e8\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg6e8\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg7e8\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg8e8\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*16,\s*e8,\s*m1,\s*t[au],\s*m[au]} 14 } } */ +/* { dg-final { scan-assembler-not {vsetvli} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c new file mode 100644 index 0000000000000..dc4d6512f231a --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-10.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE _Float16 +#define ITYPE int16_t +#include "struct_vect-6.c" + +/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c new file mode 100644 index 0000000000000..36ade63dd9e48 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-11.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE float +#define ITYPE int32_t +#include "struct_vect-6.c" + +/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c new file mode 100644 index 0000000000000..a2a93c432c648 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-12.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE double +#define ITYPE int64_t +#include "struct_vect-6.c" + +/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c new file mode 100644 index 0000000000000..4da1c4148bb6f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-13.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define N 2000 + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME (TYPE *restrict dest, TYPE *restrict src) \ + { \ + for (int i = 0; i < N; ++i) \ + dest[i] += src[i * 3]; \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i8, int8_t) \ + TEST_LOOP (NAME##_i16, uint16_t) \ + TEST_LOOP (NAME##_f32, float) \ + TEST_LOOP (NAME##_f64, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg3e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c new file mode 100644 index 0000000000000..f652a35bae450 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-14.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME (TYPE *restrict dest, TYPE *restrict src, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + dest[i] += src[i * 3]; \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i8, int8_t) \ + TEST_LOOP (NAME##_i16, uint16_t) \ + TEST_LOOP (NAME##_f32, float) \ + TEST_LOOP (NAME##_f64, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg3e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c new file mode 100644 index 0000000000000..29d32ab29dc28 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-15.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define N 2000 + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME (TYPE *restrict dest, TYPE *restrict src) \ + { \ + for (int i = 0; i < N; ++i) \ + dest[i] += src[i * 2]; \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i8, int8_t) \ + TEST_LOOP (NAME##_i16, uint16_t) \ + TEST_LOOP (NAME##_f32, float) \ + TEST_LOOP (NAME##_f64, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg2e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c new file mode 100644 index 0000000000000..15de93ec66f63 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-16.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME (TYPE *restrict dest, TYPE *restrict src, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + dest[i] += src[i * 2]; \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i8, int8_t) \ + TEST_LOOP (NAME##_i16, uint16_t) \ + TEST_LOOP (NAME##_f32, float) \ + TEST_LOOP (NAME##_f64, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg2e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c new file mode 100644 index 0000000000000..44eb0725a8e7d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-17.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define N 2000 + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME (TYPE *restrict dest, TYPE *restrict src) \ + { \ + for (int i = 0; i < N; ++i) \ + dest[i] += src[i * 4]; \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i8, int8_t) \ + TEST_LOOP (NAME##_i16, uint16_t) \ + TEST_LOOP (NAME##_f32, float) \ + TEST_LOOP (NAME##_f64, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg4e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c new file mode 100644 index 0000000000000..f6f559e4c2d21 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-18.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#define TEST_LOOP(NAME, TYPE) \ + void __attribute__ ((noinline, noclone)) \ + NAME (TYPE *restrict dest, TYPE *restrict src, int n) \ + { \ + for (int i = 0; i < n; ++i) \ + dest[i] += src[i * 4]; \ + } + +#define TEST(NAME) \ + TEST_LOOP (NAME##_i8, int8_t) \ + TEST_LOOP (NAME##_i16, uint16_t) \ + TEST_LOOP (NAME##_f32, float) \ + TEST_LOOP (NAME##_f64, double) + +TEST (test) + +/* { dg-final { scan-assembler-times {vlseg4e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c new file mode 100644 index 0000000000000..2a61a79c620be --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE uint16_t +#include "struct_vect-1.c" + +/* { dg-final { scan-assembler-times {vlseg2e16\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg3e16\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg4e16\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg5e16\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg6e16\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vlseg7e16\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vlseg8e16\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg2e16\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg3e16\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg4e16\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg5e16\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg6e16\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg7e16\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vsseg8e16\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*8,\s*e16,\s*m1,\s*t[au],\s*m[au]} 14 } } */ +/* { dg-final { scan-assembler-not {vsetvli} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c new file mode 100644 index 0000000000000..3d818dad10f93 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-3.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE uint32_t +#include "struct_vect-1.c" + +/* { dg-final { scan-assembler-times {vlseg2e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg5e32\.v} 6 } } */ +/* { dg-final { scan-assembler-times {vlseg6e32\.v} 6 } } */ +/* { dg-final { scan-assembler-times {vlseg7e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vlseg8e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg2e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg3e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg4e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg5e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg6e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg7e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg8e32\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*4,\s*e32,\s*m1,\s*t[au],\s*m[au]} 14 } } */ +/* { dg-final { scan-assembler-not {vsetvli} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c new file mode 100644 index 0000000000000..b5ad45e8f82c6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-4.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE uint64_t +#include "struct_vect-1.c" + +/* { dg-final { scan-assembler-times {vlseg2e64\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg3e64\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg4e64\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg5e64\.v} 7 } } */ +/* { dg-final { scan-assembler-times {vlseg6e64\.v} 7 } } */ +/* { dg-final { scan-assembler-times {vlseg7e64\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vlseg8e64\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg2e64\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg3e64\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg4e64\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg5e64\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg6e64\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg7e64\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg8e64\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*2,\s*e64,\s*m1,\s*t[au],\s*m[au]} 14 } } */ +/* { dg-final { scan-assembler-not {vsetvli} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c new file mode 100644 index 0000000000000..63b83dfab2caa --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-5.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE float +#include "struct_vect-1.c" + +/* { dg-final { scan-assembler-times {vlseg2e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vlseg5e32\.v} 6 } } */ +/* { dg-final { scan-assembler-times {vlseg6e32\.v} 6 } } */ +/* { dg-final { scan-assembler-times {vlseg7e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vlseg8e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg2e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg3e32\.v} 8 } } */ +/* { dg-final { scan-assembler-times {vsseg4e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg5e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg6e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg7e32\.v} 4 } } */ +/* { dg-final { scan-assembler-times {vsseg8e32\.v} 2 } } */ +/* { dg-final { scan-assembler-times {vsetivli\s+zero,\s*4,\s*e32,\s*m1,\s*t[au],\s*m[au]} 14 } } */ +/* { dg-final { scan-assembler-not {vsetvli} } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c new file mode 100644 index 0000000000000..2494744d8b490 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-6.c @@ -0,0 +1,225 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include + +#ifndef TYPE +#define TYPE uint8_t +#define ITYPE int8_t +#endif + +void __attribute__ ((noinline, noclone)) +f2 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = c[i * 2]; + b[i] = c[i * 2 + 1]; + } +} + +void __attribute__ ((noinline, noclone)) +f3 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = d[i * 3]; + b[i] = d[i * 3 + 1]; + c[i] = d[i * 3 + 2]; + } +} + +void __attribute__ ((noinline, noclone)) +f4 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = e[i * 4]; + b[i] = e[i * 4 + 1]; + c[i] = e[i * 4 + 2]; + d[i] = e[i * 4 + 3]; + } +} + +void __attribute__ ((noinline, noclone)) +f5 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = f[i * 5]; + b[i] = f[i * 5 + 1]; + c[i] = f[i * 5 + 2]; + d[i] = f[i * 5 + 3]; + e[i] = f[i * 5 + 4]; + } +} + +void __attribute__ ((noinline, noclone)) +f6 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = g[i * 6]; + b[i] = g[i * 6 + 1]; + c[i] = g[i * 6 + 2]; + d[i] = g[i * 6 + 3]; + e[i] = g[i * 6 + 4]; + f[i] = g[i * 6 + 5]; + } +} + +void __attribute__ ((noinline, noclone)) +f7 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = h[i * 7]; + b[i] = h[i * 7 + 1]; + c[i] = h[i * 7 + 2]; + d[i] = h[i * 7 + 3]; + e[i] = h[i * 7 + 4]; + f[i] = h[i * 7 + 5]; + g[i] = h[i * 7 + 6]; + } +} + +void __attribute__ ((noinline, noclone)) +f8 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + a[i] = j[i * 8]; + b[i] = j[i * 8 + 1]; + c[i] = j[i * 8 + 2]; + d[i] = j[i * 8 + 3]; + e[i] = j[i * 8 + 4]; + f[i] = j[i * 8 + 5]; + g[i] = j[i * 8 + 6]; + h[i] = j[i * 8 + 7]; + } +} + +void __attribute__ ((noinline, noclone)) +g2 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + c[i * 2] = a[i]; + c[i * 2 + 1] = b[i]; + } +} + +void __attribute__ ((noinline, noclone)) +g3 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + d[i * 3] = a[i]; + d[i * 3 + 1] = b[i]; + d[i * 3 + 2] = c[i]; + } +} + +void __attribute__ ((noinline, noclone)) +g4 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + e[i * 4] = a[i]; + e[i * 4 + 1] = b[i]; + e[i * 4 + 2] = c[i]; + e[i * 4 + 3] = d[i]; + } +} + +void __attribute__ ((noinline, noclone)) +g5 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + f[i * 5] = a[i]; + f[i * 5 + 1] = b[i]; + f[i * 5 + 2] = c[i]; + f[i * 5 + 3] = d[i]; + f[i * 5 + 4] = e[i]; + } +} + +void __attribute__ ((noinline, noclone)) +g6 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + g[i * 6] = a[i]; + g[i * 6 + 1] = b[i]; + g[i * 6 + 2] = c[i]; + g[i * 6 + 3] = d[i]; + g[i * 6 + 4] = e[i]; + g[i * 6 + 5] = f[i]; + } +} + +void __attribute__ ((noinline, noclone)) +g7 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + h[i * 7] = a[i]; + h[i * 7 + 1] = b[i]; + h[i * 7 + 2] = c[i]; + h[i * 7 + 3] = d[i]; + h[i * 7 + 4] = e[i]; + h[i * 7 + 5] = f[i]; + h[i * 7 + 6] = g[i]; + } +} + +void __attribute__ ((noinline, noclone)) +g8 (TYPE *__restrict a, TYPE *__restrict b, TYPE *__restrict c, + TYPE *__restrict d, TYPE *__restrict e, TYPE *__restrict f, + TYPE *__restrict g, TYPE *__restrict h, TYPE *__restrict j, ITYPE n) +{ + for (ITYPE i = 0; i < n; ++i) + { + j[i * 8] = a[i]; + j[i * 8 + 1] = b[i]; + j[i * 8 + 2] = c[i]; + j[i * 8 + 3] = d[i]; + j[i * 8 + 4] = e[i]; + j[i * 8 + 5] = f[i]; + j[i * 8 + 6] = g[i]; + j[i * 8 + 7] = h[i]; + } +} + +/* { dg-final { scan-assembler-times {vlseg2e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e8\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+,\s*e8,\s*m1,\s*t[au],\s*m[au]} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c new file mode 100644 index 0000000000000..dd01769d98dd6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-7.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE uint16_t +#define ITYPE int16_t +#include "struct_vect-6.c" + +/* { dg-final { scan-assembler-times {vlseg2e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e16\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c new file mode 100644 index 0000000000000..bedf17a6ee070 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-8.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv_zvfh -mabi=ilp32d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE uint32_t +#define ITYPE int32_t +#include "struct_vect-6.c" + +/* { dg-final { scan-assembler-times {vlseg2e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e32\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c new file mode 100644 index 0000000000000..8b608224a4fd8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect-9.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv_zvfh -mabi=lp64d --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE uint64_t +#define ITYPE int64_t +#include "struct_vect-6.c" + +/* { dg-final { scan-assembler-times {vlseg2e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg3e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg4e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg5e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg6e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg7e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vlseg8e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg2e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg3e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg4e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg5e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg6e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg7e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsseg8e64\.v} 1 } } */ +/* { dg-final { scan-assembler-times {vsetvli\s+[a-x0-9]+,\s*[a-x0-9]+} 14 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c new file mode 100644 index 0000000000000..4807bebdd7e26 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-1.c @@ -0,0 +1,139 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#include "struct_vect-1.c" + +TYPE a[N], b[N], c[N], d[N], a2[N], b2[N], c2[N], d2[N], e[N * 8]; + +void __attribute__ ((noinline, noclone)) +init_array (TYPE *array, int n, TYPE base, TYPE step) +{ + for (int i = 0; i < n; ++i) + array[i] = base + step * i; +} + +void __attribute__ ((noinline, noclone)) +check_array (TYPE *array, int n, TYPE base, TYPE step) +{ + for (int i = 0; i < n; ++i) + if (array[i] != (TYPE) (base + step * i)) + __builtin_abort (); +} + +int __attribute__ ((optimize (1))) +main (void) +{ + init_array (e, 2 * N, 11, 5); + f2 (a, b, e); + check_array (a, N, 11, 10); + check_array (b, N, 16, 10); + + init_array (e, 3 * N, 7, 6); + f3 (a, b, c, e); + check_array (a, N, 7, 18); + check_array (b, N, 13, 18); + check_array (c, N, 19, 18); + + init_array (e, 4 * N, 4, 11); + f4 (a, b, c, d, e); + check_array (a, N, 4, 44); + check_array (b, N, 15, 44); + check_array (c, N, 26, 44); + check_array (d, N, 37, 44); + + init_array (e, 5 * N, 3, 9); + f5 (a, b, c, d, a2, e); + check_array (a, N, 3, 45); + check_array (b, N, 12, 45); + check_array (c, N, 21, 45); + check_array (d, N, 30, 45); + check_array (a2, N, 39, 45); + + init_array (e, 6 * N, 5, 5); + f6 (a, b, c, d, a2, b2, e); + check_array (a, N, 5, 30); + check_array (b, N, 10, 30); + check_array (c, N, 15, 30); + check_array (d, N, 20, 30); + check_array (a2, N, 25, 30); + check_array (b2, N, 30, 30); + + init_array (e, 7 * N, 7, 3); + f7 (a, b, c, d, a2, b2, c2, e); + check_array (a, N, 7, 21); + check_array (b, N, 10, 21); + check_array (c, N, 13, 21); + check_array (d, N, 16, 21); + check_array (a2, N, 19, 21); + check_array (b2, N, 22, 21); + check_array (c2, N, 25, 21); + + init_array (e, 8 * N, 5, 8); + f8 (a, b, c, d, a2, b2, c2, d2, e); + check_array (a, N, 5, 64); + check_array (b, N, 13, 64); + check_array (c, N, 21, 64); + check_array (d, N, 29, 64); + check_array (a2, N, 37, 64); + check_array (b2, N, 45, 64); + check_array (c2, N, 53, 64); + check_array (d2, N, 61, 64); + + init_array (a, N, 2, 8); + init_array (b, N, 6, 8); + g2 (a, b, e); + check_array (e, 2 * N, 2, 4); + + init_array (a, N, 4, 15); + init_array (b, N, 9, 15); + init_array (c, N, 14, 15); + g3 (a, b, c, e); + check_array (e, 3 * N, 4, 5); + + init_array (a, N, 14, 36); + init_array (b, N, 23, 36); + init_array (c, N, 32, 36); + init_array (d, N, 41, 36); + g4 (a, b, c, d, e); + check_array (e, 4 * N, 14, 9); + + init_array (a, N, 3, 45); + init_array (b, N, 12, 45); + init_array (c, N, 21, 45); + init_array (d, N, 30, 45); + init_array (a2, N, 39, 45); + g5 (a, b, c, d, a2, e); + check_array (e, 5 * N, 3, 9); + + init_array (a, N, 5, 30); + init_array (b, N, 10, 30); + init_array (c, N, 15, 30); + init_array (d, N, 20, 30); + init_array (a2, N, 25, 30); + init_array (b2, N, 30, 30); + g6 (a, b, c, d, a2, b2, e); + check_array (e, 6 * N, 5, 5); + + init_array (a, N, 7, 21); + init_array (b, N, 10, 21); + init_array (c, N, 13, 21); + init_array (d, N, 16, 21); + init_array (a2, N, 19, 21); + init_array (b2, N, 22, 21); + init_array (c2, N, 25, 21); + g7 (a, b, c, d, a2, b2, c2, e); + check_array (e, 7 * N, 7, 3); + + init_array (a, N, 5, 64); + init_array (b, N, 13, 64); + init_array (c, N, 21, 64); + init_array (d, N, 29, 64); + init_array (a2, N, 37, 64); + init_array (b2, N, 45, 64); + init_array (c2, N, 53, 64); + init_array (d2, N, 61, 64); + g8 (a, b, c, d, a2, b2, c2, d2, e); + check_array (e, 8 * N, 5, 8); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c new file mode 100644 index 0000000000000..afebde162d7fe --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-10.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector && riscv_zvfh_hw } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE _Float16 +#define ITYPE int16_t +#include "struct_vect_run-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c new file mode 100644 index 0000000000000..8d311b45eb4ce --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-11.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE float +#define ITYPE int32_t +#include "struct_vect_run-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c new file mode 100644 index 0000000000000..763aa9e6f582f --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-12.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE double +#define ITYPE int64_t +#include "struct_vect_run-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c new file mode 100644 index 0000000000000..e1824e912bf64 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-13.c @@ -0,0 +1,36 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-13.c" + +#undef TEST_LOOP +#define TEST_LOOP(NAME, TYPE) \ + { \ + TYPE out[N]; \ + TYPE in[N * 3]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 3; ++i) \ + { \ + in[i] = i * 9 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + NAME (out, in); \ + for (int i = 0; i < N; ++i) \ + { \ + TYPE expected = i * 7 / 2 + in[i * 3]; \ + if (out[i] != expected) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c new file mode 100644 index 0000000000000..6b23023a918f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-14.c @@ -0,0 +1,45 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-14.c" + +#define N 1000 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, TYPE) \ + { \ + TYPE out[N]; \ + TYPE in[N * 3]; \ + int counts[] = { 0, 1, N - 1 }; \ + for (int j = 0; j < 3; ++j) \ + { \ + int count = counts[j]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 3; ++i) \ + { \ + in[i] = i * 9 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + NAME (out, in, count); \ + for (int i = 0; i < N; ++i) \ + { \ + TYPE expected = i * 7 / 2; \ + if (i < count) \ + expected += in[i * 3]; \ + if (out[i] != expected) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c new file mode 100644 index 0000000000000..92eadd6fd459c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-15.c @@ -0,0 +1,36 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-15.c" + +#undef TEST_LOOP +#define TEST_LOOP(NAME, TYPE) \ + { \ + TYPE out[N]; \ + TYPE in[N * 2]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 2; ++i) \ + { \ + in[i] = i * 9 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + NAME (out, in); \ + for (int i = 0; i < N; ++i) \ + { \ + TYPE expected = i * 7 / 2 + in[i * 2]; \ + if (out[i] != expected) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c new file mode 100644 index 0000000000000..f43e06c46fdc3 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-16.c @@ -0,0 +1,45 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-16.c" + +#define N 1000 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, TYPE) \ + { \ + TYPE out[N]; \ + TYPE in[N * 2]; \ + int counts[] = { 0, 1, N - 1 }; \ + for (int j = 0; j < 3; ++j) \ + { \ + int count = counts[j]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 2; ++i) \ + { \ + in[i] = i * 9 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + NAME (out, in, count); \ + for (int i = 0; i < N; ++i) \ + { \ + TYPE expected = i * 7 / 2; \ + if (i < count) \ + expected += in[i * 2]; \ + if (out[i] != expected) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c new file mode 100644 index 0000000000000..b0bafb1cece36 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-17.c @@ -0,0 +1,36 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-17.c" + +#undef TEST_LOOP +#define TEST_LOOP(NAME, TYPE) \ + { \ + TYPE out[N]; \ + TYPE in[N * 4]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 4; ++i) \ + { \ + in[i] = i * 9 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + NAME (out, in); \ + for (int i = 0; i < N; ++i) \ + { \ + TYPE expected = i * 7 / 2 + in[i * 4]; \ + if (out[i] != expected) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c new file mode 100644 index 0000000000000..169974cc0a9d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-18.c @@ -0,0 +1,45 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "--param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-18.c" + +#define N 1000 + +#undef TEST_LOOP +#define TEST_LOOP(NAME, TYPE) \ + { \ + TYPE out[N]; \ + TYPE in[N * 4]; \ + int counts[] = { 0, 1, N - 1 }; \ + for (int j = 0; j < 3; ++j) \ + { \ + int count = counts[j]; \ + for (int i = 0; i < N; ++i) \ + { \ + out[i] = i * 7 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + for (int i = 0; i < N * 4; ++i) \ + { \ + in[i] = i * 9 / 2; \ + asm volatile ("" ::: "memory"); \ + } \ + NAME (out, in, count); \ + for (int i = 0; i < N; ++i) \ + { \ + TYPE expected = i * 7 / 2; \ + if (i < count) \ + expected += in[i * 4]; \ + if (out[i] != expected) \ + __builtin_abort (); \ + asm volatile ("" ::: "memory"); \ + } \ + } \ + } + +int __attribute__ ((optimize (1))) +main (void) +{ + TEST (test); + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c new file mode 100644 index 0000000000000..ab26245241ca8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-2.c @@ -0,0 +1,5 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE uint16_t +#include "struct_vect_run-1.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c new file mode 100644 index 0000000000000..a2b2e8183276c --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-3.c @@ -0,0 +1,5 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE uint32_t +#include "struct_vect_run-1.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c new file mode 100644 index 0000000000000..4e4ddb3b39fe8 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-4.c @@ -0,0 +1,5 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE uint64_t +#include "struct_vect_run-1.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c new file mode 100644 index 0000000000000..2fa48f1ce3ef5 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-5.c @@ -0,0 +1,5 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=fixed-vlmax -funroll-all-loops -fno-schedule-insns -fno-schedule-insns2" } */ + +#define TYPE float +#include "struct_vect_run-1.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c new file mode 100644 index 0000000000000..7146042c4040e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-6.c @@ -0,0 +1,141 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#include "struct_vect-6.c" + +#define N 93 + +TYPE a[N], b[N], c[N], d[N], a2[N], b2[N], c2[N], d2[N], e[N * 8]; + +void __attribute__ ((noinline, noclone)) +init_array (TYPE *array, int n, TYPE base, TYPE step) +{ + for (int i = 0; i < n; ++i) + array[i] = base + step * i; +} + +void __attribute__ ((noinline, noclone)) +check_array (TYPE *array, int n, TYPE base, TYPE step) +{ + for (int i = 0; i < n; ++i) + if (array[i] != (TYPE) (base + step * i)) + __builtin_abort (); +} + +int __attribute__ ((optimize (1))) +main (void) +{ + init_array (e, 2 * N, 11, 5); + f2 (a, b, e, N); + check_array (a, N, 11, 10); + check_array (b, N, 16, 10); + + init_array (e, 3 * N, 7, 6); + f3 (a, b, c, e, N); + check_array (a, N, 7, 18); + check_array (b, N, 13, 18); + check_array (c, N, 19, 18); + + init_array (e, 4 * N, 4, 11); + f4 (a, b, c, d, e, N); + check_array (a, N, 4, 44); + check_array (b, N, 15, 44); + check_array (c, N, 26, 44); + check_array (d, N, 37, 44); + + init_array (e, 5 * N, 3, 9); + f5 (a, b, c, d, a2, e, N); + check_array (a, N, 3, 45); + check_array (b, N, 12, 45); + check_array (c, N, 21, 45); + check_array (d, N, 30, 45); + check_array (a2, N, 39, 45); + + init_array (e, 6 * N, 5, 5); + f6 (a, b, c, d, a2, b2, e, N); + check_array (a, N, 5, 30); + check_array (b, N, 10, 30); + check_array (c, N, 15, 30); + check_array (d, N, 20, 30); + check_array (a2, N, 25, 30); + check_array (b2, N, 30, 30); + + init_array (e, 7 * N, 7, 3); + f7 (a, b, c, d, a2, b2, c2, e, N); + check_array (a, N, 7, 21); + check_array (b, N, 10, 21); + check_array (c, N, 13, 21); + check_array (d, N, 16, 21); + check_array (a2, N, 19, 21); + check_array (b2, N, 22, 21); + check_array (c2, N, 25, 21); + + init_array (e, 8 * N, 5, 8); + f8 (a, b, c, d, a2, b2, c2, d2, e, N); + check_array (a, N, 5, 64); + check_array (b, N, 13, 64); + check_array (c, N, 21, 64); + check_array (d, N, 29, 64); + check_array (a2, N, 37, 64); + check_array (b2, N, 45, 64); + check_array (c2, N, 53, 64); + check_array (d2, N, 61, 64); + + init_array (a, N, 2, 8); + init_array (b, N, 6, 8); + g2 (a, b, e, N); + check_array (e, 2 * N, 2, 4); + + init_array (a, N, 4, 15); + init_array (b, N, 9, 15); + init_array (c, N, 14, 15); + g3 (a, b, c, e, N); + check_array (e, 3 * N, 4, 5); + + init_array (a, N, 14, 36); + init_array (b, N, 23, 36); + init_array (c, N, 32, 36); + init_array (d, N, 41, 36); + g4 (a, b, c, d, e, N); + check_array (e, 4 * N, 14, 9); + + init_array (a, N, 3, 45); + init_array (b, N, 12, 45); + init_array (c, N, 21, 45); + init_array (d, N, 30, 45); + init_array (a2, N, 39, 45); + g5 (a, b, c, d, a2, e, N); + check_array (e, 5 * N, 3, 9); + + init_array (a, N, 5, 30); + init_array (b, N, 10, 30); + init_array (c, N, 15, 30); + init_array (d, N, 20, 30); + init_array (a2, N, 25, 30); + init_array (b2, N, 30, 30); + g6 (a, b, c, d, a2, b2, e, N); + check_array (e, 6 * N, 5, 5); + + init_array (a, N, 7, 21); + init_array (b, N, 10, 21); + init_array (c, N, 13, 21); + init_array (d, N, 16, 21); + init_array (a2, N, 19, 21); + init_array (b2, N, 22, 21); + init_array (c2, N, 25, 21); + g7 (a, b, c, d, a2, b2, c2, e, N); + check_array (e, 7 * N, 7, 3); + + init_array (a, N, 5, 64); + init_array (b, N, 13, 64); + init_array (c, N, 21, 64); + init_array (d, N, 29, 64); + init_array (a2, N, 37, 64); + init_array (b2, N, 45, 64); + init_array (c2, N, 53, 64); + init_array (d2, N, 61, 64); + g8 (a, b, c, d, a2, b2, c2, d2, e, N); + check_array (e, 8 * N, 5, 8); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c new file mode 100644 index 0000000000000..73e74493bd2cf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-7.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE uint16_t +#define ITYPE int16_t +#include "struct_vect_run-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c new file mode 100644 index 0000000000000..383a6c6862154 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-8.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE uint32_t +#define ITYPE int32_t +#include "struct_vect_run-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c new file mode 100644 index 0000000000000..79b5df73559c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/struct/struct_vect_run-9.c @@ -0,0 +1,6 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 --param=riscv-autovec-preference=scalable -fno-vect-cost-model" } */ + +#define TYPE uint64_t +#define ITYPE int64_t +#include "struct_vect_run-6.c" diff --git a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp index 1bc53cef891b9..ff76e17d0e6c5 100644 --- a/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp +++ b/gcc/testsuite/gcc.target/riscv/rvv/rvv.exp @@ -50,6 +50,8 @@ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/*.\[cS\]]] \ "-O3 -ftree-vectorize" $CFLAGS dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/vls/*.\[cS\]]] \ "-O3 -ftree-vectorize --param riscv-autovec-preference=scalable" $CFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/autovec/struct/*.\[cS\]]] \ + "" "-O3 -ftree-vectorize" set AUTOVEC_TEST_OPTS [list \ {-ftree-vectorize -O3 --param riscv-autovec-lmul=m1} \