From 9aa42ac8c636a9bdc288cdb3ade6da75ad1f2c4d Mon Sep 17 00:00:00 2001
From: Kuan-Lin Chen <rufus@atccpl09.andestech.com>
Date: Wed, 30 Oct 2024 15:08:14 +0800
Subject: [PATCH 2/3] Add one more argument to simulate_builtin_function_decl.

simulate_builtin_function_decl may return decl that be ggc_freed already
in pushdecl when duplicate_decls is true. Add a argument CREATE_P for
the caller to know if the return decl is usable.

gcc/ChangeLog:

	* langhooks.h (simulate_builtin_function_decl):
	Add one more argument.
	* langhooks.cc (simulate_builtin_function_decl): Ditto.
	* config/aarch64/aarch64-builtins.cc
	(aarch64_general_simulate_builtin):
	Add one more argument to fit simulate_builtin_function_decl.
	(aarch64_init_simd_builtin_functions): Ditto.
	* config/aarch64/aarch64-sve-builtins.cc
	(function_builder::add_function): Ditto.
	* config/arm/arm-mve-builtins.cc
	(function_builder::add_function): Ditto.
	* config/riscv/riscv-vector-builtins.cc
	(function_builder::add_function): Ditto.
---
 gcc/config/aarch64/aarch64-builtins.cc     | 10 +++++++---
 gcc/config/aarch64/aarch64-sve-builtins.cc |  3 ++-
 gcc/config/arm/arm-mve-builtins.cc         |  3 ++-
 gcc/config/riscv/riscv-vector-builtins.cc  |  8 ++++++--
 gcc/langhooks.cc                           | 12 +++++++++---
 gcc/langhooks.h                            |  2 +-
 6 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc
index 86d96e47f01..ca54d955980 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -1031,9 +1031,10 @@ aarch64_general_simulate_builtin (const char *name, tree fntype,
 				  unsigned int code,
 				  tree attrs = NULL_TREE)
 {
+  bool create_p;
   code = (code << AARCH64_BUILTIN_SHIFT) | AARCH64_BUILTIN_GENERAL;
   return simulate_builtin_function_decl (input_location, name, fntype,
-					 code, NULL, attrs);
+					 code, NULL, attrs, &create_p);
 }
 
 static const char *
@@ -1439,6 +1440,7 @@ void
 aarch64_init_simd_intrinsics (void)
 {
   unsigned int i = 0;
+  bool create_p;
 
   for (i = 0; i < ARRAY_SIZE (aarch64_simd_intrinsic_data); ++i)
     {
@@ -1468,7 +1470,8 @@ aarch64_init_simd_intrinsics (void)
       unsigned int code
 	      = (d->fcode << AARCH64_BUILTIN_SHIFT | AARCH64_BUILTIN_GENERAL);
       tree fndecl = simulate_builtin_function_decl (input_location, d->name,
-						    ftype, code, NULL, attrs);
+						    ftype, code, NULL, attrs,
+						    &create_p);
       aarch64_builtin_decls[d->fcode] = fndecl;
     }
 }
@@ -1583,11 +1586,12 @@ aarch64_init_simd_builtin_functions (bool called_from_pragma)
 
       if (called_from_pragma)
 	{
+	  bool create_p;
 	  unsigned int raw_code
 		= (fcode << AARCH64_BUILTIN_SHIFT) | AARCH64_BUILTIN_GENERAL;
 	  fndecl = simulate_builtin_function_decl (input_location, namebuf,
 						   ftype, raw_code, NULL,
-						   attrs);
+						   attrs, &create_p);
 	}
       else
 	fndecl = aarch64_general_add_builtin (namebuf, ftype, fcode, attrs);
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index ef14f8cd39d..99dff877f4d 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -1463,6 +1463,7 @@ function_builder::add_function (const function_instance &instance,
 {
   unsigned int length = vec_safe_length (registered_functions);
   unsigned int code = (m_function_index << AARCH64_BUILTIN_SHIFT) | AARCH64_BUILTIN_SVE;
+  bool create_p;
   /* We need to be able to generate placeholders to enusre that we have a
      consistent numbering scheme for function codes between the C and C++
      frontends, so that everything ties up in LTO.
@@ -1479,7 +1480,7 @@ function_builder::add_function (const function_instance &instance,
   tree decl = placeholder_p || m_function_nulls
     ? integer_zero_node
     : simulate_builtin_function_decl (input_location, name, fntype,
-				      code, NULL, attrs);
+				      code, NULL, attrs, &create_p);
 
   registered_function &rfn = *ggc_alloc <registered_function> ();
   rfn.instance = instance;
diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc
index af1908691b6..ff98db7c158 100644
--- a/gcc/config/arm/arm-mve-builtins.cc
+++ b/gcc/config/arm/arm-mve-builtins.cc
@@ -934,6 +934,7 @@ function_builder::add_function (const function_instance &instance,
 {
   unsigned int code = vec_safe_length (registered_functions);
   code = (code << ARM_BUILTIN_SHIFT) | ARM_BUILTIN_MVE;
+  bool create_p;
 
   /* We need to be able to generate placeholders to ensure that we have a
      consistent numbering scheme for function codes between the C and C++
@@ -951,7 +952,7 @@ function_builder::add_function (const function_instance &instance,
   tree decl = placeholder_p
     ? integer_zero_node
     : simulate_builtin_function_decl (input_location, name, fntype,
-				      code, NULL, attrs);
+				      code, NULL, attrs, &create_p);
   registered_function &rfn = *ggc_alloc <registered_function> ();
   rfn.instance = instance;
   rfn.decl = decl;
diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc
index 084aad89733..bb4baf1d8f5 100644
--- a/gcc/config/riscv/riscv-vector-builtins.cc
+++ b/gcc/config/riscv/riscv-vector-builtins.cc
@@ -3772,6 +3772,7 @@ function_builder::add_function (const function_instance &instance,
 {
   unsigned int code = vec_safe_length (registered_functions);
   code = (code << RISCV_BUILTIN_SHIFT) + RISCV_BUILTIN_VECTOR;
+  bool create_p = false;
 
   /* We need to be able to generate placeholders to ensure that we have a
      consistent numbering scheme for function codes between the C and C++
@@ -3789,11 +3790,14 @@ function_builder::add_function (const function_instance &instance,
   tree decl = placeholder_p
 		? integer_zero_node
 		: simulate_builtin_function_decl (input_location, name, fntype,
-						  code, NULL, attrs);
+						  code, NULL, attrs, &create_p);
 
   registered_function &rfn = *ggc_alloc<registered_function> ();
   rfn.instance = instance;
-  rfn.decl = decl;
+  if (create_p)
+    rfn.decl = decl;
+  else
+    rfn.decl = integer_zero_node;
   rfn.overload_name = overload_name ? xstrdup (overload_name) : NULL;
   rfn.argument_types = argument_types;
   rfn.overloaded_p = overloaded_p;
diff --git a/gcc/langhooks.cc b/gcc/langhooks.cc
index fe32be44956..e3af6a350a2 100644
--- a/gcc/langhooks.cc
+++ b/gcc/langhooks.cc
@@ -786,16 +786,19 @@ add_builtin_function_ext_scope (const char *name,
    location LOCATION, as though it had been declared directly in the
    source language.  NAME is the name of the function, TYPE is its function
    type, FUNCTION_CODE is the target-specific function code, LIBRARY_NAME
-   is the name of the underlying library function (NULL if none) and
-   ATTRS is a list of function attributes.
+   is the name of the underlying library function (NULL if none),
+   ATTRS is a list of function attributes and CREATE_P is true if the new_decl
+   is created successfully.
 
    Return the decl of the declared function.  */
 
 tree
 simulate_builtin_function_decl (location_t location, const char *name,
 				tree type, int function_code,
-				const char *library_name, tree attrs)
+				const char *library_name, tree attrs,
+				bool *create_p)
 {
+  *create_p = false;
   tree decl = build_builtin_function (location, name, type,
 				      function_code, BUILT_IN_MD,
 				      library_name, attrs);
@@ -808,7 +811,10 @@ simulate_builtin_function_decl (location_t location, const char *name,
      normally, even though the source code won't be able to use it.  */
   if (TREE_CODE (new_decl) == FUNCTION_DECL
       && fndecl_built_in_p (new_decl, function_code, BUILT_IN_MD))
+  {
+    *create_p = true;
     return new_decl;
+  }
 
   return decl;
 }
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 9a559d92779..69eee39b86f 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -676,7 +676,7 @@ extern tree add_builtin_function_ext_scope (const char *name, tree type,
 					    const char *library_name,
 					    tree attrs);
 extern tree simulate_builtin_function_decl (location_t, const char *, tree,
-					    int, const char *, tree);
+					    int, const char *, tree, bool *);
 extern tree add_builtin_type (const char *name, tree type);
 
 /* Language helper functions.  */
-- 
2.43.5

