https://gcc.gnu.org/g:b51998e2208b36fef6a1f68a18fdd6e562f910a4
commit r17-5394-gb51998e2208b36fef6a1f68a18fdd6e562f910a4 Author: Richard Biener <[email protected]> Date: Tue Oct 20 09:53:58 2026 +0200 tree-optimization/128008 - missing PTA constraints for parameter field The following addresses an issue with the recursion prevention when generating fake pointed-to variables for restrict qualified parameters. When we are not creating a fake pointed-to variable we have to put in a constraint from NONLOCAL as otherwise the points-to set of a restrict qualified variable/field will be empty. This also fixes the latent issue that pointed-to types with placeholders never got any constraints. PR tree-optimization/128008 * gimple-ssa-pta-constraints.cc (create_variable_info_for_1): Upon detecting recursion to the same structure type add a constraint from nonlocal. * gcc.dg/torture/pr128008.c: New testcase. Diff: --- gcc/gimple-ssa-pta-constraints.cc | 86 ++++++++++++++++++--------------- gcc/testsuite/gcc.dg/torture/pr128008.c | 20 ++++++++ 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/gcc/gimple-ssa-pta-constraints.cc b/gcc/gimple-ssa-pta-constraints.cc index 17b5989b06b8..822a8679e0db 100644 --- a/gcc/gimple-ssa-pta-constraints.cc +++ b/gcc/gimple-ssa-pta-constraints.cc @@ -3411,27 +3411,31 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id, if (POINTER_TYPE_P (decl_type) && (TYPE_RESTRICT (decl_type) || add_restrict)) vi->only_restrict_pointers = 1; - if (vi->only_restrict_pointers - && !type_contains_placeholder_p (TREE_TYPE (decl_type)) - && handle_param - && !bitmap_bit_p (handled_struct_type, - TYPE_UID (TREE_TYPE (decl_type)))) + if (handle_param + && vi->only_restrict_pointers) { - varinfo_t rvi; - tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type)); - DECL_EXTERNAL (heapvar) = 1; - if (var_can_have_subvars (heapvar)) - bitmap_set_bit (handled_struct_type, - TYPE_UID (TREE_TYPE (decl_type))); - rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, - true, handled_struct_type); - if (var_can_have_subvars (heapvar)) - bitmap_clear_bit (handled_struct_type, - TYPE_UID (TREE_TYPE (decl_type))); - rvi->is_restrict_var = 1; - insert_vi_for_tree (heapvar, rvi); - make_constraint_from (vi, rvi->id); - make_param_constraints (rvi); + if (!bitmap_bit_p (handled_struct_type, + TYPE_UID (TREE_TYPE (decl_type))) + && !type_contains_placeholder_p (TREE_TYPE (decl_type))) + { + varinfo_t rvi; + tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type)); + DECL_EXTERNAL (heapvar) = 1; + if (var_can_have_subvars (heapvar)) + bitmap_set_bit (handled_struct_type, + TYPE_UID (TREE_TYPE (decl_type))); + rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, + true, handled_struct_type); + if (var_can_have_subvars (heapvar)) + bitmap_clear_bit (handled_struct_type, + TYPE_UID (TREE_TYPE (decl_type))); + rvi->is_restrict_var = 1; + insert_vi_for_tree (heapvar, rvi); + make_constraint_from (vi, rvi->id); + make_param_constraints (rvi); + } + else + make_constraint_from (vi, nonlocal_id); } fieldstack.release (); return vi; @@ -3471,26 +3475,30 @@ create_variable_info_for_1 (tree decl, const char *name, bool add_id, newvi->may_have_pointers = fo->may_have_pointers; newvi->only_restrict_pointers = fo->only_restrict_pointers; if (handle_param - && newvi->only_restrict_pointers - && !type_contains_placeholder_p (fo->restrict_pointed_type) - && !bitmap_bit_p (handled_struct_type, - TYPE_UID (fo->restrict_pointed_type))) + && newvi->only_restrict_pointers) { - varinfo_t rvi; - tree heapvar = build_fake_var_decl (fo->restrict_pointed_type); - DECL_EXTERNAL (heapvar) = 1; - if (var_can_have_subvars (heapvar)) - bitmap_set_bit (handled_struct_type, - TYPE_UID (fo->restrict_pointed_type)); - rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, - true, handled_struct_type); - if (var_can_have_subvars (heapvar)) - bitmap_clear_bit (handled_struct_type, - TYPE_UID (fo->restrict_pointed_type)); - rvi->is_restrict_var = 1; - insert_vi_for_tree (heapvar, rvi); - make_constraint_from (newvi, rvi->id); - make_param_constraints (rvi); + if (!bitmap_bit_p (handled_struct_type, + TYPE_UID (fo->restrict_pointed_type)) + && !type_contains_placeholder_p (fo->restrict_pointed_type)) + { + varinfo_t rvi; + tree heapvar = build_fake_var_decl (fo->restrict_pointed_type); + DECL_EXTERNAL (heapvar) = 1; + if (var_can_have_subvars (heapvar)) + bitmap_set_bit (handled_struct_type, + TYPE_UID (fo->restrict_pointed_type)); + rvi = create_variable_info_for_1 (heapvar, "PARM_NOALIAS", true, + true, handled_struct_type); + if (var_can_have_subvars (heapvar)) + bitmap_clear_bit (handled_struct_type, + TYPE_UID (fo->restrict_pointed_type)); + rvi->is_restrict_var = 1; + insert_vi_for_tree (heapvar, rvi); + make_constraint_from (newvi, rvi->id); + make_param_constraints (rvi); + } + else + make_constraint_from (newvi, nonlocal_id); } if (i + 1 < fieldstack.length ()) { diff --git a/gcc/testsuite/gcc.dg/torture/pr128008.c b/gcc/testsuite/gcc.dg/torture/pr128008.c new file mode 100644 index 000000000000..d01090ab9ad0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr128008.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ + +struct T { int v; struct T *restrict next; }; + +__attribute__((noipa)) void +f(struct T *restrict p) +{ + p->next->v = 7; +} + +int main() +{ + struct T *q = __builtin_malloc(sizeof *q); + q->next = __builtin_malloc(sizeof *q); + q->next->v = 2; + f(q); + if (q->next->v != 7) + __builtin_abort(); + return 0; +}
