This patch changes VRP to use the points to info now available in prange instead of the value-range-equiv side structure it use to use.

The side table is left in place by this patch, but will be removed by a follow on patch.  Before making the switch, I implemented a double check to compare the side table and the prange information.  In a build of a stage of gcc, prange generated all the same infomration, and found 338 addition propagation opportunities.

A few more testcases need to be adjusted to account for the better information, these have been discussed earlier. Interestingly, adding noipa to the gcov test causes that test to work correctly now... so there is nothing to look at there any more.   Once of the tests is xfailed until PR 123160 is resolved.

Bootstrapped on  x86_64-pc-linux-gnu with no new regressions. Pushed.

Andrew
From bb510ccce320e153a8bc60e4d0970e10b0a287d2 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <[email protected]>
Date: Mon, 1 Jun 2026 14:28:33 -0400
Subject: [PATCH 2/4] Switch VRP to use prange.

Use the points-to info in prange instead olf the value-range-equiv side
table in VRP.  Adjust testcases:
 - PTA causes less mem*_chk routines to be generated.
 - Gimple fold is causing issues by not properly handling pointer_plus.
   See PR 123160.   XFAILing until resolved.
 - Adding noipa prevents VRP from propagating IPA info causing a failure.

	gcc/
	* tree-vrp.cc (rvrp_folder::value_of_expr): Use prange PTA info.
	(value_on_edge): Likewise.

	gcc/testsuite/
	* gcc.c-torture/execute/builtins/memcpy-chk.c: Adjust.
        * gcc.c-torture/execute/builtins/memmove-chk.c: Adjust.
	* gcc.dg/builtin-object-size-4.c: XFAIL until pr123160 is fixed.
	* gcc.dg/builtin-dynamic-object-size-4.c: Likewise.
	* gcc.misc-tests/gcov-14.c: Add noipa.
---
 .../execute/builtins/memcpy-chk.c             |  4 +-
 .../execute/builtins/memmove-chk.c            |  4 +-
 .../gcc.dg/builtin-dynamic-object-size-4.c    |  1 +
 gcc/testsuite/gcc.dg/builtin-object-size-4.c  |  1 +
 gcc/testsuite/gcc.misc-tests/gcov-14.c        |  2 +-
 gcc/tree-vrp.cc                               | 58 ++++++++++++++++---
 6 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/memcpy-chk.c b/gcc/testsuite/gcc.c-torture/execute/builtins/memcpy-chk.c
index 5b245e58e22..985e1ad2368 100644
--- a/gcc/testsuite/gcc.c-torture/execute/builtins/memcpy-chk.c
+++ b/gcc/testsuite/gcc.c-torture/execute/builtins/memcpy-chk.c
@@ -146,7 +146,7 @@ test2_sub (long *buf3, char *buf4, char *buf6, int n)
      call.  */
 
   /* buf3 points to an unknown object, so __memcpy_chk should not be done.  */
-  if (memcpy ((char *) buf3 + 4, buf5, n + 6) != (char *) buf1 + 4
+  if (memcpy ((char *) buf3 + 4, buf5, 6) != (char *) buf1 + 4
       || memcmp (buf1, "aBcdRSTUVWklmnopq\0", 19))
     abort ();
 
@@ -158,7 +158,7 @@ test2_sub (long *buf3, char *buf4, char *buf6, int n)
       || i != 3)
     abort ();
 
-  if (memcpy ((char *) buf3 + 14, buf6, n + 2) != (char *) buf1 + 14
+  if (memcpy ((char *) buf3 + 14, buf6, 2) != (char *) buf1 + 14
       || memcmp (buf1, "aBcdRSTUVWkSmnrsq\0", 19))
     abort ();
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/memmove-chk.c b/gcc/testsuite/gcc.c-torture/execute/builtins/memmove-chk.c
index 73b35883ed1..fbecf313ed1 100644
--- a/gcc/testsuite/gcc.c-torture/execute/builtins/memmove-chk.c
+++ b/gcc/testsuite/gcc.c-torture/execute/builtins/memmove-chk.c
@@ -149,7 +149,7 @@ test2_sub (long *buf3, char *buf4, char *buf6, int n)
      call.  */
 
   /* buf3 points to an unknown object, so __memmove_chk should not be done.  */
-  if (memmove ((char *) buf3 + 4, buf5, n + 6) != (char *) buf1 + 4
+  if (memmove ((char *) buf3 + 4, buf5, 6) != (char *) buf1 + 4
       || memcmp (buf1, "aBcdRSTUVWklmnopq\0", 19))
     abort ();
 
@@ -161,7 +161,7 @@ test2_sub (long *buf3, char *buf4, char *buf6, int n)
       || i != 3)
     abort ();
 
-  if (memmove ((char *) buf3 + 14, buf6, n + 2) != (char *) buf1 + 14
+  if (memmove ((char *) buf3 + 14, buf6, 2) != (char *) buf1 + 14
       || memcmp (buf1, "aBcdRSTUVWkSmnrsq\0", 19))
     abort ();
 
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
index 4a909b263a7..1a01d0e4beb 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
@@ -1,6 +1,7 @@
 /* { dg-do run } */
 /* { dg-options "-O2 -Wno-stringop-overread" } */
 /* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */
+/* { dg-xfail-run-if "PTA now triggers PR123160" { "*-*-*" } } */
 
 #define __builtin_object_size __builtin_dynamic_object_size
 #include "builtin-object-size-4.c"
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
index ec7cde9522b..511f844683b 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
@@ -1,6 +1,7 @@
 /* { dg-do run } */
 /* { dg-options "-O2 -Wno-stringop-overread" } */
 /* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */
+/* { dg-xfail-run-if "PTA now triggers PR123160" { "*-*-*" } } */
 
 #include "builtin-object-size-common.h"
 
diff --git a/gcc/testsuite/gcc.misc-tests/gcov-14.c b/gcc/testsuite/gcc.misc-tests/gcov-14.c
index 847b09cc13b..97a77437d17 100644
--- a/gcc/testsuite/gcc.misc-tests/gcov-14.c
+++ b/gcc/testsuite/gcc.misc-tests/gcov-14.c
@@ -15,7 +15,7 @@ extern __inline int Foo ()
   return 0; /* count(-) */
 }
 
-int (* __attribute__ ((noinline)) Bar ()) ()
+int (* __attribute__ ((noinline,noipa)) Bar ()) ()
 {
   return Foo; /* count(1) */
 }
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 8f80fc6b69c..89c57d791c9 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -977,10 +977,32 @@ public:
   {
     // Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
     if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
-      return NULL;
-    tree ret = m_ranger->value_of_expr (name, s);
-    if (!ret && supported_pointer_equiv_p (name))
-      ret = m_pta->get_equiv (name);
+      return NULL_TREE;
+    if (!value_range::supports_type_p (TREE_TYPE (name)))
+      return NULL_TREE;
+
+    value_range r (TREE_TYPE (name));
+    if (!m_ranger->range_of_expr (r, name, s))
+      return NULL_TREE;
+
+    // A constant used in an unreachable block often returns as UNDEFINED.
+    // If the result is undefined, check the global value for a constant.
+    if (r.undefined_p ())
+      range_of_expr (r, name);
+
+    tree ret;
+    if (r.singleton_p (&ret))
+      return ret;
+    else
+      ret = NULL_TREE;
+    if (is_a <prange> (r))
+      {
+	prange &p = as_a <prange> (r);
+	ret = p.pt_invariant ();
+	// A const points has to be gimple_min_invariant.
+	gcc_checking_assert (!ret || is_gimple_min_invariant (ret));
+      }
+
     return ret;
   }
 
@@ -989,9 +1011,31 @@ public:
     // Shortcircuit subst_and_fold callbacks for abnormal ssa_names.
     if (TREE_CODE (name) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
       return NULL;
-    tree ret = m_ranger->value_on_edge (e, name);
-    if (!ret && supported_pointer_equiv_p (name))
-      ret = m_pta->get_equiv (name);
+    if (!value_range::supports_type_p (TREE_TYPE (name)))
+      return NULL_TREE;
+
+    value_range r (TREE_TYPE (name));
+    if (!m_ranger->range_on_edge (r, e, name))
+      return NULL_TREE;
+
+    // A constant used in an unreachable block often returns as UNDEFINED.
+    // If the result is undefined, check the global value for a constant.
+    if (r.undefined_p ())
+      range_of_expr (r, name);
+
+    tree ret;
+    if (r.singleton_p (&ret))
+      return ret;
+    else
+      ret = NULL_TREE;
+    if (is_a <prange> (r))
+      {
+	prange &p = as_a <prange> (r);
+	ret = p.pt_invariant ();
+	// A const points has to be gimple_min_invariant.
+	gcc_checking_assert (!ret || is_gimple_min_invariant (ret));
+      }
+
     return ret;
   }
 
-- 
2.45.0

Reply via email to