https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120146
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Component|tree-optimization |ipa CC| |hubicka at gcc dot gnu.org Ever confirmed|0 |1 Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org Last reconfirmed| |2025-05-07 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- I'd guess openacc creates a global but does not create a varpool node for it and thus varpool_node *vnode = varpool_node::get (decl); /* For escaped variables initialize them from nonlocal. */ if (!vnode->all_refs_explicit_p ()) make_copy_constraint (vi, nonlocal_id); gets a NULL vnode. Hmm, the decl is $1 = <var_decl 0x7ffff6fe8390 _ZTV14basic_ifstreamIcE> <var_decl 0x7ffff6fe8390 _ZTV14basic_ifstreamIcE ... readonly addressable used public static tree_1 tree_2 ignored external read virtual decl_5 decl_8 BLK t.c:5:28 size <integer_cst 0x7ffff6e20708 192> unit-size <integer_cst 0x7ffff6e206d8 24> which is referenced from the CONSTRUCTOR {&MEM <int (*) ()> [(void *)&_ZTV14basic_ifstreamIcE + 24B], &MEM <int (*) ()> [(void *)&_ZTC14basic_ifstreamIcE0_13basic_istream + 24B]} of $5 = <varpool_node * 0x7ffff6e26880 "_ZTT14basic_ifstreamIcE"/16> and -fopenacc simply enables early IPA PTA it seems: PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc) NEXT_PASS (pass_ipa_pta); /* Pass group that runs when the function is an offloaded function containing oacc kernels loops. */ NEXT_PASS (pass_ipa_oacc_kernels); ... Likely caused by my fix for PR119973. I'm not sure why the variables referenced in the global var initializer are not finalized? I see _ZTT14basic_ifstreamIcE/17 (constexpr const void* basic_ifstream<char>::_ZTT14basic_ifstreamIcE [2]) Type: variable definition analyzed Visibility: semantic_interposition external public virtual artificial Aux: @0x4f8c200 References: _ZTV14basic_ifstreamIcE/8 (addr) _ZTC14basic_ifstreamIcE0_13basic_istream/20 (addr) But at the time IPA PTA runs the symbol is elided, but the reference through the CTOR is still there? That is, DECL_INITIAL isn't pruned? At the IPA PTA point the variable refering to the elided node is _ZTT14basic_ifstreamIcE/17 (constexpr const void* basic_ifstream<char>::_ZTT14basic_ifstreamIcE [2]) Type: variable Body removed by symtab_remove_unreachable_nodes Visibility: externally_visible semantic_interposition external public virtual artificial References: Referring: _Z18CompareFiles_path2v/7 (read) Availability: not_available Varpool flags: initialized read-only const-value-known so it's const-value-known, but it no longer has references (from said initializer) and it's not_available, whatever that means. IPA PTA in it's walk over globals still does the following, not sure if it should skip some variables. The one in question has !var->analyzed for example, for whatever reason. /* Create constraints for global variables and their initializers. */ FOR_EACH_VARIABLE (var) { if (var->alias && var->analyzed) continue; varinfo_t vi = get_vi_for_tree (var->decl); /* For the purpose of IPA PTA unit-local globals are not escape points. */ bool nonlocal_p = (DECL_EXTERNAL (var->decl) || TREE_PUBLIC (var->decl) || var->used_from_other_partition || var->force_output); var->call_for_symbol_and_aliases (refered_from_nonlocal_var, &nonlocal_p, true); if (nonlocal_p) vi->is_ipa_escape_point = true; } Not processing globals with !var->analyzed does not help since we still refer to those from the IL (CompareFiles_path2): # VUSE <.MEM_2> _4 = MEM[(const void * *)&_ZTT14basic_ifstreamIcE + 8B]; so why was the varpool node "elided"? Or why is it not analyzed/available? I'm confused. I can paper over the ICE by simply "dealing" with a NULL varpool node but I think this is just playing whack-a-mole without understanding what IPA does here :/ "Fix:" diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc index 3ad0c69930c..1a6522593ba 100644 --- a/gcc/tree-ssa-structalias.cc +++ b/gcc/tree-ssa-structalias.cc @@ -6562,7 +6562,7 @@ create_variable_info_for (tree decl, const char *name, bool add_id) varpool_node *vnode = varpool_node::get (decl); /* For escaped variables initialize them from nonlocal. */ - if (!vnode->all_refs_explicit_p ()) + if (!vnode || !vnode->all_refs_explicit_p ()) make_copy_constraint (vi, nonlocal_id); /* While we can in theory walk references for the varpool @@ -6581,7 +6581,7 @@ create_variable_info_for (tree decl, const char *name, bool add_id) process_constraint (new_constraint (lhs, *rhsp)); /* If this is a variable that escapes from the unit the initializer escapes as well. */ - if (!vnode->all_refs_explicit_p ()) + if (!vnode || !vnode->all_refs_explicit_p ()) { lhs.var = escaped_id; lhs.offset = 0;