Hi,

In r16-7312-gecc37444062b40 we allowed all vector modes for the
any_target hook.  Since then we would ICE in gcc.target/riscv/pr122051.c
as emit_move_multi_word would choose a fractional vector mode.

This patch disallows fractional vector modes for xtheadvector in
riscv_vector_mode_supported_p but makes an exception for builtin
registration (through a global variable).  During registration we
need to have all modes available in order to maintain the registration
order for LTO streaming.

Regtested on rv64gcv_zvl512b.

Regards
 Robin

        PR target/124613

gcc/ChangeLog:

        * config/riscv/riscv-vector-builtins.cc (rvv_switcher::rvv_switcher):
        Add riscv_registering_builtins.
        (rvv_switcher::~rvv_switcher): Set riscv_registering_builtins to
        false.
        * config/riscv/riscv.cc (riscv_vector_mode_supported_p): Use
        riscv_registering_builtins.
        * config/riscv/riscv.h: Declare.
---
 gcc/config/riscv/riscv-vector-builtins.cc |  7 +++++++
 gcc/config/riscv/riscv.cc                 | 15 ++++++++++++++-
 gcc/config/riscv/riscv.h                  |  1 +
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv-vector-builtins.cc 
b/gcc/config/riscv/riscv-vector-builtins.cc
index 92f343c0044..b3bce40e5bf 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3784,6 +3784,11 @@ rvv_switcher::rvv_switcher (bool pollute_flags)
       riscv_option_override ();
     }
 
+  /* Allow all vector modes during builtin registration so that
+     vector_mode_supported_p does not reject fractional LMUL modes
+     for xtheadvector.  */
+  riscv_registering_builtins = true;
+
   /* Set have_regs_of_mode before targetm.init_builtins ().  */
   memcpy (m_old_have_regs_of_mode, have_regs_of_mode,
          sizeof (have_regs_of_mode));
@@ -3803,6 +3808,8 @@ rvv_switcher::rvv_switcher (bool pollute_flags)
 
 rvv_switcher::~rvv_switcher ()
 {
+  riscv_registering_builtins = false;
+
   /* Recover back have_regs_of_mode.  */
   memcpy (have_regs_of_mode, m_old_have_regs_of_mode,
          sizeof (have_regs_of_mode));
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 67b94354c27..816b62236b8 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -356,6 +356,9 @@ poly_uint16 riscv_vector_chunks;
 /* The number of bytes in a vector chunk.  */
 unsigned riscv_bytes_per_vector_chunk;
 
+/* Whether we are currently registering builtins.  */
+bool riscv_registering_builtins;
+
 /* Index R is the smallest register class that contains register R.  */
 const enum reg_class riscv_regno_to_class[FIRST_PSEUDO_REGISTER] = {
   GR_REGS,     GR_REGS,        GR_REGS,        GR_REGS,
@@ -13458,7 +13461,17 @@ static bool
 riscv_vector_mode_supported_p (machine_mode mode)
 {
   if (TARGET_VECTOR)
-    return riscv_vector_mode_p (mode);
+    {
+      /* Avoid fractional LMUL modes for xtheadvector with the exception
+        of builtin registration time.  During registration, all modes
+        must be available so the order and numbering is consistent,
+        see PR123279.  */
+      if (TARGET_XTHEADVECTOR && !riscv_registering_builtins
+         && maybe_lt (GET_MODE_SIZE (mode), BYTES_PER_RISCV_VECTOR))
+       return false;
+
+      return riscv_vector_mode_p (mode);
+    }
 
   return false;
 }
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 195012f216b..26e5e7cd64a 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -1206,6 +1206,7 @@ extern bool riscv_user_wants_strict_align;
 extern unsigned riscv_stack_boundary;
 extern unsigned riscv_bytes_per_vector_chunk;
 extern poly_uint16 riscv_vector_chunks;
+extern bool riscv_registering_builtins;
 extern poly_int64 riscv_v_adjust_nunits (enum machine_mode, int);
 extern poly_int64 riscv_v_adjust_nunits (machine_mode, bool, int, int);
 extern poly_int64 riscv_v_adjust_precision (enum machine_mode, int);
-- 
2.53.0

Reply via email to