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
0002-Switch-VRP-to-use-prange.patch
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;
}