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;
> >     }
> >
>

Reply via email to