ipa pta: How did this .arg1 pt set get filled?
Filip Kastl
fkastl@suse.cz
Mon Jun 29 15:23:16 GMT 2026
On Mon 2026-06-29 16:02:25, Richard Biener wrote:
> On Mon, 29 Jun 2026, Filip Kastl wrote:
>
> > > On Mon, 29 Jun 2026, Filip Kastl wrote:
> > > > Ah and one more detail: I'm working with all constraints involving uses and
> > > > clobbers disabled (I don't call
> > > > gimple-ssa-pta-constraints.cc:find_func_clobbers). I'm mentioning that in case
> > > > you'd be confused that some constraints are missing.
> > > >
> > > > But the mystery of why Andersen decides to fill those sets remains.
> > > >
> > > > Filip
> > > >
> > > > On Mon 2026-06-29 11:57:49, Filip Kastl wrote:
> > > > > Hi Richi,
> > > > >
> > > > > I have another question about PTA that may or may not be related to the last
> > > > > week's question.
> > > > >
> > > > > I'm debugging a difference between what my Steensgaard-style solver and what
> > > > > GCC's Andersen-style solver compute. In particular on my testcase (gcc_r from
> > > > > 2017 SPEC CPU) Steensgaard computes these sets...
> > > > >
> > > > > ix86_encode_section_info.clobber = { }
> > > > > ix86_encode_section_info.use = { }
> > > > > ix86_encode_section_info.result = { }
> > > > > ix86_encode_section_info.arg0 = { NULL ANYTHING STRING ESCAPED N ...
> > > > > ix86_encode_section_info.arg1 = { NULL ANYTHING STRING ESCAPED N ...
> > > > > ix86_encode_section_info.arg2 = { }
> > > > >
> > > > > ...while Steensgaard computes this:
> > > > >
> > > > > ix86_encode_section_info.clobber = { NULL ANYTHING p p }
> > > > > ix86_encode_section_info.use = { NULL ANYTHING p p }
> > > > > ix86_encode_section_info.result = { NULL ANYTHING p p }
> > > > > ix86_encode_section_info.arg0 = { NULL ANYTHING p p }
> > > > > ix86_encode_section_info.arg1 = { NULL ANYTHING p p }
> > > > > ix86_encode_section_info.arg2 = { NULL ANYTHING p p }
> > > > >
> > > > > To figure out how Andersen arrived at these sets I searched the IPA PTA dump
> > > > > for constraints involving ix86_encode_section_info*. I found only these...
> > >
> > > It's been some time since I had the Andersen code swapped in my brain,
> > > so please bear with me eventually giving false hints ...
> > >
> > > > > Generating constraints for ix86_encode_section_info/332 (ix86_encode_section_info)
> > > > > _18 = *ix86_encode_section_info.arg1
> > > > > _19 = *ix86_encode_section_info.arg1 + 64
> > > > > _24 = *ix86_encode_section_info.arg0
> > > > > *_26 + 5 = ix86_encode_section_info.arg0
> > > > > _30 = *ix86_encode_section_info.arg0
> > > > > _31 = *ix86_encode_section_info.arg0 + 1165
> > > > > _32 = *ix86_encode_section_info.arg0 + 1160
> > > > > *_38 + 5 = ix86_encode_section_info.arg0
> > > > > _41 = *ix86_encode_section_info.arg0
> > > > > _44 = *ix86_encode_section_info.arg0 + 472
> > > > > _46 = *ix86_encode_section_info.arg0 + 24
> > > > > _1 = *ix86_encode_section_info.arg0
> > > > > _2 = *ix86_encode_section_info.arg0 + 24
> > > > > _4 = *ix86_encode_section_info.arg0 + 472
> > > > > _55 = *ix86_encode_section_info.arg0
> > > > > _56 = *ix86_encode_section_info.arg0 + 1024
> > > > > _60 = *ix86_encode_section_info.arg0 + 128
> > > > > _17 = *ix86_encode_section_info.arg1 + 64
> > > > >
> > > > > ...which is strange. I don't see any assigning into ix86_encode_section_info*
> > > > > nor assigning &ix86_encode_section_info* into any other set. Shouldn't then
> > > > > Andersen compute empty sets for all of these? (Although it is a good thing
> > > > > that Andersen fills those sets. Otherwise, there would be a miscompilation.
> > > > > I just want to understand what is it that my solver fails to do here.)
> > >
> > > There must be call sites of ix86_encode_section_info/332 and I'd expect
> > > those to have constraints like
> > >
> > > ix86_encode_section_info.arg0 = ...
> >
> > I don't see any constraints like this. But since the function only gets called
> > indirectly, that makes sense to me.
> >
> > > &ix86_encode_section_info itself would appear when the function is only
> > > called indirectly ...
> > >
> > > > > First explanation I came up with was expanding of ix86_encode_section_info (the
> > > > > fninfo) using '+ UNKNOWN' that we discussed last week. But
> > > > > ix86_encode_section_info is not present in any constraint at all so it cannot
> > > > > be present in any pt set and therefore it cannot get expanded this way.
> > > > >
> > > > > Note that ix86_encode_section_info is only ever called indirectly through a
> > > > > function pointer targetm.encode_section_info. That may be relevant here, I
> > > > > think.
> > >
> > > ... as you say here. It might be only visible when creating
> > > constraints for the targem initializer (a global).
> >
> > Not sure what you mean by this sentence ^. Could you expand on this a bit?
>
> targetm is initialized from
>
> struct gcc_target targetm = TARGET_INITIALIZER;
>
> in config/*/*.cc
>
> constraints for that are generated by ipa_create_global_variable_infos,
> so you should see
>
> targetm[ + N] = ...
>
> in the 'Generating constraints for global initializers' section.
Alright, makes sense. I see...
targetm = NONLOCAL
targetm = &ANYTHING
...so I believe that targetm is too big for field sensitivity.
> > > We might end up
> > > with just feeding that from NONLOCAL and thus you'd get ESCAPED
> > > at uses and ix86_encode_section_info should be escaped?
> >
> > Hm, doesn't look like ix86_encode_section_info escaped though:
> >
> > ESCAPED = { NULL ANYTHING STRING ESCAPED NONLOCAL output_object_block_htab const_desc_eq assemble_real.arg0 mark_constant object_block_entry_hash gt_pch_p_P23constant_descriptor_rtx4htab gt_pch_p_17rtx_constant_pool const_rtx_hash_1 section_entry_eq emutls_common_1 const_desc_rtx_eq section_entry_hash gt_pch_p_23constant_descriptor_rtx compute_reloc_for_rtx_1 const_desc_rtx_hash const_desc_hash object_block_entry_eq build_int_cst_wide_type.arg1 build_int_cst_wide_type.arg2 type_hash_eq gt_pch_p_P9type_hash4htab gt_pch_p_9type_hash cl_option_hash_eq cl_option_hash_hash type_hash_hash tree_map_hash tree_map_base_hash tree_map_base_eq int_cst_hash_eq int_cst_hash_hash gt_pch_p_17stack_local_entry ix86_init_machine_status extended_reg_mentioned_1 get_some_local_dynamic_name_1 dconst0 dconsthalf dconstm1 internal_label_prefix optab_table dconst1 isa_other target_other name name label tmp_label key.0+64 key.0+64 buf buf buffer x reloc flagchars ggc_calloc ggc_free in.0+64 label tmp.0+64
> x h label data body in.0+64 lhd_dwarf_name gimple_decl_printable_name lhd_set_decl_assembler_name gimple_fold_obj_type_ref mode_name_buf D.16879.0+64 D.16880.0+64 dc p code code precision in.0+64 in.0+64 in.0+64 in.0+64 in.0+64 in.0+64 in in p low1 hi d.0+32 TWO52r.0+32 half_minus_pred_half.0+32 pred_half.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 TWO52r.0+32 half_minus_pred_half.0+32 pred_half.0+32 r.0+32 inf.0+32 words use r.0+32 dstr dstr ONE16r.0+32 TWO31r.0+32 r.0+32 l xops xops name r.0+32 cur_target rperm rperm rperm rperm name xops rperm buf name } same as lookup_constant_def.result
> >
> > In fact, I don't see ix86_encode_section_info in any PT set in the dump.
>
> Do you see targetm? I suppose it's too large for field-sensitivity,
> but still.
In the other mail, you note that there is ANYTHING inside the ESCAPE set. That
got me thinking -- maybe ANYTHING (or some similar special variable) is
involved in the filling of ix86_encode_section_info.arg1? Through GDB, I've
also discovered that the filling happens because there is an edge in the
Andersen graph from STOREDANYTHING to ix86_encode_section_info.arg1. I don't
yet understand what STOREDANYTHING is used for but I've noticed that the
Steensgaard solver outputs...
STOREDANYTHING = { }
...while the Andersen solver outputs
STOREDANYTHING = { NULL ANYTHING ...
And once again, I don't see any constraints involving STOREDANYTHING. That's
explained by this code from pta-andersen.cc:
/* Add edges from STOREDANYTHING to all nodes that can receive pointers. */
t = find (storedanything_id);
for (i = integer_id + 1; i < FIRST_REF_NODE; ++i)
{
if (get_varinfo (i)->may_have_pointers)
add_graph_edge (graph, find (i), t);
}
Andersen adds edges that aren't based on any constraints and I didn't know
about this while writing Steensgaard.
Maybe this explains why ix86_encode_section_info.arg1 gets filled by Andersen
and not by Steensgaard. I'll have to look into what STOREDANYTHING is and
think about this.
Thanks for the hints,
Filip
More information about the Gcc
mailing list