From f04a78f09f9ea06189603e62481550e544b41aa1 Mon Sep 17 00:00:00 2001
From: Kuan-Lin Chen <rufus@andestech.com>
Date: Wed, 16 Oct 2024 15:57:05 +0800
Subject: [PATCH 3/3] RISC-V: Fix rvv builtin function groups registration
 asynchronously.

In the origin, cc1 registers rvv builtins with turn on all sub vector
extensions but lto not.  It makes lto use the asynchronous DECL_MD_FUNCTION_CODE
from lto-objects.

Example:
riscv64-unknown-elf-gcc -flto gcc/testsuite/gcc.target/riscv/rvv/base/bug-10.c
-O2 -march=rv64gcv

bug-10.c: In function 'main':
bug-10.c:10:3: error: invalid argument to built-in function
   10 |   __riscv_vse32_v_i32m1 (d, vd, 1);

gcc/ChangeLog:

	* config/riscv/riscv-c.cc
	(riscv_pragma_intrinsic_flags_pollute): Move to
	riscv-vector-builtins.cc
	(riscv_pragma_intrinsic_flags_restore): Ditto
	(riscv_ext_version_value): Remove flags initialization.
	* config/riscv/riscv-vector-builtins.cc:
	(reinit_builtins): Remove handle_pragma_vector in lto_p.
	(riscv_pragma_intrinsic_flags_pollute): Cut from riscv-c.cc.
	(riscv_pragma_intrinsic_flags_restore): Ditto.
	(riscv_vector_push_setting): Backup flags.
	(riscv_vector_pop_setting): Restore flags.
	(handle_pragma_vector): Intialize flags for registering
	builtins.
---
 gcc/config/riscv/riscv-c.cc               |  88 +------------------
 gcc/config/riscv/riscv-vector-builtins.cc | 101 +++++++++++++++++++++-
 2 files changed, 99 insertions(+), 90 deletions(-)

diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc
index c59f408d3a8..268a1fe7c2e 100644
--- a/gcc/config/riscv/riscv-c.cc
+++ b/gcc/config/riscv/riscv-c.cc
@@ -34,77 +34,6 @@ along with GCC; see the file COPYING3.  If not see
 
 #define builtin_define(TXT) cpp_define (pfile, TXT)
 
-struct pragma_intrinsic_flags
-{
-  int intrinsic_target_flags;
-
-  int intrinsic_riscv_vector_elen_flags;
-  int intrinsic_riscv_zvl_flags;
-  int intrinsic_riscv_zvb_subext;
-  int intrinsic_riscv_zvk_subext;
-};
-
-static void
-riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
-{
-  flags->intrinsic_target_flags = target_flags;
-  flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
-  flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
-  flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
-  flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
-
-  target_flags = target_flags
-    | MASK_VECTOR;
-
-  riscv_zvl_flags = riscv_zvl_flags
-    | MASK_ZVL32B
-    | MASK_ZVL64B
-    | MASK_ZVL128B
-    | MASK_ZVL256B
-    | MASK_ZVL512B
-    | MASK_ZVL1024B
-    | MASK_ZVL2048B
-    | MASK_ZVL4096B;
-
-  riscv_vector_elen_flags = riscv_vector_elen_flags
-    | MASK_VECTOR_ELEN_32
-    | MASK_VECTOR_ELEN_64
-    | MASK_VECTOR_ELEN_FP_16
-    | MASK_VECTOR_ELEN_FP_32
-    | MASK_VECTOR_ELEN_FP_64;
-
-  riscv_zvb_subext = riscv_zvb_subext
-    | MASK_ZVBB
-    | MASK_ZVBC
-    | MASK_ZVKB;
-
-  riscv_zvk_subext = riscv_zvk_subext
-    | MASK_ZVKG
-    | MASK_ZVKNED
-    | MASK_ZVKNHA
-    | MASK_ZVKNHB
-    | MASK_ZVKSED
-    | MASK_ZVKSH
-    | MASK_ZVKN
-    | MASK_ZVKNC
-    | MASK_ZVKNG
-    | MASK_ZVKS
-    | MASK_ZVKSC
-    | MASK_ZVKSG
-    | MASK_ZVKT;
-}
-
-static void
-riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
-{
-  target_flags = flags->intrinsic_target_flags;
-
-  riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
-  riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
-  riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
-  riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
-}
-
 static int
 riscv_ext_version_value (unsigned major, unsigned minor)
 {
@@ -271,22 +200,7 @@ riscv_pragma_intrinsic (cpp_reader *)
 
   if (strcmp (name, "vector") == 0
       || strcmp (name, "xtheadvector") == 0)
-    {
-      struct pragma_intrinsic_flags backup_flags;
-
-      riscv_pragma_intrinsic_flags_pollute (&backup_flags);
-
-      riscv_option_override ();
-      init_adjust_machine_modes ();
-      riscv_vector::reinit_builtins ();
-      riscv_vector::handle_pragma_vector ();
-
-      riscv_pragma_intrinsic_flags_restore (&backup_flags);
-
-      /* Re-initialize after the flags are restored.  */
-      riscv_option_override ();
-      init_adjust_machine_modes ();
-    }
+    riscv_vector::handle_pragma_vector ();
   else
     error ("unknown %<#pragma riscv intrinsic%> option %qs", name);
 }
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index bb4baf1d8f5..fd964bcd84b 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -129,6 +129,17 @@ struct non_overloaded_registered_function_hasher
   static bool equal (value_type, const compare_type &);
 };
 
+/* Structure for backuping flags.  */
+struct pragma_intrinsic_flags
+{
+  int intrinsic_target_flags;
+
+  int intrinsic_riscv_vector_elen_flags;
+  int intrinsic_riscv_zvl_flags;
+  int intrinsic_riscv_zvb_subext;
+  int intrinsic_riscv_zvk_subext;
+};
+
 /* Static information about each RVV type.  */
 static CONSTEXPR const vector_type_info vector_types[] = {
 #define DEF_RVV_TYPE(NAME, NCHARS, ABI_NAME, ARGS...)                          \
@@ -4534,9 +4545,6 @@ reinit_builtins ()
     return;
 
   register_builtin_types_on_null ();
-
-  if (in_lto_p)
-    handle_pragma_vector ();
 }
 
 /* Implement TARGET_VERIFY_TYPE_CONTEXT for RVV types.  */
@@ -4647,10 +4655,95 @@ register_frm ()
   lang_hooks.types.simulate_enum_decl (input_location, "__RISCV_FRM", &values);
 }
 
+static void
+riscv_pragma_intrinsic_flags_pollute (struct pragma_intrinsic_flags *flags)
+{
+  flags->intrinsic_target_flags = target_flags;
+  flags->intrinsic_riscv_vector_elen_flags = riscv_vector_elen_flags;
+  flags->intrinsic_riscv_zvl_flags = riscv_zvl_flags;
+  flags->intrinsic_riscv_zvb_subext = riscv_zvb_subext;
+  flags->intrinsic_riscv_zvk_subext = riscv_zvk_subext;
+
+  target_flags = target_flags
+    | MASK_VECTOR;
+
+  riscv_zvl_flags = riscv_zvl_flags
+    | MASK_ZVL32B
+    | MASK_ZVL64B
+    | MASK_ZVL128B
+    | MASK_ZVL256B
+    | MASK_ZVL512B
+    | MASK_ZVL1024B
+    | MASK_ZVL2048B
+    | MASK_ZVL4096B;
+
+  riscv_vector_elen_flags = riscv_vector_elen_flags
+    | MASK_VECTOR_ELEN_32
+    | MASK_VECTOR_ELEN_64
+    | MASK_VECTOR_ELEN_FP_16
+    | MASK_VECTOR_ELEN_FP_32
+    | MASK_VECTOR_ELEN_FP_64;
+
+  riscv_zvb_subext = riscv_zvb_subext
+    | MASK_ZVBB
+    | MASK_ZVBC
+    | MASK_ZVKB;
+
+  riscv_zvk_subext = riscv_zvk_subext
+    | MASK_ZVKG
+    | MASK_ZVKNED
+    | MASK_ZVKNHA
+    | MASK_ZVKNHB
+    | MASK_ZVKSED
+    | MASK_ZVKSH
+    | MASK_ZVKN
+    | MASK_ZVKNC
+    | MASK_ZVKNG
+    | MASK_ZVKS
+    | MASK_ZVKSC
+    | MASK_ZVKSG
+    | MASK_ZVKT;
+}
+
+static void
+riscv_pragma_intrinsic_flags_restore (struct pragma_intrinsic_flags *flags)
+{
+  target_flags = flags->intrinsic_target_flags;
+
+  riscv_vector_elen_flags = flags->intrinsic_riscv_vector_elen_flags;
+  riscv_zvl_flags = flags->intrinsic_riscv_zvl_flags;
+  riscv_zvb_subext = flags->intrinsic_riscv_zvb_subext;
+  riscv_zvk_subext = flags->intrinsic_riscv_zvk_subext;
+}
+
+static void
+riscv_vector_push_setting (struct pragma_intrinsic_flags *flags)
+{
+  riscv_pragma_intrinsic_flags_pollute (flags);
+
+  riscv_option_override ();
+  init_adjust_machine_modes ();
+  riscv_vector::reinit_builtins ();
+}
+
+static void
+riscv_vector_pop_setting (struct pragma_intrinsic_flags *flags)
+{
+  riscv_pragma_intrinsic_flags_restore (flags);
+
+  /* Re-initialize after the flags are restored.  */
+  riscv_option_override ();
+  init_adjust_machine_modes ();
+}
+
 /* Implement #pragma riscv intrinsic vector.  */
 void
 handle_pragma_vector ()
 {
+  struct pragma_intrinsic_flags backup_flags;
+
+  riscv_vector_push_setting (&backup_flags);
+
   if (function_table || non_overloaded_function_table)
     {
       error ("duplicate definition of %qs", "riscv_vector.h");
@@ -4676,6 +4769,8 @@ handle_pragma_vector ()
     if (function_groups[i].match (function_groups[i].required_extensions))
       builder.register_function_group (function_groups[i]);
   }
+
+  riscv_vector_pop_setting (&backup_flags);
 }
 
 /* Return the function decl with RVV function subcode CODE, or error_mark_node
-- 
2.43.5

