RISC-V: Support interleave vector with different step sequence
commit71a5ac6703d1b7a0409936fcdec4e592d7cc06b0
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>
Thu, 7 Dec 2023 22:09:10 +0000 (8 06:09 +0800)
committerPan Li <pan2.li@intel.com>
Thu, 7 Dec 2023 23:26:22 +0000 (8 07:26 +0800)
treeb7a4e4f3552c43d778b4f956f4fdc3e0a7f4a78c
parent0832cf42a6912f876086cb14b92f788d8406f393
RISC-V: Support interleave vector with different step sequence

This patch fixes 64 ICEs in full coverage testing since they happens due to same reason.

Before this patch:

internal compiler error: in expand_const_vector, at config/riscv/riscv-v.cc:1270

appears 400 times in full coverage testing report.

The root cause is we didn't support interleave vector with different steps.

Here is the story:

We already supported interleave with single same step, that is:
e.g. v = { 0, 100, 2, 102, 4, 104, ... }
This sequence can be interpreted as interleave vector by 2 seperate sequences:
sequence1 = { 0, 2, 4, ... } and sequence2 = { 100, 102, 104, ... }.
Their step are both 2.

However, we didn't support interleave vector when they have different steps which
cause ICE in such situations.

This patch support different steps interleaved vector for the following 2 situations:

1. When vector can be extended EEW:

Case 1: { 0, 0, 1, 0, 2, 0, ... }
It's interleaved by sequence1 = { 0, 1, 2, ... } and sequence1 = { 0, 0, 0, ... }
Suppose the original vector can be extended EEW, e.g. mode = RVVM1SImode.
Then such interleaved vector can be achieved with { 1, 2, 3, ... } with RVVM1DImode.
So, for this situation the codegen is pretty efficient and clean:

.MASK_LEN_STORE (&s, 32B, { -1, ... }, 16, 0, { 0, 0, 1, 0, 2, 0, ... });

->
   vsetvli a5,zero,e64,m8,ta,ma
   vid.v v8
   vsetivli zero,16,e32,m8,ta,ma
   vse32.v v8,0(a4)

Case 2: { 0, 100, 1, 100, 2, 100, ... }

.MASK_LEN_STORE (&s, 32B, { -1, ... }, 16, 0, { 0, 100, 1, 100, 2, 100, ... });

->

   vsetvli a1,zero,e64,m8,ta,ma
   vid.v v8
   li a7,100
   vand.vx v8,v8,a4
   vsetivli zero,16,e32,m8,ta,ma
   vse32.v v8,0(a5)

2. When vector can't be extended EEW:

Since we can't use EEW = 64, for example, RVVM1SImode in -march=rv32gc_zve32f,
we use vmerge to combine the sequence.

.MASK_LEN_STORE (&s, 32B, { -1, ... }, 16, 0, { 200, 100, 201, 103, 202, 106, ... });

1. Generate sequence1 = { 200, 200, 201, 201, 202, 202, ... } and sequence2 = { 100, 100, 103, 103, 106, 106, ... }
2. Merge sequence1 and sequence2 with mask { 0, 1, 0, 1, ... }

gcc/ChangeLog:

* config/riscv/riscv-protos.h (expand_vec_series): Adapt function.
* config/riscv/riscv-v.cc (rvv_builder::double_steps_npatterns_p): New function.
(expand_vec_series): Adapt function.
(expand_const_vector): Support new interleave vector with different step.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/autovec/slp-interleave-1.c: New test.
* gcc.target/riscv/rvv/autovec/slp-interleave-2.c: New test.
* gcc.target/riscv/rvv/autovec/slp-interleave-3.c: New test.
* gcc.target/riscv/rvv/autovec/slp-interleave-4.c: New test.
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv-v.cc
gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-interleave-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-interleave-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-interleave-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/slp-interleave-4.c [new file with mode: 0644]