]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Allow vector constants in riscv_const_insns.
authorRobin Dapp <rdapp@ventanamicro.com>
Wed, 26 Apr 2023 18:32:36 +0000 (20:32 +0200)
committerRobin Dapp <rdapp@ventanamicro.com>
Thu, 11 May 2023 14:17:34 +0000 (16:17 +0200)
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
gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv32.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-rv64.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/autovec/vmv-imm-template.h [new file with mode: 0644]

index 8f032250b0f8f2aee97eaa8a63d53716a8810484..de578b5b8999f9a61ceb4f7fc03a2f4e2eb2e90e 100644 (file)
@@ -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 (file)
index 0000000..309a296
--- /dev/null
@@ -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 <stdint.h>
+#include <assert.h>
+
+#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 (file)
index 0000000..c419256
--- /dev/null
@@ -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 (file)
index 0000000..520321e
--- /dev/null
@@ -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 (file)
index 0000000..93ba520
--- /dev/null
@@ -0,0 +1,54 @@
+#include <stdint.h>
+#include <assert.h>
+
+#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()