Richard Biener wrote:
On Wed, 9 Sep 2026, Tobias Burnus wrote:

This failed as no varpool_node was available when needed and,
as for some reason, the same decl appeared multiple times
in the FOR_EACH_VARIABLE loop. - For some reasons, and possibly
related to VALUE_EXPR, IPA also decided that it could remove that
node - even though it was used. (It worked at -O0)
Well, because you add variables by creating a varpool node
while looping over the symtab?  I don't think this is safe.
May I suggest to create a worklist for the varpool creation part?

Otherwise, well, I suppose it makes sense.

I concur that it makes sense  not to modify the varpool while
walking it. However, the same DECL still occurs multiple times.

With the following incremental patch (diff -w), I still get for
libgomp.c/usm_env_handling-1-self.c:

lto1: warning: »A«, 0x7f39b6efc100, 0x7f39b6f02000
lto1: warning: »A«, 0x7f39b6efc100, 0x7f39b6f02000
lto1: warning: »A« (»(*A$linkptr)«), 0x7f39b6efc100, 0x7f39b6f02000

That is: The same node appears multiple times in FOR_EACH_VARIABLE,
such that the 'if' condition is still required.

Thus, I intent to commit the attached (incremental) patch.
(Same as the diff below, except for re-indenting and without warning
calls.)

(diff -w with debug 'warning' calls:)
--- a/gcc/lto/lto.cc
+++ b/gcc/lto/lto.cc
@@ -482,13 +482,23 @@ static void
 offload_handle_link_vars (void)
 {
 #ifdef ACCEL_COMPILER
+  size_t i;
   varpool_node *var;
+  auto_vec <varpool_node *>temp_link_vars;
   FOR_EACH_VARIABLE (var)
     if (lookup_attribute ("omp declare target link",
                          DECL_ATTRIBUTES (var->decl)))
+{
+      temp_link_vars.safe_push (var);
+warning(0, "%qD, %p, %p", var->decl, (void*) var, (void *) var->decl);
+}
+  FOR_EACH_VEC_ELT (temp_link_vars, i, var)
     {
+      /* For some reasons, the same varpool node can appear multiple times.  */
       if (DECL_HAS_VALUE_EXPR_P (var->decl))
+       {
+         warning(0, "%qD (%qE), %p, %p", var->decl, DECL_VALUE_EXPR (var->decl), 
(void*) var, (void *) var->decl);
          continue;
+       }
       tree type = build_pointer_type (TREE_TYPE (var->decl));
       tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
                                        clone_function_name (var->decl,


Tobias
 gcc/lto/lto.cc | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/gcc/lto/lto.cc b/gcc/lto/lto.cc
index d22827bbcc0..cf470c73195 100644
--- a/gcc/lto/lto.cc
+++ b/gcc/lto/lto.cc
@@ -482,27 +482,32 @@ static void
 offload_handle_link_vars (void)
 {
 #ifdef ACCEL_COMPILER
+  size_t i;
   varpool_node *var;
+  auto_vec <varpool_node *>temp_link_vars;
   FOR_EACH_VARIABLE (var)
     if (lookup_attribute ("omp declare target link",
 			  DECL_ATTRIBUTES (var->decl)))
-      {
-	if (DECL_HAS_VALUE_EXPR_P (var->decl))
-	  continue;
-	tree type = build_pointer_type (TREE_TYPE (var->decl));
-	tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+      temp_link_vars.safe_push (var);
+  FOR_EACH_VEC_ELT (temp_link_vars, i, var)
+    {
+      /* For some reasons, the same varpool node can appear multiple times.  */
+      if (DECL_HAS_VALUE_EXPR_P (var->decl))
+	continue;
+      tree type = build_pointer_type (TREE_TYPE (var->decl));
+      tree link_ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
 					clone_function_name (var->decl,
 							     "linkptr"), type);
-	TREE_USED (link_ptr_var) = 1;
-	TREE_STATIC (link_ptr_var) = 1;
-	TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
-	DECL_ARTIFICIAL (link_ptr_var) = 1;
-	SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
-	SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
-	DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
-	varpool_node::finalize_decl (link_ptr_var);
-	varpool_node::get (link_ptr_var)->force_output = var->force_output;
-      }
+      TREE_USED (link_ptr_var) = 1;
+      TREE_STATIC (link_ptr_var) = 1;
+      TREE_PUBLIC (link_ptr_var) = TREE_PUBLIC (var->decl);
+      DECL_ARTIFICIAL (link_ptr_var) = 1;
+      SET_DECL_ASSEMBLER_NAME (link_ptr_var, DECL_NAME (link_ptr_var));
+      SET_DECL_VALUE_EXPR (var->decl, build_simple_mem_ref (link_ptr_var));
+      DECL_HAS_VALUE_EXPR_P (var->decl) = 1;
+      varpool_node::finalize_decl (link_ptr_var);
+      varpool_node::get (link_ptr_var)->force_output = var->force_output;
+    }
 #endif
 }
 

Reply via email to