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