> 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