RISC-V: Support VLS modes VEC_EXTRACT auto-vectorization

This patch support VLS modes VEC_EXTRACT to fix PR111391:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111391

I need VLS modes VEC_EXTRACT to fix this issue.

I have run the whole gcc testsuite, notice this patch increase these 4 FAILs:
FAIL: c-c++-common/vector-subscript-4.c  -std=gnu++14  scan-tree-dump-not optimized "vector"
FAIL: c-c++-common/vector-subscript-4.c  -std=gnu++17  scan-tree-dump-not optimized "vector"
FAIL: c-c++-common/vector-subscript-4.c  -std=gnu++20  scan-tree-dump-not optimized "vector"
FAIL: c-c++-common/vector-subscript-4.c  -std=gnu++98  scan-tree-dump-not optimized "vector"

After analysis and comparing with LLVM:
https://godbolt.org/z/ozhfKhj5Y

with this patch, GCC generate similar codegen like LLVM (Previously it can not be vectorized).

This patch is the prerequisite patch to fix an ICE.

So let's ignore those increased 4 dump IR FAILs since ICE is un-acceptable wheras dump FAILs are acceptable (But we should remember and eventually fix dump IR FAILs too).

gcc/ChangeLog:

	* config/riscv/autovec.md (vec_extract<mode><vel>): Add VLS modes.
	(@vec_extract<mode><vel>): Ditto.
	* config/riscv/vector.md: Ditto

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/rvv/autovec/vls/def.h: Add more def.
	* gcc.target/riscv/rvv/autovec/vls/extract-1.c: New test.
	* gcc.target/riscv/rvv/autovec/vls/extract-2.c: New test.
This commit is contained in:
Juzhe-Zhong 2023-09-13 20:18:02 +08:00 committed by Pan Li
parent 4a937fa94f
commit d03773c8ef
5 changed files with 307 additions and 9 deletions

View file

@ -1442,10 +1442,10 @@
;; -------------------------------------------------------------------------
;; ---- [INT,FP] Extract a vector element.
;; -------------------------------------------------------------------------
(define_expand "vec_extract<mode><vel>"
(define_expand "@vec_extract<mode><vel>"
[(set (match_operand:<VEL> 0 "register_operand")
(vec_select:<VEL>
(match_operand:V 1 "register_operand")
(match_operand:V_VLS 1 "register_operand")
(parallel
[(match_operand 2 "nonmemory_operand")])))]
"TARGET_VECTOR"

View file

@ -8096,7 +8096,7 @@
[(set (match_operand:<VEL> 0 "register_operand")
(unspec:<VEL>
[(vec_select:<VEL>
(match_operand:VI 1 "reg_or_mem_operand")
(match_operand:V_VLSI 1 "reg_or_mem_operand")
(parallel [(const_int 0)]))
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))]
"TARGET_VECTOR"
@ -8113,7 +8113,7 @@
[(set (match_operand:<VEL> 0 "register_operand" "=r")
(unspec:<VEL>
[(vec_select:<VEL>
(match_operand:VI 1 "register_operand" "vr")
(match_operand:V_VLSI 1 "register_operand" "vr")
(parallel [(const_int 0)]))
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))]
"TARGET_VECTOR"
@ -8147,7 +8147,7 @@
(truncate:SI
(unspec:<VEL>
[(vec_select:<VEL>
(match_operand:VI_D 1 "register_operand" "vr")
(match_operand:V_VLSI_D 1 "register_operand" "vr")
(parallel [(const_int 0)]))
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)))]
"TARGET_VECTOR"
@ -8159,7 +8159,7 @@
[(set (match_operand:<VEL> 0 "register_operand")
(unspec:<VEL>
[(vec_select:<VEL>
(match_operand:VF 1 "reg_or_mem_operand")
(match_operand:V_VLSF 1 "reg_or_mem_operand")
(parallel [(const_int 0)]))
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))]
"TARGET_VECTOR"
@ -8176,7 +8176,7 @@
[(set (match_operand:<VEL> 0 "register_operand" "=f")
(unspec:<VEL>
[(vec_select:<VEL>
(match_operand:VF 1 "register_operand" "vr")
(match_operand:V_VLSF 1 "register_operand" "vr")
(parallel [(const_int 0)]))
(reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE))]
"TARGET_VECTOR"

View file

@ -45,7 +45,53 @@ typedef int64_t v32di __attribute__ ((vector_size (256)));
typedef int64_t v64di __attribute__ ((vector_size (512)));
typedef int64_t v128di __attribute__ ((vector_size (1024)));
typedef int64_t v256di __attribute__ ((vector_size (2048)));
typedef int64_t v512di __attribute__ ((vector_size (4096)));
typedef uint64_t v512di __attribute__ ((vector_size (4096)));
typedef uint8_t v1uqi __attribute__ ((vector_size (1)));
typedef uint8_t v2uqi __attribute__ ((vector_size (2)));
typedef uint8_t v4uqi __attribute__ ((vector_size (4)));
typedef uint8_t v8uqi __attribute__ ((vector_size (8)));
typedef uint8_t v16uqi __attribute__ ((vector_size (16)));
typedef uint8_t v32uqi __attribute__ ((vector_size (32)));
typedef uint8_t v64uqi __attribute__ ((vector_size (64)));
typedef uint8_t v128uqi __attribute__ ((vector_size (128)));
typedef uint8_t v256uqi __attribute__ ((vector_size (256)));
typedef uint8_t v512uqi __attribute__ ((vector_size (512)));
typedef uint8_t v1024uqi __attribute__ ((vector_size (1024)));
typedef uint8_t v2048uqi __attribute__ ((vector_size (2048)));
typedef uint8_t v4096uqi __attribute__ ((vector_size (4096)));
typedef uint16_t v1uhi __attribute__ ((vector_size (2)));
typedef uint16_t v2uhi __attribute__ ((vector_size (4)));
typedef uint16_t v4uhi __attribute__ ((vector_size (8)));
typedef uint16_t v8uhi __attribute__ ((vector_size (16)));
typedef uint16_t v16uhi __attribute__ ((vector_size (32)));
typedef uint16_t v32uhi __attribute__ ((vector_size (64)));
typedef uint16_t v64uhi __attribute__ ((vector_size (128)));
typedef uint16_t v128uhi __attribute__ ((vector_size (256)));
typedef uint16_t v256uhi __attribute__ ((vector_size (512)));
typedef uint16_t v512uhi __attribute__ ((vector_size (1024)));
typedef uint16_t v1024uhi __attribute__ ((vector_size (2048)));
typedef uint16_t v2048uhi __attribute__ ((vector_size (4096)));
typedef uint32_t v1usi __attribute__ ((vector_size (4)));
typedef uint32_t v2usi __attribute__ ((vector_size (8)));
typedef uint32_t v4usi __attribute__ ((vector_size (16)));
typedef uint32_t v8usi __attribute__ ((vector_size (32)));
typedef uint32_t v16usi __attribute__ ((vector_size (64)));
typedef uint32_t v32usi __attribute__ ((vector_size (128)));
typedef uint32_t v64usi __attribute__ ((vector_size (256)));
typedef uint32_t v128usi __attribute__ ((vector_size (512)));
typedef uint32_t v256usi __attribute__ ((vector_size (1024)));
typedef uint32_t v512usi __attribute__ ((vector_size (2048)));
typedef uint32_t v1024usi __attribute__ ((vector_size (4096)));
typedef uint64_t v1udi __attribute__ ((vector_size (8)));
typedef uint64_t v2udi __attribute__ ((vector_size (16)));
typedef uint64_t v4udi __attribute__ ((vector_size (32)));
typedef uint64_t v8udi __attribute__ ((vector_size (64)));
typedef uint64_t v16udi __attribute__ ((vector_size (128)));
typedef uint64_t v32udi __attribute__ ((vector_size (256)));
typedef uint64_t v64udi __attribute__ ((vector_size (512)));
typedef uint64_t v128udi __attribute__ ((vector_size (1024)));
typedef uint64_t v256udi __attribute__ ((vector_size (2048)));
typedef uint64_t v512udi __attribute__ ((vector_size (4096)));
typedef _Float16 v1hf __attribute__ ((vector_size (2)));
typedef _Float16 v2hf __attribute__ ((vector_size (4)));
typedef _Float16 v4hf __attribute__ ((vector_size (8)));
@ -108,7 +154,7 @@ typedef double v512df __attribute__ ((vector_size (4096)));
PREFIX##_##TYPE##NUM (TYPE *restrict a, TYPE *restrict b, TYPE *restrict c) \
{ \
for (int i = 0; i < NUM; ++i) \
a[i] = b[i] OP -16; \
a[i] = b[i] OP - 16; \
}
#define DEF_OP_VI_15(PREFIX, NUM, TYPE, OP) \
@ -196,3 +242,10 @@ typedef double v512df __attribute__ ((vector_size (4096)));
for (TYPE i = 0; i < NUM; ++i) \
a[i] = (BASE) + i * (STEP); \
}
#define DEF_EXTRACT(SCALAR, VECTOR, INDEX) \
SCALAR \
extract_##SCALAR##VECTOR (VECTOR v) \
{ \
return v[INDEX]; \
}

View file

@ -0,0 +1,122 @@
/* { dg-do compile } */
/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param riscv-autovec-lmul=m8" } */
#include "def.h"
DEF_EXTRACT (int8_t, v2qi, 0)
DEF_EXTRACT (int8_t, v4qi, 0)
DEF_EXTRACT (int8_t, v8qi, 0)
DEF_EXTRACT (int8_t, v16qi, 0)
DEF_EXTRACT (int8_t, v32qi, 0)
DEF_EXTRACT (int8_t, v64qi, 0)
DEF_EXTRACT (int8_t, v128qi, 0)
DEF_EXTRACT (int8_t, v256qi, 0)
DEF_EXTRACT (int8_t, v512qi, 0)
DEF_EXTRACT (int8_t, v1024qi, 0)
DEF_EXTRACT (int8_t, v2048qi, 0)
DEF_EXTRACT (int8_t, v4096qi, 0)
DEF_EXTRACT (int16_t, v2hi, 0)
DEF_EXTRACT (int16_t, v4hi, 0)
DEF_EXTRACT (int16_t, v8hi, 0)
DEF_EXTRACT (int16_t, v16hi, 0)
DEF_EXTRACT (int16_t, v32hi, 0)
DEF_EXTRACT (int16_t, v64hi, 0)
DEF_EXTRACT (int16_t, v128hi, 0)
DEF_EXTRACT (int16_t, v256hi, 0)
DEF_EXTRACT (int16_t, v512hi, 0)
DEF_EXTRACT (int16_t, v1024hi, 0)
DEF_EXTRACT (int16_t, v2048hi, 0)
DEF_EXTRACT (int32_t, v2si, 0)
DEF_EXTRACT (int32_t, v4si, 0)
DEF_EXTRACT (int32_t, v8si, 0)
DEF_EXTRACT (int32_t, v16si, 0)
DEF_EXTRACT (int32_t, v32si, 0);
DEF_EXTRACT (int32_t, v64si, 0);
DEF_EXTRACT (int32_t, v128si, 0)
DEF_EXTRACT (int32_t, v256si, 0)
DEF_EXTRACT (int32_t, v512si, 0)
DEF_EXTRACT (int32_t, v1024si, 0)
DEF_EXTRACT (int64_t, v2di, 0)
DEF_EXTRACT (int64_t, v4di, 0)
DEF_EXTRACT (int64_t, v8di, 0)
DEF_EXTRACT (int64_t, v16di, 0)
DEF_EXTRACT (int64_t, v32di, 0)
DEF_EXTRACT (int64_t, v64di, 0)
DEF_EXTRACT (int64_t, v128di, 0)
DEF_EXTRACT (int64_t, v256di, 0)
DEF_EXTRACT (int64_t, v512di, 0)
DEF_EXTRACT (uint8_t, v2uqi, 0)
DEF_EXTRACT (uint8_t, v4uqi, 0)
DEF_EXTRACT (uint8_t, v8uqi, 0)
DEF_EXTRACT (uint8_t, v16uqi, 0)
DEF_EXTRACT (uint8_t, v32uqi, 0)
DEF_EXTRACT (uint8_t, v64uqi, 0)
DEF_EXTRACT (uint8_t, v128uqi, 0)
DEF_EXTRACT (uint8_t, v256uqi, 0)
DEF_EXTRACT (uint8_t, v512uqi, 0)
DEF_EXTRACT (uint8_t, v1024uqi, 0)
DEF_EXTRACT (uint8_t, v2048uqi, 0)
DEF_EXTRACT (uint8_t, v4096uqi, 0)
DEF_EXTRACT (uint16_t, v2uhi, 0)
DEF_EXTRACT (uint16_t, v4uhi, 0)
DEF_EXTRACT (uint16_t, v8uhi, 0)
DEF_EXTRACT (uint16_t, v16uhi, 0)
DEF_EXTRACT (uint16_t, v32uhi, 0)
DEF_EXTRACT (uint16_t, v64uhi, 0)
DEF_EXTRACT (uint16_t, v128uhi, 0)
DEF_EXTRACT (uint16_t, v256uhi, 0)
DEF_EXTRACT (uint16_t, v512uhi, 0)
DEF_EXTRACT (uint16_t, v1024uhi, 0)
DEF_EXTRACT (uint16_t, v2048uhi, 0)
DEF_EXTRACT (uint32_t, v2usi, 0)
DEF_EXTRACT (uint32_t, v4usi, 0)
DEF_EXTRACT (uint32_t, v8usi, 0)
DEF_EXTRACT (uint32_t, v16usi, 0)
DEF_EXTRACT (uint32_t, v32usi, 0)
DEF_EXTRACT (uint32_t, v64usi, 0)
DEF_EXTRACT (uint32_t, v128usi, 0)
DEF_EXTRACT (uint32_t, v256usi, 0)
DEF_EXTRACT (uint32_t, v512usi, 0)
DEF_EXTRACT (uint32_t, v1024usi, 0)
DEF_EXTRACT (uint64_t, v2udi, 0)
DEF_EXTRACT (uint64_t, v4udi, 0)
DEF_EXTRACT (uint64_t, v8udi, 0)
DEF_EXTRACT (uint64_t, v16udi, 0)
DEF_EXTRACT (uint64_t, v32udi, 0)
DEF_EXTRACT (uint64_t, v64udi, 0)
DEF_EXTRACT (uint64_t, v128udi, 0)
DEF_EXTRACT (uint64_t, v256udi, 0)
DEF_EXTRACT (uint64_t, v512udi, 0)
DEF_EXTRACT (_Float16, v2hf, 0)
DEF_EXTRACT (_Float16, v4hf, 0)
DEF_EXTRACT (_Float16, v8hf, 0)
DEF_EXTRACT (_Float16, v16hf, 0)
DEF_EXTRACT (_Float16, v32hf, 0)
DEF_EXTRACT (_Float16, v64hf, 0)
DEF_EXTRACT (_Float16, v128hf, 0)
DEF_EXTRACT (_Float16, v256hf, 0)
DEF_EXTRACT (_Float16, v512hf, 0)
DEF_EXTRACT (_Float16, v1024hf, 0)
DEF_EXTRACT (_Float16, v2048hf, 0)
DEF_EXTRACT (float, v2sf, 0)
DEF_EXTRACT (float, v4sf, 0)
DEF_EXTRACT (float, v8sf, 0)
DEF_EXTRACT (float, v16sf, 0)
DEF_EXTRACT (float, v32sf, 0)
DEF_EXTRACT (float, v64sf, 0)
DEF_EXTRACT (float, v128sf, 0)
DEF_EXTRACT (float, v256sf, 0)
DEF_EXTRACT (float, v512sf, 0)
DEF_EXTRACT (float, v1024sf, 0)
DEF_EXTRACT (double, v2df, 0)
DEF_EXTRACT (double, v4df, 0)
DEF_EXTRACT (double, v8df, 0)
DEF_EXTRACT (double, v16df, 0)
DEF_EXTRACT (double, v32df, 0)
DEF_EXTRACT (double, v64df, 0)
DEF_EXTRACT (double, v128df, 0)
DEF_EXTRACT (double, v256df, 0)
DEF_EXTRACT (double, v512df, 0)
/* { dg-final { scan-assembler-times {vmv\.x\.s} 84 } } */
/* { dg-final { scan-assembler-times {vfmv\.f\.s} 30 } } */

View file

@ -0,0 +1,123 @@
/* { dg-do compile } */
/* { dg-options "-march=rv64gcv_zvfh_zvl4096b -mabi=lp64d -O3 --param riscv-autovec-lmul=m8" } */
#include "def.h"
DEF_EXTRACT (int8_t, v2qi, 1)
DEF_EXTRACT (int8_t, v4qi, 1)
DEF_EXTRACT (int8_t, v8qi, 1)
DEF_EXTRACT (int8_t, v16qi, 1)
DEF_EXTRACT (int8_t, v32qi, 1)
DEF_EXTRACT (int8_t, v64qi, 1)
DEF_EXTRACT (int8_t, v128qi, 1)
DEF_EXTRACT (int8_t, v256qi, 1)
DEF_EXTRACT (int8_t, v512qi, 1)
DEF_EXTRACT (int8_t, v1024qi, 1)
DEF_EXTRACT (int8_t, v2048qi, 1)
DEF_EXTRACT (int8_t, v4096qi, 1)
DEF_EXTRACT (int16_t, v2hi, 1)
DEF_EXTRACT (int16_t, v4hi, 1)
DEF_EXTRACT (int16_t, v8hi, 1)
DEF_EXTRACT (int16_t, v16hi, 1)
DEF_EXTRACT (int16_t, v32hi, 1)
DEF_EXTRACT (int16_t, v64hi, 1)
DEF_EXTRACT (int16_t, v128hi, 1)
DEF_EXTRACT (int16_t, v256hi, 1)
DEF_EXTRACT (int16_t, v512hi, 1)
DEF_EXTRACT (int16_t, v1024hi, 1)
DEF_EXTRACT (int16_t, v2048hi, 1)
DEF_EXTRACT (int32_t, v2si, 1)
DEF_EXTRACT (int32_t, v4si, 1)
DEF_EXTRACT (int32_t, v8si, 1)
DEF_EXTRACT (int32_t, v16si, 1)
DEF_EXTRACT (int32_t, v32si, 1);
DEF_EXTRACT (int32_t, v64si, 1);
DEF_EXTRACT (int32_t, v128si, 1)
DEF_EXTRACT (int32_t, v256si, 1)
DEF_EXTRACT (int32_t, v512si, 1)
DEF_EXTRACT (int32_t, v1024si, 1)
DEF_EXTRACT (int64_t, v2di, 1)
DEF_EXTRACT (int64_t, v4di, 1)
DEF_EXTRACT (int64_t, v8di, 1)
DEF_EXTRACT (int64_t, v16di, 1)
DEF_EXTRACT (int64_t, v32di, 1)
DEF_EXTRACT (int64_t, v64di, 1)
DEF_EXTRACT (int64_t, v128di, 1)
DEF_EXTRACT (int64_t, v256di, 1)
DEF_EXTRACT (int64_t, v512di, 1)
DEF_EXTRACT (uint8_t, v2uqi, 1)
DEF_EXTRACT (uint8_t, v4uqi, 1)
DEF_EXTRACT (uint8_t, v8uqi, 1)
DEF_EXTRACT (uint8_t, v16uqi, 1)
DEF_EXTRACT (uint8_t, v32uqi, 1)
DEF_EXTRACT (uint8_t, v64uqi, 1)
DEF_EXTRACT (uint8_t, v128uqi, 1)
DEF_EXTRACT (uint8_t, v256uqi, 1)
DEF_EXTRACT (uint8_t, v512uqi, 1)
DEF_EXTRACT (uint8_t, v1024uqi, 1)
DEF_EXTRACT (uint8_t, v2048uqi, 1)
DEF_EXTRACT (uint8_t, v4096uqi, 1)
DEF_EXTRACT (uint16_t, v2uhi, 1)
DEF_EXTRACT (uint16_t, v4uhi, 1)
DEF_EXTRACT (uint16_t, v8uhi, 1)
DEF_EXTRACT (uint16_t, v16uhi, 1)
DEF_EXTRACT (uint16_t, v32uhi, 1)
DEF_EXTRACT (uint16_t, v64uhi, 1)
DEF_EXTRACT (uint16_t, v128uhi, 1)
DEF_EXTRACT (uint16_t, v256uhi, 1)
DEF_EXTRACT (uint16_t, v512uhi, 1)
DEF_EXTRACT (uint16_t, v1024uhi, 1)
DEF_EXTRACT (uint16_t, v2048uhi, 1)
DEF_EXTRACT (uint32_t, v2usi, 1)
DEF_EXTRACT (uint32_t, v4usi, 1)
DEF_EXTRACT (uint32_t, v8usi, 1)
DEF_EXTRACT (uint32_t, v16usi, 1)
DEF_EXTRACT (uint32_t, v32usi, 1)
DEF_EXTRACT (uint32_t, v64usi, 1)
DEF_EXTRACT (uint32_t, v128usi, 1)
DEF_EXTRACT (uint32_t, v256usi, 1)
DEF_EXTRACT (uint32_t, v512usi, 1)
DEF_EXTRACT (uint32_t, v1024usi, 1)
DEF_EXTRACT (uint64_t, v2udi, 1)
DEF_EXTRACT (uint64_t, v4udi, 1)
DEF_EXTRACT (uint64_t, v8udi, 1)
DEF_EXTRACT (uint64_t, v16udi, 1)
DEF_EXTRACT (uint64_t, v32udi, 1)
DEF_EXTRACT (uint64_t, v64udi, 1)
DEF_EXTRACT (uint64_t, v128udi, 1)
DEF_EXTRACT (uint64_t, v256udi, 1)
DEF_EXTRACT (uint64_t, v512udi, 1)
DEF_EXTRACT (_Float16, v2hf, 1)
DEF_EXTRACT (_Float16, v4hf, 1)
DEF_EXTRACT (_Float16, v8hf, 1)
DEF_EXTRACT (_Float16, v16hf, 1)
DEF_EXTRACT (_Float16, v32hf, 1)
DEF_EXTRACT (_Float16, v64hf, 1)
DEF_EXTRACT (_Float16, v128hf, 1)
DEF_EXTRACT (_Float16, v256hf, 1)
DEF_EXTRACT (_Float16, v512hf, 1)
DEF_EXTRACT (_Float16, v1024hf, 1)
DEF_EXTRACT (_Float16, v2048hf, 1)
DEF_EXTRACT (float, v2sf, 1)
DEF_EXTRACT (float, v4sf, 1)
DEF_EXTRACT (float, v8sf, 1)
DEF_EXTRACT (float, v16sf, 1)
DEF_EXTRACT (float, v32sf, 1)
DEF_EXTRACT (float, v64sf, 1)
DEF_EXTRACT (float, v128sf, 1)
DEF_EXTRACT (float, v256sf, 1)
DEF_EXTRACT (float, v512sf, 1)
DEF_EXTRACT (float, v1024sf, 1)
DEF_EXTRACT (double, v2df, 1)
DEF_EXTRACT (double, v4df, 1)
DEF_EXTRACT (double, v8df, 1)
DEF_EXTRACT (double, v16df, 1)
DEF_EXTRACT (double, v32df, 1)
DEF_EXTRACT (double, v64df, 1)
DEF_EXTRACT (double, v128df, 1)
DEF_EXTRACT (double, v256df, 1)
DEF_EXTRACT (double, v512df, 1)
/* { dg-final { scan-assembler-times {vmv\.x\.s} 84 } } */
/* { dg-final { scan-assembler-times {vfmv\.f\.s} 30 } } */
/* { dg-final { scan-assembler-times {vslidedown.vi} 114 } } */