> Am 29.06.2026 um 17:25 schrieb Filip Kastl <[email protected]>:
> 
> 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.

It is when ANYTHING is on the LHS.  Above means you have a *ANYTHING = ANYTHING 
constraint which is pretty bad quality wise.  We don’t want to explicitly 
manage edges for this case (and we failed to, before I introduced 
STOREDANYTHING)

Richard 

> 
> Thanks for the hints,
> Filip

Reply via email to