https://gcc.gnu.org/g:47c73130063c86f3625e6d0060db06e5e781ebdb

commit r17-5682-g47c73130063c86f3625e6d0060db06e5e781ebdb
Author: Andrew MacLeod <[email protected]>
Date:   Tue Oct 13 15:00:57 2026 -0400

    Store and retrieve prange in global tables
    
    Only non-nullness was stored until now in the ptr_info_def structure.
    This completes saving and restoring a full prange object in the global
    tables.
    
            gcc/
            * gimple-pretty-print.cc (dump_ssaname_info): Do not print
            VARYING pointer ranges.
            * ipa-prop.cc (ipa_set_jfunc_vr): Remove points to info from
            pointers as necessary.
            * tree-ssanames.cc (set_range_info): Handle prange.
            * value-query.cc (get_ssa_name_range_info): Likewise.
            (gimple_range_global): Likewise.
    
            gcc/testsuite/
            * gcc.dg/ipa/ipa-prange-local-addr-1.c: New.
            * gcc.dg/tree-ssa/prange-global-1.c: New

Diff:
---
 gcc/gimple-pretty-print.cc                         | 14 ++++++---
 gcc/ipa-prop.cc                                    | 25 +++++++++++++++
 gcc/testsuite/gcc.dg/ipa/ipa-prange-local-addr-1.c | 32 +++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/prange-global-1.c    | 18 +++++++++++
 gcc/tree-ssanames.cc                               | 33 ++++++++++----------
 gcc/value-query.cc                                 | 36 ++++++++++------------
 6 files changed, 117 insertions(+), 41 deletions(-)

diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index b36e50b0fd48..ecbd02c92da7 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -2415,14 +2415,18 @@ dump_ssaname_info (pretty_printer *pp, tree node, int 
spc)
        }
     }
 
-  if (!POINTER_TYPE_P (TREE_TYPE (node))
-      && SSA_NAME_RANGE_INFO (node))
+  if (SSA_NAME_RANGE_INFO (node))
     {
       value_range r (TREE_TYPE (node));
       get_global_range_query ()->range_of_expr (r, node);
-      pp_string (pp, "# RANGE ");
-      pp_vrange (pp, &r);
-      newline_and_indent (pp, spc);
+      /* A pointer has storage as soon as it has aliasing info, so do not
+        print the VARYING that results.  */
+      if (!r.varying_p ())
+       {
+         pp_string (pp, "# RANGE ");
+         pp_vrange (pp, &r);
+         newline_and_indent (pp, spc);
+       }
     }
 }
 
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index c614ddccbbb0..8cc031570de8 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2395,6 +2395,31 @@ ipa_get_value_range (const vrange &tmp)
 static void
 ipa_set_jfunc_vr (ipa_jump_func *jf, const vrange &tmp)
 {
+  /* A points-to that names something only invariant within the caller --
+     the address of one of its locals, say -- must not travel to the callee.
+     Same restriction as ipa_record_return_value_range_1; see PR125857.
+     Drop just the points-to rather than the whole range, as the bounds and
+     the bitmask remain valid.  */
+  if (is_a <prange> (tmp))
+    {
+      const prange &pr = as_a <prange> (tmp);
+      tree t = pr.pt_invariant ();
+      if (!t)
+       t = pr.pt_invariant_away ();
+      if (t && !is_gimple_ip_invariant (t))
+       {
+         if (dump_file && (dump_flags & TDF_DETAILS))
+           {
+             fprintf (dump_file, "Dropping non ipa invariant points-to from ");
+             tmp.dump (dump_file);
+             fprintf (dump_file, "\n");
+           }
+         prange stripped = pr;
+         stripped.set_pt_unknown ();
+         jf->m_vr = ipa_get_value_range (stripped);
+         return;
+       }
+    }
   jf->m_vr = ipa_get_value_range (tmp);
 }
 
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-prange-local-addr-1.c 
b/gcc/testsuite/gcc.dg/ipa/ipa-prange-local-addr-1.c
new file mode 100644
index 000000000000..baad06d1ca7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-prange-local-addr-1.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-cp-details" } */
+
+/* A prange can carry the address of an object.  The address of an automatic
+   is gimple_min_invariant inside its own function but not ip-invariant, so
+   it must not reach a callee through a jump function.  This test confirms the
+   equivalent fix for PR125857 for globals and params is present.  */
+
+int sink;
+
+static __attribute__((noinline)) int
+walk (int x, int *flagp)
+{
+  if (x > 10) { *flagp = 1; return 1; }
+  if (x < -10) { *flagp = 2; return 2; }
+  return 0;
+}
+
+int
+top (int a, int b)
+{
+  int flag = 0;
+  int r = walk (a, &flag);
+  if (r)
+    return r;
+  r = walk (b, &flag);
+  if (r)
+    return r;
+  return flag;
+}
+
+/* { dg-final { scan-ipa-dump "Dropping non ipa invariant points-to" "cp" } } 
*/
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/prange-global-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/prange-global-1.c
new file mode 100644
index 000000000000..fbc04b14c651
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/prange-global-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-alias" } */
+
+/* A pointer's global range used to be a single non-null bit.
+   With pranges properly stored, we should pick up the mask.  */
+
+extern void g (void *);
+
+long *
+f (long *q)
+{
+  if ((__UINTPTR_TYPE__) q & 15)
+    __builtin_unreachable ();
+  g (q);
+  return q;
+}
+
+/* { dg-final { scan-tree-dump "prange.* MASK " "optimized" } } */
diff --git a/gcc/tree-ssanames.cc b/gcc/tree-ssanames.cc
index 2dab3fe947cb..9f0cddfb38ab 100644
--- a/gcc/tree-ssanames.cc
+++ b/gcc/tree-ssanames.cc
@@ -444,28 +444,27 @@ set_range_info (tree name, const vrange &r)
 
   // Pick up the current range, or VARYING if none.
   tree type = TREE_TYPE (name);
+  value_range tmp (type);
+  if (range_info_p (name))
+    range_info_get_range (name, tmp);
+  else
+    tmp.set_varying (type);
+
+  // If the result doesn't change, or is undefined, return false.
+  if (!tmp.intersect (r) || tmp.undefined_p ())
+    return false;
+
   if (POINTER_TYPE_P (type))
     {
-      struct ptr_info_def *pi = get_ptr_info (name);
       // If R is nonnull and pi is not, set nonnull.
-      if (!r.contains_zero_p () && (!pi || pi->pt.null))
+      struct ptr_info_def *pi = get_ptr_info (name);
+      if (!tmp.contains_zero_p () && pi->pt.null)
        set_ptr_nonnull (name);
-      else
-       return false;
-    }
-  else
-    {
-      value_range tmp (type);
-      if (range_info_p (name))
-       range_info_get_range (name, tmp);
-      else
-       tmp.set_varying (type);
-      // If the result doesn't change, or is undefined, return false.
-      if (!tmp.intersect (r) || tmp.undefined_p ())
-       return false;
-      if (!range_info_set_range (name, tmp))
-       return false;
     }
+
+  if (!range_info_set_range (name, tmp))
+    return false;
+
   if (dump_file)
     {
       value_range tmp (type);
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index a623d5f83bad..3e64f431fd2c 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -582,7 +582,6 @@ static inline void
 get_ssa_name_range_info (vrange &r, const_tree name)
 {
   tree type = TREE_TYPE (name);
-  gcc_checking_assert (!POINTER_TYPE_P (type));
   gcc_checking_assert (TREE_CODE (name) == SSA_NAME);
 
   vrange_storage *ri = SSA_NAME_RANGE_INFO (name);
@@ -633,21 +632,20 @@ gimple_range_global (vrange &r, tree name, struct 
function *fun)
       // Use a range from an SSA_NAME's available range.
       if (TREE_CODE (sym) == PARM_DECL)
        {
-         // Try to use the "nonnull" attribute to create ~[0, 0]
-         // anti-ranges for pointers.  Note that this is only valid with
-         // default definitions of PARM_DECLs.
+         get_ssa_name_range_info (r, name);
+         if (r.undefined_p ())
+           r.set_varying (type);
+         // Try to use the "nonnull" attribute to refine a pointer to
+         // ~[0, 0].  Note that this is only valid with default definitions
+         // of PARM_DECLs
          if (POINTER_TYPE_P (type)
              && ((cfun && fun == cfun && nonnull_arg_p (sym))
                  || get_ssa_name_ptr_info_nonnull (name)))
-           r.set_nonzero (type);
-         else if (!POINTER_TYPE_P (type))
            {
-             get_ssa_name_range_info (r, name);
-             if (r.undefined_p ())
-               r.set_varying (type);
+             prange nz (type);
+             nz.set_nonzero (type);
+             r.intersect (nz);
            }
-         else
-           r.set_varying (type);
        }
       // If this is a local automatic with no definition, use undefined.
       else if (TREE_CODE (sym) != RESULT_DECL)
@@ -655,18 +653,18 @@ gimple_range_global (vrange &r, tree name, struct 
function *fun)
       else
        r.set_varying (type);
    }
-  else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
+  else if (SSA_NAME_RANGE_INFO (name))
     {
       get_ssa_name_range_info (r, name);
       if (r.undefined_p ())
        r.set_varying (type);
-    }
-  else if (POINTER_TYPE_P (type) && SSA_NAME_PTR_INFO (name))
-    {
-      if (get_ssa_name_ptr_info_nonnull (name))
-       r.set_nonzero (type);
-      else
-       r.set_varying (type);
+      // pt.null may still carry non-nullness the stored range does not.
+      if (POINTER_TYPE_P (type) && get_ssa_name_ptr_info_nonnull (name))
+       {
+         prange nz (type);
+         nz.set_nonzero (type);
+         r.intersect (nz);
+       }
     }
   else
     r.set_varying (type);

Reply via email to