* [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask @ 2023-06-28 1:59 Juzhe-Zhong 2023-06-28 3:14 ` juzhe.zhong 0 siblings, 1 reply; 11+ messages in thread From: Juzhe-Zhong @ 2023-06-28 1:59 UTC (permalink / raw) To: gcc-patches Cc: kito.cheng, kito.cheng, palmer, palmer, jeffreyalaw, rdapp.gcc, Juzhe-Zhong This bug blocks the following patches. GCC doesn't know RVV is using compact mask model. Consider this following case: #define N 16 int main () { int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; int8_t out[N] = {0}; for (int8_t i = 0; i < N; ++i) if (mask[i]) out[i] = i; for (int8_t i = 0; i < N; ++i) { if (mask[i]) assert (out[i] == i); else assert (out[i] == 0); } } Before this patch, the pre-calculated mask in constant memory pool: .LC1: .byte 68 ====> 0b01000100 This is incorrect, such case failed in execution. After this patch: .LC1: .byte 10 ====> 0b1010 Pass on exection. gcc/ChangeLog: * config/riscv/riscv-v.cc (rvv_builder::get_compact_mask): New function. (expand_const_vector): Ditto. * config/riscv/riscv.cc (riscv_const_insns): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c: New test. --- gcc/config/riscv/riscv-v.cc | 64 +++++++++++++++++-- gcc/config/riscv/riscv.cc | 6 ++ .../riscv/rvv/autovec/vls-vlmax/bitmask-1.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-2.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-3.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-4.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-5.c | 25 ++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-6.c | 27 ++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-7.c | 30 +++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-8.c | 30 +++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-9.c | 30 +++++++++ 11 files changed, 299 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index adb8d7d36a5..5da0dc5e998 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -291,6 +291,7 @@ public: bool single_step_npatterns_p () const; bool npatterns_all_equal_p () const; + rtx get_compact_mask () const; machine_mode new_mode () const { return m_new_mode; } scalar_mode inner_mode () const { return m_inner_mode; } @@ -505,6 +506,47 @@ rvv_builder::npatterns_all_equal_p () const return true; } +/* Generate the compact mask. + + E.g: mask = { 0, -1 }, mode = VNx2BI, bitsize = 128bits. + + GCC by default will generate the mask = 0b00000001xxxxx. + + However, it's not expected mask for RVV since RVV + prefers the compact mask = 0b10xxxxx. +*/ +rtx +rvv_builder::get_compact_mask () const +{ + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. + Otherwise, the minimum LMUL = 1/8. */ + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; + unsigned min_container_size + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); + machine_mode container_mode + = get_vector_mode (QImode, container_size).require (); + + unsigned nunits = GET_MODE_NUNITS (container_mode).to_constant (); + rtvec v = rtvec_alloc (nunits); + for (unsigned i = 0; i < nunits; i++) + RTVEC_ELT (v, i) = const0_rtx; + + unsigned char b = 0; + for (unsigned i = 0; i < npatterns (); i++) + { + if (INTVAL (elt (i))) + b = b | (1 << (i % 8)); + + if ((i > 0 && (i % 8) == 7) || (i == (npatterns () - 1))) + { + RTVEC_ELT (v, ((i + 7) / 8) - 1) = gen_int_mode (b, QImode); + b = 0; + } + } + return gen_rtx_CONST_VECTOR (container_mode, v); +} + static unsigned get_sew (machine_mode mode) { @@ -1141,11 +1183,23 @@ expand_const_vector (rtx target, rtx src) if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) { rtx elt; - gcc_assert ( - const_vec_duplicate_p (src, &elt) - && (rtx_equal_p (elt, const0_rtx) || rtx_equal_p (elt, const1_rtx))); - rtx ops[] = {target, src}; - emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); + unsigned int nelts; + if (const_vec_duplicate_p (src, &elt)) + { + rtx ops[] = {target, src}; + emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); + } + else if (GET_MODE_NUNITS (mode).is_constant (&nelts)) + { + rvv_builder builder (mode, nelts, 1); + for (unsigned int i = 0; i < nelts; i++) + builder.quick_push (CONST_VECTOR_ELT (src, i)); + rtx mask = builder.get_compact_mask (); + rtx mem = validize_mem (force_const_mem (GET_MODE (mask), mask)); + emit_move_insn (target, gen_rtx_MEM (mode, XEXP (mem, 0))); + } + else + gcc_unreachable (); return; } diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 280aa0b33b9..86c83f0906d 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1323,6 +1323,12 @@ riscv_const_insns (rtx x) return 1 + 4; /*vmv.v.x + memory access. */ } } + + /* GCC doesn't known RVV is using compact model of mask, + we should by default handle mask in mov<mode> pattern. */ + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL) + /* TODO: We can adjust it according real cost model of vlm.v. */ + return 1; } /* TODO: We may support more const vector in the future. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c new file mode 100644 index 00000000000..81229fd62b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int64_t out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c new file mode 100644 index 00000000000..a23e47171bc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c new file mode 100644 index 00000000000..6ea8fdd89c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int16_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int16_t out[N] = {0}; + for (int16_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int16_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c new file mode 100644 index 00000000000..2d97c26abfd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int8_t out[N] = {0}; + for (int8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c new file mode 100644 index 00000000000..b89b70e99a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c @@ -0,0 +1,25 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 32 + +int +main () +{ + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int8_t out[N] = {0}; + for (int8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c new file mode 100644 index 00000000000..ac8d91e793b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c @@ -0,0 +1,27 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 64 + +int +main () +{ + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int8_t out[N] = {0}; + for (int8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c new file mode 100644 index 00000000000..f538db23b1d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 128 + +int +main () +{ + uint8_t mask[N] + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + uint8_t out[N] = {0}; + for (uint8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (uint8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c new file mode 100644 index 00000000000..5abb34c1686 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 128 + +int +main () +{ + int mask[N] + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c new file mode 100644 index 00000000000..6fdaa516534 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 128 + +int +main () +{ + int64_t mask[N] + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int64_t out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} -- 2.36.1 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 1:59 [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask Juzhe-Zhong @ 2023-06-28 3:14 ` juzhe.zhong 2023-06-28 3:16 ` Kito Cheng 0 siblings, 1 reply; 11+ messages in thread From: juzhe.zhong @ 2023-06-28 3:14 UTC (permalink / raw) To: 钟居哲, gcc-patches Cc: kito.cheng, Kito.cheng, palmer, palmer, jeffreyalaw, Robin Dapp [-- Attachment #1: Type: text/plain, Size: 15975 bytes --] This patch is the critical patch for following patches since it is a bug which I already address in rvv-next. juzhe.zhong@rivai.ai From: Juzhe-Zhong Date: 2023-06-28 09:59 To: gcc-patches CC: kito.cheng; kito.cheng; palmer; palmer; jeffreyalaw; rdapp.gcc; Juzhe-Zhong Subject: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask This bug blocks the following patches. GCC doesn't know RVV is using compact mask model. Consider this following case: #define N 16 int main () { int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; int8_t out[N] = {0}; for (int8_t i = 0; i < N; ++i) if (mask[i]) out[i] = i; for (int8_t i = 0; i < N; ++i) { if (mask[i]) assert (out[i] == i); else assert (out[i] == 0); } } Before this patch, the pre-calculated mask in constant memory pool: .LC1: .byte 68 ====> 0b01000100 This is incorrect, such case failed in execution. After this patch: .LC1: .byte 10 ====> 0b1010 Pass on exection. gcc/ChangeLog: * config/riscv/riscv-v.cc (rvv_builder::get_compact_mask): New function. (expand_const_vector): Ditto. * config/riscv/riscv.cc (riscv_const_insns): Ditto. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c: New test. * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c: New test. --- gcc/config/riscv/riscv-v.cc | 64 +++++++++++++++++-- gcc/config/riscv/riscv.cc | 6 ++ .../riscv/rvv/autovec/vls-vlmax/bitmask-1.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-2.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-3.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-4.c | 23 +++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-5.c | 25 ++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-6.c | 27 ++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-7.c | 30 +++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-8.c | 30 +++++++++ .../riscv/rvv/autovec/vls-vlmax/bitmask-9.c | 30 +++++++++ 11 files changed, 299 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc index adb8d7d36a5..5da0dc5e998 100644 --- a/gcc/config/riscv/riscv-v.cc +++ b/gcc/config/riscv/riscv-v.cc @@ -291,6 +291,7 @@ public: bool single_step_npatterns_p () const; bool npatterns_all_equal_p () const; + rtx get_compact_mask () const; machine_mode new_mode () const { return m_new_mode; } scalar_mode inner_mode () const { return m_inner_mode; } @@ -505,6 +506,47 @@ rvv_builder::npatterns_all_equal_p () const return true; } +/* Generate the compact mask. + + E.g: mask = { 0, -1 }, mode = VNx2BI, bitsize = 128bits. + + GCC by default will generate the mask = 0b00000001xxxxx. + + However, it's not expected mask for RVV since RVV + prefers the compact mask = 0b10xxxxx. +*/ +rtx +rvv_builder::get_compact_mask () const +{ + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. + Otherwise, the minimum LMUL = 1/8. */ + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; + unsigned min_container_size + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); + machine_mode container_mode + = get_vector_mode (QImode, container_size).require (); + + unsigned nunits = GET_MODE_NUNITS (container_mode).to_constant (); + rtvec v = rtvec_alloc (nunits); + for (unsigned i = 0; i < nunits; i++) + RTVEC_ELT (v, i) = const0_rtx; + + unsigned char b = 0; + for (unsigned i = 0; i < npatterns (); i++) + { + if (INTVAL (elt (i))) + b = b | (1 << (i % 8)); + + if ((i > 0 && (i % 8) == 7) || (i == (npatterns () - 1))) + { + RTVEC_ELT (v, ((i + 7) / 8) - 1) = gen_int_mode (b, QImode); + b = 0; + } + } + return gen_rtx_CONST_VECTOR (container_mode, v); +} + static unsigned get_sew (machine_mode mode) { @@ -1141,11 +1183,23 @@ expand_const_vector (rtx target, rtx src) if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) { rtx elt; - gcc_assert ( - const_vec_duplicate_p (src, &elt) - && (rtx_equal_p (elt, const0_rtx) || rtx_equal_p (elt, const1_rtx))); - rtx ops[] = {target, src}; - emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); + unsigned int nelts; + if (const_vec_duplicate_p (src, &elt)) + { + rtx ops[] = {target, src}; + emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); + } + else if (GET_MODE_NUNITS (mode).is_constant (&nelts)) + { + rvv_builder builder (mode, nelts, 1); + for (unsigned int i = 0; i < nelts; i++) + builder.quick_push (CONST_VECTOR_ELT (src, i)); + rtx mask = builder.get_compact_mask (); + rtx mem = validize_mem (force_const_mem (GET_MODE (mask), mask)); + emit_move_insn (target, gen_rtx_MEM (mode, XEXP (mem, 0))); + } + else + gcc_unreachable (); return; } diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 280aa0b33b9..86c83f0906d 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1323,6 +1323,12 @@ riscv_const_insns (rtx x) return 1 + 4; /*vmv.v.x + memory access. */ } } + + /* GCC doesn't known RVV is using compact model of mask, + we should by default handle mask in mov<mode> pattern. */ + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL) + /* TODO: We can adjust it according real cost model of vlm.v. */ + return 1; } /* TODO: We may support more const vector in the future. */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c new file mode 100644 index 00000000000..81229fd62b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int64_t out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c new file mode 100644 index 00000000000..a23e47171bc --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c new file mode 100644 index 00000000000..6ea8fdd89c0 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int16_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int16_t out[N] = {0}; + for (int16_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int16_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c new file mode 100644 index 00000000000..2d97c26abfd --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c @@ -0,0 +1,23 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> +#define N 16 + +int +main () +{ + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int8_t out[N] = {0}; + for (int8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c new file mode 100644 index 00000000000..b89b70e99a6 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c @@ -0,0 +1,25 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 32 + +int +main () +{ + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int8_t out[N] = {0}; + for (int8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c new file mode 100644 index 00000000000..ac8d91e793b --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c @@ -0,0 +1,27 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 64 + +int +main () +{ + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int8_t out[N] = {0}; + for (int8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c new file mode 100644 index 00000000000..f538db23b1d --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 128 + +int +main () +{ + uint8_t mask[N] + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + uint8_t out[N] = {0}; + for (uint8_t i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (uint8_t i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c new file mode 100644 index 00000000000..5abb34c1686 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 128 + +int +main () +{ + int mask[N] + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c new file mode 100644 index 00000000000..6fdaa516534 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ + +#include <stdint-gcc.h> +#include <assert.h> + +#define N 128 + +int +main () +{ + int64_t mask[N] + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; + int64_t out[N] = {0}; + for (int i = 0; i < N; ++i) + if (mask[i]) + out[i] = i; + for (int i = 0; i < N; ++i) + { + if (mask[i]) + assert (out[i] == i); + else + assert (out[i] == 0); + } +} -- 2.36.1 ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 3:14 ` juzhe.zhong @ 2023-06-28 3:16 ` Kito Cheng 2023-06-28 3:19 ` juzhe.zhong ` (2 more replies) 0 siblings, 3 replies; 11+ messages in thread From: Kito Cheng @ 2023-06-28 3:16 UTC (permalink / raw) To: juzhe.zhong Cc: gcc-patches, kito.cheng, palmer, palmer, jeffreyalaw, Robin Dapp Do you mind giving some comments about what the difference between the two versions? On Wed, Jun 28, 2023 at 11:14 AM juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> wrote: > > This patch is the critical patch for following patches since it is a bug which I already address in rvv-next. > > ________________________________ > juzhe.zhong@rivai.ai > > > From: Juzhe-Zhong > Date: 2023-06-28 09:59 > To: gcc-patches > CC: kito.cheng; kito.cheng; palmer; palmer; jeffreyalaw; rdapp.gcc; Juzhe-Zhong > Subject: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask > This bug blocks the following patches. > > GCC doesn't know RVV is using compact mask model. > Consider this following case: > > #define N 16 > > int > main () > { > int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > int8_t out[N] = {0}; > for (int8_t i = 0; i < N; ++i) > if (mask[i]) > out[i] = i; > for (int8_t i = 0; i < N; ++i) > { > if (mask[i]) > assert (out[i] == i); > else > assert (out[i] == 0); > } > } > > Before this patch, the pre-calculated mask in constant memory pool: > .LC1: > .byte 68 ====> 0b01000100 > > This is incorrect, such case failed in execution. > > After this patch: > .LC1: > .byte 10 ====> 0b1010 > > Pass on exection. > > gcc/ChangeLog: > > * config/riscv/riscv-v.cc (rvv_builder::get_compact_mask): New function. > (expand_const_vector): Ditto. > * config/riscv/riscv.cc (riscv_const_insns): Ditto. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c: New test. > > --- > gcc/config/riscv/riscv-v.cc | 64 +++++++++++++++++-- > gcc/config/riscv/riscv.cc | 6 ++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-1.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-2.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-3.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-4.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-5.c | 25 ++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-6.c | 27 ++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-7.c | 30 +++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-8.c | 30 +++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-9.c | 30 +++++++++ > 11 files changed, 299 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > > diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc > index adb8d7d36a5..5da0dc5e998 100644 > --- a/gcc/config/riscv/riscv-v.cc > +++ b/gcc/config/riscv/riscv-v.cc > @@ -291,6 +291,7 @@ public: > bool single_step_npatterns_p () const; > bool npatterns_all_equal_p () const; > + rtx get_compact_mask () const; > machine_mode new_mode () const { return m_new_mode; } > scalar_mode inner_mode () const { return m_inner_mode; } > @@ -505,6 +506,47 @@ rvv_builder::npatterns_all_equal_p () const > return true; > } > +/* Generate the compact mask. > + > + E.g: mask = { 0, -1 }, mode = VNx2BI, bitsize = 128bits. > + > + GCC by default will generate the mask = 0b00000001xxxxx. > + > + However, it's not expected mask for RVV since RVV > + prefers the compact mask = 0b10xxxxx. > +*/ > +rtx > +rvv_builder::get_compact_mask () const > +{ > + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. > + Otherwise, the minimum LMUL = 1/8. */ > + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; > + unsigned min_container_size > + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; > + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); > + machine_mode container_mode > + = get_vector_mode (QImode, container_size).require (); > + > + unsigned nunits = GET_MODE_NUNITS (container_mode).to_constant (); > + rtvec v = rtvec_alloc (nunits); > + for (unsigned i = 0; i < nunits; i++) > + RTVEC_ELT (v, i) = const0_rtx; > + > + unsigned char b = 0; > + for (unsigned i = 0; i < npatterns (); i++) > + { > + if (INTVAL (elt (i))) > + b = b | (1 << (i % 8)); > + > + if ((i > 0 && (i % 8) == 7) || (i == (npatterns () - 1))) > + { > + RTVEC_ELT (v, ((i + 7) / 8) - 1) = gen_int_mode (b, QImode); > + b = 0; > + } > + } > + return gen_rtx_CONST_VECTOR (container_mode, v); > +} > + > static unsigned > get_sew (machine_mode mode) > { > @@ -1141,11 +1183,23 @@ expand_const_vector (rtx target, rtx src) > if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) > { > rtx elt; > - gcc_assert ( > - const_vec_duplicate_p (src, &elt) > - && (rtx_equal_p (elt, const0_rtx) || rtx_equal_p (elt, const1_rtx))); > - rtx ops[] = {target, src}; > - emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); > + unsigned int nelts; > + if (const_vec_duplicate_p (src, &elt)) > + { > + rtx ops[] = {target, src}; > + emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); > + } > + else if (GET_MODE_NUNITS (mode).is_constant (&nelts)) > + { > + rvv_builder builder (mode, nelts, 1); > + for (unsigned int i = 0; i < nelts; i++) > + builder.quick_push (CONST_VECTOR_ELT (src, i)); > + rtx mask = builder.get_compact_mask (); > + rtx mem = validize_mem (force_const_mem (GET_MODE (mask), mask)); > + emit_move_insn (target, gen_rtx_MEM (mode, XEXP (mem, 0))); > + } > + else > + gcc_unreachable (); > return; > } > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index 280aa0b33b9..86c83f0906d 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -1323,6 +1323,12 @@ riscv_const_insns (rtx x) > return 1 + 4; /*vmv.v.x + memory access. */ > } > } > + > + /* GCC doesn't known RVV is using compact model of mask, > + we should by default handle mask in mov<mode> pattern. */ > + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL) > + /* TODO: We can adjust it according real cost model of vlm.v. */ > + return 1; > } > /* TODO: We may support more const vector in the future. */ > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > new file mode 100644 > index 00000000000..81229fd62b9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int64_t out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > new file mode 100644 > index 00000000000..a23e47171bc > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > new file mode 100644 > index 00000000000..6ea8fdd89c0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int16_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int16_t out[N] = {0}; > + for (int16_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int16_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > new file mode 100644 > index 00000000000..2d97c26abfd > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > new file mode 100644 > index 00000000000..b89b70e99a6 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > @@ -0,0 +1,25 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 32 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > new file mode 100644 > index 00000000000..ac8d91e793b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > @@ -0,0 +1,27 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 64 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > new file mode 100644 > index 00000000000..f538db23b1d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + uint8_t mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + uint8_t out[N] = {0}; > + for (uint8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (uint8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > new file mode 100644 > index 00000000000..5abb34c1686 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + int mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > new file mode 100644 > index 00000000000..6fdaa516534 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + int64_t mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int64_t out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > -- > 2.36.1 > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 3:16 ` Kito Cheng @ 2023-06-28 3:19 ` juzhe.zhong 2023-06-28 4:09 ` Jeff Law 2023-06-28 9:50 ` juzhe.zhong 2 siblings, 0 replies; 11+ messages in thread From: juzhe.zhong @ 2023-06-28 3:19 UTC (permalink / raw) To: Kito.cheng Cc: gcc-patches, kito.cheng, palmer, palmer, jeffreyalaw, Robin Dapp [-- Attachment #1: Type: text/plain, Size: 17609 bytes --] I have commented in commit log: before this patch: The mask is: .LC1: .byte 68 ====> 0b01000100 However, this is incorrect for RVV since RVV always uses 1-bit compact mask, now after this patch: .LC1: .byte 10 ====> 0b1010 juzhe.zhong@rivai.ai From: Kito Cheng Date: 2023-06-28 11:16 To: juzhe.zhong@rivai.ai CC: gcc-patches; kito.cheng; palmer; palmer; jeffreyalaw; Robin Dapp Subject: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask Do you mind giving some comments about what the difference between the two versions? On Wed, Jun 28, 2023 at 11:14 AM juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> wrote: > > This patch is the critical patch for following patches since it is a bug which I already address in rvv-next. > > ________________________________ > juzhe.zhong@rivai.ai > > > From: Juzhe-Zhong > Date: 2023-06-28 09:59 > To: gcc-patches > CC: kito.cheng; kito.cheng; palmer; palmer; jeffreyalaw; rdapp.gcc; Juzhe-Zhong > Subject: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask > This bug blocks the following patches. > > GCC doesn't know RVV is using compact mask model. > Consider this following case: > > #define N 16 > > int > main () > { > int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > int8_t out[N] = {0}; > for (int8_t i = 0; i < N; ++i) > if (mask[i]) > out[i] = i; > for (int8_t i = 0; i < N; ++i) > { > if (mask[i]) > assert (out[i] == i); > else > assert (out[i] == 0); > } > } > > Before this patch, the pre-calculated mask in constant memory pool: > .LC1: > .byte 68 ====> 0b01000100 > > This is incorrect, such case failed in execution. > > After this patch: > .LC1: > .byte 10 ====> 0b1010 > > Pass on exection. > > gcc/ChangeLog: > > * config/riscv/riscv-v.cc (rvv_builder::get_compact_mask): New function. > (expand_const_vector): Ditto. > * config/riscv/riscv.cc (riscv_const_insns): Ditto. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c: New test. > > --- > gcc/config/riscv/riscv-v.cc | 64 +++++++++++++++++-- > gcc/config/riscv/riscv.cc | 6 ++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-1.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-2.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-3.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-4.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-5.c | 25 ++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-6.c | 27 ++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-7.c | 30 +++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-8.c | 30 +++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-9.c | 30 +++++++++ > 11 files changed, 299 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > > diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc > index adb8d7d36a5..5da0dc5e998 100644 > --- a/gcc/config/riscv/riscv-v.cc > +++ b/gcc/config/riscv/riscv-v.cc > @@ -291,6 +291,7 @@ public: > bool single_step_npatterns_p () const; > bool npatterns_all_equal_p () const; > + rtx get_compact_mask () const; > machine_mode new_mode () const { return m_new_mode; } > scalar_mode inner_mode () const { return m_inner_mode; } > @@ -505,6 +506,47 @@ rvv_builder::npatterns_all_equal_p () const > return true; > } > +/* Generate the compact mask. > + > + E.g: mask = { 0, -1 }, mode = VNx2BI, bitsize = 128bits. > + > + GCC by default will generate the mask = 0b00000001xxxxx. > + > + However, it's not expected mask for RVV since RVV > + prefers the compact mask = 0b10xxxxx. > +*/ > +rtx > +rvv_builder::get_compact_mask () const > +{ > + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. > + Otherwise, the minimum LMUL = 1/8. */ > + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; > + unsigned min_container_size > + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; > + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); > + machine_mode container_mode > + = get_vector_mode (QImode, container_size).require (); > + > + unsigned nunits = GET_MODE_NUNITS (container_mode).to_constant (); > + rtvec v = rtvec_alloc (nunits); > + for (unsigned i = 0; i < nunits; i++) > + RTVEC_ELT (v, i) = const0_rtx; > + > + unsigned char b = 0; > + for (unsigned i = 0; i < npatterns (); i++) > + { > + if (INTVAL (elt (i))) > + b = b | (1 << (i % 8)); > + > + if ((i > 0 && (i % 8) == 7) || (i == (npatterns () - 1))) > + { > + RTVEC_ELT (v, ((i + 7) / 8) - 1) = gen_int_mode (b, QImode); > + b = 0; > + } > + } > + return gen_rtx_CONST_VECTOR (container_mode, v); > +} > + > static unsigned > get_sew (machine_mode mode) > { > @@ -1141,11 +1183,23 @@ expand_const_vector (rtx target, rtx src) > if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) > { > rtx elt; > - gcc_assert ( > - const_vec_duplicate_p (src, &elt) > - && (rtx_equal_p (elt, const0_rtx) || rtx_equal_p (elt, const1_rtx))); > - rtx ops[] = {target, src}; > - emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); > + unsigned int nelts; > + if (const_vec_duplicate_p (src, &elt)) > + { > + rtx ops[] = {target, src}; > + emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); > + } > + else if (GET_MODE_NUNITS (mode).is_constant (&nelts)) > + { > + rvv_builder builder (mode, nelts, 1); > + for (unsigned int i = 0; i < nelts; i++) > + builder.quick_push (CONST_VECTOR_ELT (src, i)); > + rtx mask = builder.get_compact_mask (); > + rtx mem = validize_mem (force_const_mem (GET_MODE (mask), mask)); > + emit_move_insn (target, gen_rtx_MEM (mode, XEXP (mem, 0))); > + } > + else > + gcc_unreachable (); > return; > } > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index 280aa0b33b9..86c83f0906d 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -1323,6 +1323,12 @@ riscv_const_insns (rtx x) > return 1 + 4; /*vmv.v.x + memory access. */ > } > } > + > + /* GCC doesn't known RVV is using compact model of mask, > + we should by default handle mask in mov<mode> pattern. */ > + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL) > + /* TODO: We can adjust it according real cost model of vlm.v. */ > + return 1; > } > /* TODO: We may support more const vector in the future. */ > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > new file mode 100644 > index 00000000000..81229fd62b9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int64_t out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > new file mode 100644 > index 00000000000..a23e47171bc > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > new file mode 100644 > index 00000000000..6ea8fdd89c0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int16_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int16_t out[N] = {0}; > + for (int16_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int16_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > new file mode 100644 > index 00000000000..2d97c26abfd > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > new file mode 100644 > index 00000000000..b89b70e99a6 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > @@ -0,0 +1,25 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 32 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > new file mode 100644 > index 00000000000..ac8d91e793b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > @@ -0,0 +1,27 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 64 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > new file mode 100644 > index 00000000000..f538db23b1d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + uint8_t mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + uint8_t out[N] = {0}; > + for (uint8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (uint8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > new file mode 100644 > index 00000000000..5abb34c1686 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + int mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > new file mode 100644 > index 00000000000..6fdaa516534 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + int64_t mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int64_t out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > -- > 2.36.1 > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 3:16 ` Kito Cheng 2023-06-28 3:19 ` juzhe.zhong @ 2023-06-28 4:09 ` Jeff Law 2023-06-28 6:01 ` Kito Cheng 2023-06-28 7:17 ` Richard Biener 2023-06-28 9:50 ` juzhe.zhong 2 siblings, 2 replies; 11+ messages in thread From: Jeff Law @ 2023-06-28 4:09 UTC (permalink / raw) To: Kito Cheng, juzhe.zhong Cc: gcc-patches, kito.cheng, palmer, palmer, Robin Dapp On 6/27/23 21:16, Kito Cheng wrote: > Do you mind giving some comments about what the difference between the > two versions? And I'd like a before/after assembly code with the example in the commit message. I didn't see the same behavior when I tried it earlier today and ran out of time to dig into it further. Juzhe -- most folks wait ~1wk to ping patches, even codegen bugfixes. Pinging this fast runs the risk of irritating others. Please be patient. Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 4:09 ` Jeff Law @ 2023-06-28 6:01 ` Kito Cheng 2023-06-28 6:17 ` juzhe.zhong 2023-06-28 7:17 ` Richard Biener 1 sibling, 1 reply; 11+ messages in thread From: Kito Cheng @ 2023-06-28 6:01 UTC (permalink / raw) To: Jeff Law; +Cc: juzhe.zhong, gcc-patches, kito.cheng, palmer, palmer, Robin Dapp I mean the difference between v1 and v2 patch On Wed, Jun 28, 2023 at 12:09 PM Jeff Law <jeffreyalaw@gmail.com> wrote: > > > > On 6/27/23 21:16, Kito Cheng wrote: > > Do you mind giving some comments about what the difference between the > > two versions? > And I'd like a before/after assembly code with the example in the commit > message. I didn't see the same behavior when I tried it earlier today > and ran out of time to dig into it further. > > Juzhe -- most folks wait ~1wk to ping patches, even codegen bugfixes. > Pinging this fast runs the risk of irritating others. Please be patient. > > Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 6:01 ` Kito Cheng @ 2023-06-28 6:17 ` juzhe.zhong 0 siblings, 0 replies; 11+ messages in thread From: juzhe.zhong @ 2023-06-28 6:17 UTC (permalink / raw) To: Kito.cheng, jeffreyalaw Cc: gcc-patches, kito.cheng, palmer, palmer, Robin Dapp [-- Attachment #1: Type: text/plain, Size: 2196 bytes --] The difference between v1 and v2 is the compact mask generation: v1 : +rtx +rvv_builder::compact_mask () const +{ + /* Use the container mode with SEW = 8 and LMUL = 1. */ + unsigned container_size + = MAX (CEIL (npatterns (), 8), BYTES_PER_RISCV_VECTOR.to_constant () / 8); + machine_mode container_mode + = get_vector_mode (QImode, container_size).require ();... v2: +rtx +rvv_builder::get_compact_mask () const +{ + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. + Otherwise, the minimum LMUL = 1/8. */ + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; + unsigned min_container_size + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); + machine_mode container_mode + = get_vector_mode (QImode, container_size).require ();... The difference is that v1: unsigned container_size = MAX (CEIL (npatterns (), 8), BYTES_PER_RISCV_VECTOR.to_constant () / 8); v2: + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. + Otherwise, the minimum LMUL = 1/8. */ + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; + unsigned min_container_size + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); juzhe.zhong@rivai.ai From: Kito Cheng Date: 2023-06-28 14:01 To: Jeff Law CC: juzhe.zhong@rivai.ai; gcc-patches; kito.cheng; palmer; palmer; Robin Dapp Subject: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask I mean the difference between v1 and v2 patch On Wed, Jun 28, 2023 at 12:09 PM Jeff Law <jeffreyalaw@gmail.com> wrote: > > > > On 6/27/23 21:16, Kito Cheng wrote: > > Do you mind giving some comments about what the difference between the > > two versions? > And I'd like a before/after assembly code with the example in the commit > message. I didn't see the same behavior when I tried it earlier today > and ran out of time to dig into it further. > > Juzhe -- most folks wait ~1wk to ping patches, even codegen bugfixes. > Pinging this fast runs the risk of irritating others. Please be patient. > > Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 4:09 ` Jeff Law 2023-06-28 6:01 ` Kito Cheng @ 2023-06-28 7:17 ` Richard Biener 2023-06-28 7:38 ` juzhe.zhong 2023-06-28 8:15 ` juzhe.zhong 1 sibling, 2 replies; 11+ messages in thread From: Richard Biener @ 2023-06-28 7:17 UTC (permalink / raw) To: Jeff Law Cc: Kito Cheng, juzhe.zhong, gcc-patches, kito.cheng, palmer, palmer, Robin Dapp On Wed, Jun 28, 2023 at 6:09 AM Jeff Law via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > On 6/27/23 21:16, Kito Cheng wrote: > > Do you mind giving some comments about what the difference between the > > two versions? > And I'd like a before/after assembly code with the example in the commit > message. I didn't see the same behavior when I tried it earlier today > and ran out of time to dig into it further. > > Juzhe -- most folks wait ~1wk to ping patches, even codegen bugfixes. > Pinging this fast runs the risk of irritating others. Please be patient. I think if we get constant mask expansion wrong this has to be fixed in generic code. ISTR fixing similar issues with AVX512 compact masks. But maybe I'm misunderstanding the problem and the issue only exists in the backend? Richard. > Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 7:17 ` Richard Biener @ 2023-06-28 7:38 ` juzhe.zhong 2023-06-28 8:15 ` juzhe.zhong 1 sibling, 0 replies; 11+ messages in thread From: juzhe.zhong @ 2023-06-28 7:38 UTC (permalink / raw) To: Richard Biener, jeffreyalaw Cc: Kito.cheng, gcc-patches, kito.cheng, palmer, palmer, Robin Dapp [-- Attachment #1: Type: text/plain, Size: 1844 bytes --] Hi, Richi. Thanks for taking care of this issue. From my observation, VNx2BI is using 2-bit mask: 00 = 0, 01 = 1 VNx4BI is using 4-bit mask: 0000 = 0, 0001 = 1 This perfectly works for ARM SVE since this is the layout of ARM mask register. However, RVV is always using compact mask that is using 1-bit mask. That's why it doesn't work for RVV. For X86, I think it wouldn't be the issue since X86 is always constant mask: VECTOR_BOOL_MODE (NAME, COUNT, COMPONENT, BYTESIZE) X86 can always adjust the compact bit by this define. Wheras, RVV is scalable vector which always uses ADJUST_NUNTIS and ADJUST_BYTESIZE && ADJUST_PRECISION. So this will make a confusion to GCC. Thanks. juzhe.zhong@rivai.ai From: Richard Biener Date: 2023-06-28 15:17 To: Jeff Law CC: Kito Cheng; juzhe.zhong@rivai.ai; gcc-patches; kito.cheng; palmer; palmer; Robin Dapp Subject: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask On Wed, Jun 28, 2023 at 6:09 AM Jeff Law via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > On 6/27/23 21:16, Kito Cheng wrote: > > Do you mind giving some comments about what the difference between the > > two versions? > And I'd like a before/after assembly code with the example in the commit > message. I didn't see the same behavior when I tried it earlier today > and ran out of time to dig into it further. > > Juzhe -- most folks wait ~1wk to ping patches, even codegen bugfixes. > Pinging this fast runs the risk of irritating others. Please be patient. I think if we get constant mask expansion wrong this has to be fixed in generic code. ISTR fixing similar issues with AVX512 compact masks. But maybe I'm misunderstanding the problem and the issue only exists in the backend? Richard. > Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 7:17 ` Richard Biener 2023-06-28 7:38 ` juzhe.zhong @ 2023-06-28 8:15 ` juzhe.zhong 1 sibling, 0 replies; 11+ messages in thread From: juzhe.zhong @ 2023-06-28 8:15 UTC (permalink / raw) To: Richard Biener, jeffreyalaw Cc: Kito.cheng, gcc-patches, kito.cheng, palmer, palmer, Robin Dapp [-- Attachment #1: Type: text/plain, Size: 2326 bytes --] Hi, Richi. After I dig into the codes and experiment: https://godbolt.org/z/hMf5nsPeK This example is VNx8QI, GCC works fine for RVV using 1-bit compact mask. ADJUST_PRECISION (VNx1BI, riscv_v_adjust_precision (VNx1BImode, 1)); ADJUST_PRECISION (VNx2BI, riscv_v_adjust_precision (VNx2BImode, 2)); ADJUST_PRECISION (VNx4BI, riscv_v_adjust_precision (VNx4BImode, 4)); ADJUST_PRECISION (VNx8BI, riscv_v_adjust_precision (VNx8BImode, 8)); ADJUST_PRECISION (VNx16BI, riscv_v_adjust_precision (VNx16BImode, 16)); ADJUST_PRECISION (VNx32BI, riscv_v_adjust_precision (VNx32BImode, 32)); ADJUST_PRECISION (VNx64BI, riscv_v_adjust_precision (VNx64BImode, 64)); ADJUST_PRECISION (VNx128BI, riscv_v_adjust_precision (VNx128BImode, 128)); The only problem is for VNx1BI, VNx2BI, VNx4BI since we use ADJUST_PRECISION to differentiate them with VNx8QI. VNx1BI, VNx2BI, VNx4BI is too small and GCC can not represent a mode with only 4bit size in GET_MODE_SIZE, now we use ADJUST_PRECISION to differentiate them. However, it cause loading bitmask for VNx1BI/VNx2BI/VNx4BI incorrectly, so this patch is to fix such in RISC-V backend. This is the RISC-V specific issue and would not happen on X86. Thanks. juzhe.zhong@rivai.ai From: Richard Biener Date: 2023-06-28 15:17 To: Jeff Law CC: Kito Cheng; juzhe.zhong@rivai.ai; gcc-patches; kito.cheng; palmer; palmer; Robin Dapp Subject: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask On Wed, Jun 28, 2023 at 6:09 AM Jeff Law via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > On 6/27/23 21:16, Kito Cheng wrote: > > Do you mind giving some comments about what the difference between the > > two versions? > And I'd like a before/after assembly code with the example in the commit > message. I didn't see the same behavior when I tried it earlier today > and ran out of time to dig into it further. > > Juzhe -- most folks wait ~1wk to ping patches, even codegen bugfixes. > Pinging this fast runs the risk of irritating others. Please be patient. I think if we get constant mask expansion wrong this has to be fixed in generic code. ISTR fixing similar issues with AVX512 compact masks. But maybe I'm misunderstanding the problem and the issue only exists in the backend? Richard. > Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask 2023-06-28 3:16 ` Kito Cheng 2023-06-28 3:19 ` juzhe.zhong 2023-06-28 4:09 ` Jeff Law @ 2023-06-28 9:50 ` juzhe.zhong 2 siblings, 0 replies; 11+ messages in thread From: juzhe.zhong @ 2023-06-28 9:50 UTC (permalink / raw) To: Kito.cheng Cc: gcc-patches, kito.cheng, palmer, palmer, jeffreyalaw, Robin Dapp [-- Attachment #1: Type: text/plain, Size: 17580 bytes --] Hi, after deeply diging into this issue: I figure out what is happening, this is the V3 patch: https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623052.html There is a comprehensive explanation in commit log. juzhe.zhong@rivai.ai From: Kito Cheng Date: 2023-06-28 11:16 To: juzhe.zhong@rivai.ai CC: gcc-patches; kito.cheng; palmer; palmer; jeffreyalaw; Robin Dapp Subject: Re: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask Do you mind giving some comments about what the difference between the two versions? On Wed, Jun 28, 2023 at 11:14 AM juzhe.zhong@rivai.ai <juzhe.zhong@rivai.ai> wrote: > > This patch is the critical patch for following patches since it is a bug which I already address in rvv-next. > > ________________________________ > juzhe.zhong@rivai.ai > > > From: Juzhe-Zhong > Date: 2023-06-28 09:59 > To: gcc-patches > CC: kito.cheng; kito.cheng; palmer; palmer; jeffreyalaw; rdapp.gcc; Juzhe-Zhong > Subject: [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask > This bug blocks the following patches. > > GCC doesn't know RVV is using compact mask model. > Consider this following case: > > #define N 16 > > int > main () > { > int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > int8_t out[N] = {0}; > for (int8_t i = 0; i < N; ++i) > if (mask[i]) > out[i] = i; > for (int8_t i = 0; i < N; ++i) > { > if (mask[i]) > assert (out[i] == i); > else > assert (out[i] == 0); > } > } > > Before this patch, the pre-calculated mask in constant memory pool: > .LC1: > .byte 68 ====> 0b01000100 > > This is incorrect, such case failed in execution. > > After this patch: > .LC1: > .byte 10 ====> 0b1010 > > Pass on exection. > > gcc/ChangeLog: > > * config/riscv/riscv-v.cc (rvv_builder::get_compact_mask): New function. > (expand_const_vector): Ditto. > * config/riscv/riscv.cc (riscv_const_insns): Ditto. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c: New test. > * gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c: New test. > > --- > gcc/config/riscv/riscv-v.cc | 64 +++++++++++++++++-- > gcc/config/riscv/riscv.cc | 6 ++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-1.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-2.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-3.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-4.c | 23 +++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-5.c | 25 ++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-6.c | 27 ++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-7.c | 30 +++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-8.c | 30 +++++++++ > .../riscv/rvv/autovec/vls-vlmax/bitmask-9.c | 30 +++++++++ > 11 files changed, 299 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > > diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc > index adb8d7d36a5..5da0dc5e998 100644 > --- a/gcc/config/riscv/riscv-v.cc > +++ b/gcc/config/riscv/riscv-v.cc > @@ -291,6 +291,7 @@ public: > bool single_step_npatterns_p () const; > bool npatterns_all_equal_p () const; > + rtx get_compact_mask () const; > machine_mode new_mode () const { return m_new_mode; } > scalar_mode inner_mode () const { return m_inner_mode; } > @@ -505,6 +506,47 @@ rvv_builder::npatterns_all_equal_p () const > return true; > } > +/* Generate the compact mask. > + > + E.g: mask = { 0, -1 }, mode = VNx2BI, bitsize = 128bits. > + > + GCC by default will generate the mask = 0b00000001xxxxx. > + > + However, it's not expected mask for RVV since RVV > + prefers the compact mask = 0b10xxxxx. > +*/ > +rtx > +rvv_builder::get_compact_mask () const > +{ > + /* If TARGET_MIN_VLEN == 32, the minimum LMUL = 1/4. > + Otherwise, the minimum LMUL = 1/8. */ > + unsigned min_lmul = TARGET_MIN_VLEN == 32 ? 4 : 8; > + unsigned min_container_size > + = BYTES_PER_RISCV_VECTOR.to_constant () / min_lmul; > + unsigned container_size = MAX (CEIL (npatterns (), 8), min_container_size); > + machine_mode container_mode > + = get_vector_mode (QImode, container_size).require (); > + > + unsigned nunits = GET_MODE_NUNITS (container_mode).to_constant (); > + rtvec v = rtvec_alloc (nunits); > + for (unsigned i = 0; i < nunits; i++) > + RTVEC_ELT (v, i) = const0_rtx; > + > + unsigned char b = 0; > + for (unsigned i = 0; i < npatterns (); i++) > + { > + if (INTVAL (elt (i))) > + b = b | (1 << (i % 8)); > + > + if ((i > 0 && (i % 8) == 7) || (i == (npatterns () - 1))) > + { > + RTVEC_ELT (v, ((i + 7) / 8) - 1) = gen_int_mode (b, QImode); > + b = 0; > + } > + } > + return gen_rtx_CONST_VECTOR (container_mode, v); > +} > + > static unsigned > get_sew (machine_mode mode) > { > @@ -1141,11 +1183,23 @@ expand_const_vector (rtx target, rtx src) > if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL) > { > rtx elt; > - gcc_assert ( > - const_vec_duplicate_p (src, &elt) > - && (rtx_equal_p (elt, const0_rtx) || rtx_equal_p (elt, const1_rtx))); > - rtx ops[] = {target, src}; > - emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); > + unsigned int nelts; > + if (const_vec_duplicate_p (src, &elt)) > + { > + rtx ops[] = {target, src}; > + emit_vlmax_insn (code_for_pred_mov (mode), RVV_UNOP, ops); > + } > + else if (GET_MODE_NUNITS (mode).is_constant (&nelts)) > + { > + rvv_builder builder (mode, nelts, 1); > + for (unsigned int i = 0; i < nelts; i++) > + builder.quick_push (CONST_VECTOR_ELT (src, i)); > + rtx mask = builder.get_compact_mask (); > + rtx mem = validize_mem (force_const_mem (GET_MODE (mask), mask)); > + emit_move_insn (target, gen_rtx_MEM (mode, XEXP (mem, 0))); > + } > + else > + gcc_unreachable (); > return; > } > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc > index 280aa0b33b9..86c83f0906d 100644 > --- a/gcc/config/riscv/riscv.cc > +++ b/gcc/config/riscv/riscv.cc > @@ -1323,6 +1323,12 @@ riscv_const_insns (rtx x) > return 1 + 4; /*vmv.v.x + memory access. */ > } > } > + > + /* GCC doesn't known RVV is using compact model of mask, > + we should by default handle mask in mov<mode> pattern. */ > + if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL) > + /* TODO: We can adjust it according real cost model of vlm.v. */ > + return 1; > } > /* TODO: We may support more const vector in the future. */ > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > new file mode 100644 > index 00000000000..81229fd62b9 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-1.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int64_t out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > new file mode 100644 > index 00000000000..a23e47171bc > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-2.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > new file mode 100644 > index 00000000000..6ea8fdd89c0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-3.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int16_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int16_t out[N] = {0}; > + for (int16_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int16_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > new file mode 100644 > index 00000000000..2d97c26abfd > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-4.c > @@ -0,0 +1,23 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > +#define N 16 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > new file mode 100644 > index 00000000000..b89b70e99a6 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-5.c > @@ -0,0 +1,25 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m2 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 32 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > new file mode 100644 > index 00000000000..ac8d91e793b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-6.c > @@ -0,0 +1,27 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m4 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 64 > + > +int > +main () > +{ > + int8_t mask[N] = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int8_t out[N] = {0}; > + for (int8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > new file mode 100644 > index 00000000000..f538db23b1d > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-7.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + uint8_t mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + uint8_t out[N] = {0}; > + for (uint8_t i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (uint8_t i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > new file mode 100644 > index 00000000000..5abb34c1686 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-8.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + int mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > new file mode 100644 > index 00000000000..6fdaa516534 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vls-vlmax/bitmask-9.c > @@ -0,0 +1,30 @@ > +/* { dg-do run { target { riscv_vector } } } */ > +/* { dg-options "--param riscv-autovec-preference=fixed-vlmax --param riscv-autovec-lmul=m8 -O3" } */ > + > +#include <stdint-gcc.h> > +#include <assert.h> > + > +#define N 128 > + > +int > +main () > +{ > + int64_t mask[N] > + = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, > + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1}; > + int64_t out[N] = {0}; > + for (int i = 0; i < N; ++i) > + if (mask[i]) > + out[i] = i; > + for (int i = 0; i < N; ++i) > + { > + if (mask[i]) > + assert (out[i] == i); > + else > + assert (out[i] == 0); > + } > +} > -- > 2.36.1 > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-06-28 9:50 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-06-28 1:59 [PATCH V2] RISC-V: Fix bug of pre-calculated const vector mask Juzhe-Zhong 2023-06-28 3:14 ` juzhe.zhong 2023-06-28 3:16 ` Kito Cheng 2023-06-28 3:19 ` juzhe.zhong 2023-06-28 4:09 ` Jeff Law 2023-06-28 6:01 ` Kito Cheng 2023-06-28 6:17 ` juzhe.zhong 2023-06-28 7:17 ` Richard Biener 2023-06-28 7:38 ` juzhe.zhong 2023-06-28 8:15 ` juzhe.zhong 2023-06-28 9:50 ` juzhe.zhong
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).