On Fri, Jun 26, 2026 at 8:04 AM Torbjorn SVENSSON <[email protected]> wrote: > > Hello Andrew, > > This change introduces a regression for arm-none-eabi with thumb2. > > With r17-1602-ga5ab19d9db2d13, I see that the following test cases are now > failing: > > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_l1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_l1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_l3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_l3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_n1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_n1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_n2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_n2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_n3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_n3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_s1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_s1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_s2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_s2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstatic_s3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstatic_s3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_l1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_l1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_l3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_l3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_n1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_n1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_n2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_n2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_n3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_n3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_s1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_s1\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_s2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_s2\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl?\tstrong_s3\n > FAIL: gcc.target/arm/long-calls-1.c scan-assembler \tbl\tstrong_s3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_l1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_l1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_l3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_l3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_n1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_n1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_n3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_n3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_s1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_s1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_s2\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_s2\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstatic_s3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstatic_s3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_l1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_l1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_l3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_l3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_n1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_n1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_n3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_n3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_s1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_s1\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_s2\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_s2\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl?\tstrong_s3\n > FAIL: gcc.target/arm/long-calls-2.c scan-assembler \tbl\tstrong_s3\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_l1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_l1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_l3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_l3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_n1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_n1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_n2((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_n2((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_n3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_n3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_s1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_s1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_s2((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_s2((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl?\tstatic_s3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-3.c scan-assembler > \tbl\tstatic_s3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_l1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_l1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_l3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_l3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_n1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_n1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_n3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_n3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_s1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_s1((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_s2((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_s2((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl?\tstatic_s3((\\(PLT\\))?)\n > FAIL: gcc.target/arm/long-calls-4.c scan-assembler > \tbl\tstatic_s3((\\(PLT\\))?)\n > > The test cases were still broken as of r17-1841-ga928b9c408d818.
Looking into the testcases, after this patch, GCC is able to figure out that some of the functions now return a `STRING_CST` and inlines that and is able to remove the call. So the noinline attribute for these functions really should be noipa. Thanks, Andrea > > Kind regards, > Torbjörn > > On 2026-06-17 02:29, Andrew MacLeod wrote: > > 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; > > } > > >
