From 6445f1224509861f2d471a66134b98f26290586e Mon Sep 17 00:00:00 2001 From: Robin Dapp Date: Wed, 26 Apr 2023 20:32:36 +0200 Subject: [PATCH] RISC-V: Allow vector constants in riscv_const_insns. This patch adds various vector constants to riscv_const_insns in order for them to be properly recognized as immediate operands. This then allows to emit vmv.v.i instructions via autovectorization. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_const_insns): Add permissible vector constants. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c: New test. * gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c: New test. * gcc.target/riscv/rvv/autovec/vmv-imm-template.h: New test. * gcc.target/riscv/rvv/autovec/vmv-imm-run.c: New test. --- gcc/config/riscv/riscv.cc | 7 +++ .../gcc.target/riscv/rvv/autovec/vmv-imm-run.c | 57 ++++++++++++++++++++++ .../gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c | 6 +++ .../gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c | 6 +++ .../riscv/rvv/autovec/vmv-imm-template.h | 54 ++++++++++++++++++++ 5 files changed, 130 insertions(+) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-run.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-template.h diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 8f032250b0f..de578b5b899 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -1291,6 +1291,13 @@ riscv_const_insns (rtx x) return 1; } } + /* Constants from -16 to 15 can be loaded with vmv.v.i. + The Wc0, Wc1 constraints are already covered by the + vi constraint so we do not need to check them here + separately. */ + else if (TARGET_VECTOR && satisfies_constraint_vi (x)) + return 1; + /* TODO: We may support more const vector in the future. */ return x == CONST0_RTX (GET_MODE (x)) ? 1 : 0; } diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-run.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-run.c new file mode 100644 index 00000000000..309a296b686 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-run.c @@ -0,0 +1,57 @@ +/* { dg-do run { target { riscv_vector } } } */ +/* { dg-additional-options "-std=c99 -fno-vect-cost-model --param=riscv-autovec-preference=scalable -fno-builtin" } */ + +#include "vmv-imm-template.h" + +#include +#include + +#define SZ 512 + +#define TEST_POS(TYPE,VAL) \ + TYPE a##TYPE##VAL[SZ]; \ + vmv_##VAL (a##TYPE##VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (a##TYPE##VAL[i] == VAL); + +#define TEST_NEG(TYPE,VAL) \ + TYPE am##TYPE##VAL[SZ]; \ + vmv_m##VAL (am##TYPE##VAL, SZ); \ + for (int i = 0; i < SZ; i++) \ + assert (am##TYPE##VAL[i] == -VAL); + +int main () +{ + TEST_NEG(int8_t, 16) + TEST_NEG(int8_t, 15) + TEST_NEG(int8_t, 14) + TEST_NEG(int8_t, 13) + TEST_NEG(int16_t, 12) + TEST_NEG(int16_t, 11) + TEST_NEG(int16_t, 10) + TEST_NEG(int16_t, 9) + TEST_NEG(int32_t, 8) + TEST_NEG(int32_t, 7) + TEST_NEG(int32_t, 6) + TEST_NEG(int32_t, 5) + TEST_NEG(int64_t, 4) + TEST_NEG(int64_t, 3) + TEST_NEG(int64_t, 2) + TEST_NEG(int64_t, 1) + TEST_POS(uint8_t, 0) + TEST_POS(uint8_t, 1) + TEST_POS(uint8_t, 2) + TEST_POS(uint8_t, 3) + TEST_POS(uint16_t, 4) + TEST_POS(uint16_t, 5) + TEST_POS(uint16_t, 6) + TEST_POS(uint16_t, 7) + TEST_POS(uint32_t, 8) + TEST_POS(uint32_t, 9) + TEST_POS(uint32_t, 10) + TEST_POS(uint32_t, 11) + TEST_POS(uint64_t, 12) + TEST_POS(uint64_t, 13) + TEST_POS(uint64_t, 14) + TEST_POS(uint64_t, 15) +} diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c new file mode 100644 index 00000000000..c419256cd45 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv32gcv -mabi=ilp32d -fno-vect-cost-model --param=riscv-autovec-preference=scalable -fno-builtin" } */ + +#include "vmv-imm-template.h" + +/* { dg-final { scan-assembler-times "vmv.v.i" 32 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c new file mode 100644 index 00000000000..520321e1c73 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c99 -march=rv64gcv -fno-vect-cost-model --param=riscv-autovec-preference=scalable -fno-builtin" } */ + +#include "vmv-imm-template.h" + +/* { dg-final { scan-assembler-times "vmv.v.i" 32 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-template.h b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-template.h new file mode 100644 index 00000000000..93ba5204c2e --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-template.h @@ -0,0 +1,54 @@ +#include +#include + +#define VMV_POS(TYPE,VAL) \ + __attribute__ ((noipa)) \ + void vmv_##VAL (TYPE dst[], int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = VAL; \ + } + +#define VMV_NEG(TYPE,VAL) \ + __attribute__ ((noipa)) \ + void vmv_m##VAL (TYPE dst[], int n) \ + { \ + for (int i = 0; i < n; i++) \ + dst[i] = -VAL; \ + } + +#define TEST_ALL() \ +VMV_NEG(int8_t,16) \ +VMV_NEG(int8_t,15) \ +VMV_NEG(int8_t,14) \ +VMV_NEG(int8_t,13) \ +VMV_NEG(int16_t,12) \ +VMV_NEG(int16_t,11) \ +VMV_NEG(int16_t,10) \ +VMV_NEG(int16_t,9) \ +VMV_NEG(int32_t,8) \ +VMV_NEG(int32_t,7) \ +VMV_NEG(int32_t,6) \ +VMV_NEG(int32_t,5) \ +VMV_NEG(int64_t,4) \ +VMV_NEG(int64_t,3) \ +VMV_NEG(int64_t,2) \ +VMV_NEG(int64_t,1) \ +VMV_POS(uint8_t,0) \ +VMV_POS(uint8_t,1) \ +VMV_POS(uint8_t,2) \ +VMV_POS(uint8_t,3) \ +VMV_POS(uint16_t,4) \ +VMV_POS(uint16_t,5) \ +VMV_POS(uint16_t,6) \ +VMV_POS(uint16_t,7) \ +VMV_POS(uint32_t,8) \ +VMV_POS(uint32_t,9) \ +VMV_POS(uint32_t,10) \ +VMV_POS(uint32_t,11) \ +VMV_POS(uint64_t,12) \ +VMV_POS(uint64_t,13) \ +VMV_POS(uint64_t,14) \ +VMV_POS(uint64_t,15) + +TEST_ALL() -- 2.11.4.GIT