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
}