From: Ju-Zhe Zhong
gcc/ChangeLog:
* config/riscv/constraints.md (Wdm): New constraint.
* config/riscv/predicates.md (direct_broadcast_operand): New predicate.
* config/riscv/riscv-protos.h (RVV_VLMAX): New macro.
(emit_pred_op): Refine function.
* config/riscv/riscv-selftests.cc (run_const_vector_selftests): New
function.
(run_broadcast_selftests): Ditto.
(BROADCAST_TEST): New tests.
(riscv_run_selftests): More tests.
* config/riscv/riscv-v.cc (emit_pred_move): Refine function.
(emit_vlmax_vsetvl): Ditto.
(emit_pred_op): Ditto.
(expand_const_vector): New function.
(legitimize_move): Add constant vector support.
* config/riscv/riscv.cc (riscv_print_operand): New asm print rule for
const vector.
* config/riscv/riscv.h (X0_REGNUM): New macro.
* config/riscv/vector-iterators.md: New attribute.
* config/riscv/vector.md (vec_duplicate): New pattern.
(@pred_broadcast): New pattern.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/base/dup-1.c: New test.
* gcc.target/riscv/rvv/base/dup-2.c: New test.
---
gcc/config/riscv/constraints.md | 5 +
gcc/config/riscv/predicates.md| 5 +
gcc/config/riscv/riscv-protos.h | 2 +
gcc/config/riscv/riscv-selftests.cc | 127 +
gcc/config/riscv/riscv-v.cc | 86 ++-
gcc/config/riscv/riscv.cc | 13 +
gcc/config/riscv/riscv.h | 3 +
gcc/config/riscv/vector-iterators.md | 9 +
gcc/config/riscv/vector.md| 53 +-
.../gcc.target/riscv/rvv/base/dup-1.c | 521 ++
.../gcc.target/riscv/rvv/base/dup-2.c | 75 +++
11 files changed, 881 insertions(+), 18 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/dup-1.c
create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/dup-2.c
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md
index 4088c48150a..51cffb2bcb6 100644
--- a/gcc/config/riscv/constraints.md
+++ b/gcc/config/riscv/constraints.md
@@ -151,3 +151,8 @@
A constraint that matches a vector of immediate all ones."
(and (match_code "const_vector")
(match_test "op == CONSTM1_RTX (GET_MODE (op))")))
+
+(define_constraint "Wdm"
+ "Vector duplicate memory operand"
+ (and (match_operand 0 "memory_operand")
+ (match_code "reg" "0")))
diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index dfd98761b8b..5a5a49bf7c0 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -286,6 +286,11 @@
(match_test "GET_CODE (op) == UNSPEC
&& (XINT (op, 1) == UNSPEC_VUNDEF)"
+;; The scalar operand can be directly broadcast by RVV instructions.
+(define_predicate "direct_broadcast_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_test "satisfies_constraint_Wdm (op)")))
+
;; A CONST_INT operand that has exactly two bits cleared.
(define_predicate "const_nottwobits_operand"
(and (match_code "const_int")
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 2ec3af05aa4..27692ffb210 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -119,6 +119,7 @@ extern void riscv_run_selftests (void);
#endif
namespace riscv_vector {
+#define RVV_VLMAX gen_rtx_REG (Pmode, X0_REGNUM)
/* Routines implemented in riscv-vector-builtins.cc. */
extern void init_builtins (void);
extern const char *mangle_builtin_type (const_tree);
@@ -130,6 +131,7 @@ extern tree builtin_decl (unsigned, bool);
extern rtx expand_builtin (unsigned int, tree, rtx);
extern bool const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
extern bool legitimize_move (rtx, rtx, machine_mode);
+extern void emit_pred_op (unsigned, rtx, rtx, machine_mode);
enum tail_policy
{
TAIL_UNDISTURBED = 0,
diff --git a/gcc/config/riscv/riscv-selftests.cc
b/gcc/config/riscv/riscv-selftests.cc
index 636874ebc0f..1bf1a648fa1 100644
--- a/gcc/config/riscv/riscv-selftests.cc
+++ b/gcc/config/riscv/riscv-selftests.cc
@@ -33,6 +33,9 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "selftest.h"
#include "selftest-rtl.h"
+#include "insn-attr.h"
+#include "target.h"
+#include "optabs.h"
#if CHECKING_P
using namespace selftest;
@@ -230,12 +233,136 @@ run_poly_int_selftests (void)
run_poly_int_selftest ("rv32imafd_zve32x1p0", ABI_ILP32D, POLY_TEST_DIMODE,
worklist);
}
+
+static void
+run_const_vector_selftests (void)
+{
+ /* We dont't need to do the redundant tests in different march && mabi.
+ Just pick up the march && mabi which fully support all RVV modes. */
+ riscv_selftest_arch_abi_setter rv ("rv64imafdcv", ABI_LP64D);
+ rtl_dump_test t (SELFTEST_LOCATION, locate_file ("riscv/emp