https://gcc.gnu.org/g:f3e5f4c58591f5dacdd14a65ec47bbe310df02a0
commit r15-580-gf3e5f4c58591f5dacdd14a65ec47bbe310df02a0 Author: Richard Biener <rguent...@suse.de> Date: Mon Mar 11 11:17:32 2024 +0100 tree-optimization/13962 - handle ptr-ptr compares in ptrs_compare_unequal Now that we handle pt.null conservatively we can implement the missing tracking of constant pool entries (aka STRING_CST) and handle ptr-ptr compares using points-to info in ptrs_compare_unequal. PR tree-optimization/13962 PR tree-optimization/96564 * tree-ssa-alias.h (pt_solution::const_pool): New flag. * tree-ssa-alias.cc (ptrs_compare_unequal): Handle pointer-pointer compares. (dump_points_to_solution): Dump the const_pool flag, fix guard of flag dumping. * gimple-pretty-print.cc (pp_points_to_solution): Likewise. * tree-ssa-structalias.cc (find_what_var_points_to): Set the const_pool flag for STRING. (pt_solution_ior_into): Handle the const_pool flag. (ipa_escaped_pt): Initialize it. * gcc.dg/tree-ssa/alias-39.c: New testcase. * g++.dg/vect/pr68145.cc: Use -fno-tree-pta to avoid UB to manifest in transforms no longer vectorizing this testcase for an ICE. Diff: --- gcc/gimple-pretty-print.cc | 5 ++++- gcc/testsuite/g++.dg/vect/pr68145.cc | 2 +- gcc/testsuite/gcc.dg/tree-ssa/alias-39.c | 12 ++++++++++++ gcc/tree-ssa-alias.cc | 30 ++++++++++++++++++++++++++---- gcc/tree-ssa-alias.h | 5 +++++ gcc/tree-ssa-structalias.cc | 6 +++--- 6 files changed, 51 insertions(+), 9 deletions(-) diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc index abda8871f97f..a71e1e0efc77 100644 --- a/gcc/gimple-pretty-print.cc +++ b/gcc/gimple-pretty-print.cc @@ -822,6 +822,8 @@ pp_points_to_solution (pretty_printer *buffer, const pt_solution *pt) pp_string (buffer, "unit-escaped "); if (pt->null) pp_string (buffer, "null "); + if (pt->const_pool) + pp_string (buffer, "const-pool "); if (pt->vars && !bitmap_empty_p (pt->vars)) { @@ -838,7 +840,8 @@ pp_points_to_solution (pretty_printer *buffer, const pt_solution *pt) if (pt->vars_contains_nonlocal || pt->vars_contains_escaped || pt->vars_contains_escaped_heap - || pt->vars_contains_restrict) + || pt->vars_contains_restrict + || pt->vars_contains_interposable) { const char *comma = ""; pp_string (buffer, " ("); diff --git a/gcc/testsuite/g++.dg/vect/pr68145.cc b/gcc/testsuite/g++.dg/vect/pr68145.cc index 8a1e10ee7833..8d3502b0bf4e 100644 --- a/gcc/testsuite/g++.dg/vect/pr68145.cc +++ b/gcc/testsuite/g++.dg/vect/pr68145.cc @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-Wno-return-type" } */ +/* { dg-additional-options "-fno-tree-pta -Wno-return-type" } */ struct A { bool operator()(int p1, int p2) { return p1 && p2; } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-39.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-39.c new file mode 100644 index 000000000000..3b452893f6b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-39.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop3" } */ + +static int a, b; +int foo (int n, int which) +{ + void *p = __builtin_malloc (n); + void *q = which ? &a : &b; + return p == q; +} + +/* { dg-final { scan-tree-dump "return 0;" "forwprop3" } } */ diff --git a/gcc/tree-ssa-alias.cc b/gcc/tree-ssa-alias.cc index 96301bbde7fa..6d31fc836917 100644 --- a/gcc/tree-ssa-alias.cc +++ b/gcc/tree-ssa-alias.cc @@ -484,9 +484,27 @@ ptrs_compare_unequal (tree ptr1, tree ptr2) } return !pt_solution_includes (&pi->pt, obj1); } - - /* ??? We'd like to handle ptr1 != NULL and ptr1 != ptr2 - but those require pt.null to be conservatively correct. */ + else if (TREE_CODE (ptr1) == SSA_NAME) + { + struct ptr_info_def *pi1 = SSA_NAME_PTR_INFO (ptr1); + if (!pi1 + || pi1->pt.vars_contains_restrict + || pi1->pt.vars_contains_interposable) + return false; + if (integer_zerop (ptr2) && !pi1->pt.null) + return true; + if (TREE_CODE (ptr2) == SSA_NAME) + { + struct ptr_info_def *pi2 = SSA_NAME_PTR_INFO (ptr2); + if (!pi2 + || pi2->pt.vars_contains_restrict + || pi2->pt.vars_contains_interposable) + return false; + if ((!pi1->pt.null || !pi2->pt.null) + && (!pi1->pt.const_pool || !pi2->pt.const_pool)) + return !pt_solutions_intersect (&pi1->pt, &pi2->pt); + } + } return false; } @@ -636,6 +654,9 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt) if (pt->null) fprintf (file, ", points-to NULL"); + if (pt->const_pool) + fprintf (file, ", points-to const-pool"); + if (pt->vars) { fprintf (file, ", points-to vars: "); @@ -643,7 +664,8 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt) if (pt->vars_contains_nonlocal || pt->vars_contains_escaped || pt->vars_contains_escaped_heap - || pt->vars_contains_restrict) + || pt->vars_contains_restrict + || pt->vars_contains_interposable) { const char *comma = ""; fprintf (file, " ("); diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index b26fffeeb2df..e29dff583750 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -47,6 +47,11 @@ struct GTY(()) pt_solution includes memory at address NULL. */ unsigned int null : 1; + /* Nonzero if the points-to set includes a readonly object like a + STRING_CST that does not have an underlying declaration but will + end up in the constant pool. */ + unsigned int const_pool : 1; + /* Nonzero if the vars bitmap includes a variable included in 'nonlocal'. */ unsigned int vars_contains_nonlocal : 1; /* Nonzero if the vars bitmap includes a variable included in 'escaped'. */ diff --git a/gcc/tree-ssa-structalias.cc b/gcc/tree-ssa-structalias.cc index 0bac1a1f045a..0c6085b17662 100644 --- a/gcc/tree-ssa-structalias.cc +++ b/gcc/tree-ssa-structalias.cc @@ -6799,8 +6799,7 @@ find_what_var_points_to (tree fndecl, varinfo_t orig_vi) else if (vi->id == nonlocal_id) pt->nonlocal = 1; else if (vi->id == string_id) - /* Nobody cares - STRING_CSTs are read-only entities. */ - ; + pt->const_pool = 1; else if (vi->id == anything_id || vi->id == integer_id) pt->anything = 1; @@ -6956,6 +6955,7 @@ pt_solution_ior_into (struct pt_solution *dest, struct pt_solution *src) dest->escaped |= src->escaped; dest->ipa_escaped |= src->ipa_escaped; dest->null |= src->null; + dest->const_pool |= src->const_pool ; dest->vars_contains_nonlocal |= src->vars_contains_nonlocal; dest->vars_contains_escaped |= src->vars_contains_escaped; dest->vars_contains_escaped_heap |= src->vars_contains_escaped_heap; @@ -8128,7 +8128,7 @@ make_pass_build_ealias (gcc::context *ctxt) /* IPA PTA solutions for ESCAPED. */ struct pt_solution ipa_escaped_pt - = { true, false, false, false, false, + = { true, false, false, false, false, false, false, false, false, false, false, NULL }; /* Associate node with varinfo DATA. Worker for