On 6/1/26 16:08, Andrew Pinski wrote:
When I was looking into fixing tree_expr_nonnegative_p not to be recusive,
we should have tree_expr_nonnegative_p use the ranger.
I also didn't realize I wrote this patch before so this is
the updated version of the already approved:
https://gcc.gnu.org/pipermail/gcc-patches/2023-October/634205.html
Updated for the review comments.

Note testsuite/g++.dg/ipa/pure-const-3.C testcase will always fail as we can
use the fact the argument is always non-negative in many different places now.
Since there is no way to test it, let's remove the testcase.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/111959

gcc/ChangeLog:

        * fold-const.cc (tree_single_nonnegative_p): Use the range to see
        if the SSA_NAME was nonnegative.

gcc/testsuite/ChangeLog:

        * gcc.dg/pr80776-1.c: xfail and update comment.
        * gcc.dg/tree-ssa/forwprop-44.c: New test.
        * testsuite/g++.dg/ipa/pure-const-3.C: Remove.

Signed-off-by: Andrew Pinski <[email protected]>
---
  gcc/fold-const.cc                           | 13 +++++++++++++
  gcc/testsuite/g++.dg/ipa/pure-const-3.C     |  6 ------
  gcc/testsuite/gcc.dg/pr80776-1.c            | 10 +++++-----
  gcc/testsuite/gcc.dg/tree-ssa/forwprop-44.c | 14 ++++++++++++++
  4 files changed, 32 insertions(+), 11 deletions(-)
  delete mode 100644 gcc/testsuite/g++.dg/ipa/pure-const-3.C
  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/forwprop-44.c

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 179c7e167a3..bc690b24663 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -14576,6 +14576,19 @@ tree_single_nonnegative_p (tree t, int depth)
        return RECURSE (TREE_OPERAND (t, 1)) && RECURSE (TREE_OPERAND (t, 2));
case SSA_NAME:
+      /* For integral types, query the range if possible. */
+      if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
+       {
+         int_range_max r;
+         get_global_range_query ()->range_of_expr (r, t);


IS there a reason not to use get_range_query() ? get_global_range_query will only uses ranges from SSA_NAME_RANGE_INFO(ssaname), and is the fallback if there is no active ranger...   You will not get any contextual info this way, just global values.


+         if (!r.undefined_p () && !r.varying_p())
+           {
+             if (r.nonnegative_p ())
+               return true;
+             if (r.nonpositive_p () && !range_includes_zero_p (r))
+               return false;
+           }
+       }
        /* Limit the depth of recursion to avoid quadratic behavior.
         This is expected to catch almost all occurrences in practice.
         If this code misses important cases that unbounded recursion
diff --git a/gcc/testsuite/g++.dg/ipa/pure-const-3.C 
b/gcc/testsuite/g++.dg/ipa/pure-const-3.C
deleted file mode 100644
index 62d355b4ce7..00000000000
--- a/gcc/testsuite/g++.dg/ipa/pure-const-3.C
+++ /dev/null
@@ -1,6 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fno-ipa-vrp -fdump-tree-optimized -fno-tree-ccp 
-fdisable-tree-evrp -fdisable-tree-vrp1 -fdisable-tree-vrp2 -fno-thread-jumps 
-fno-tree-dominator-opts"  } */
-
-#include "pure-const-3.h"
-
-/* { dg-final { scan-tree-dump "barvar"  "optimized"  } } */
diff --git a/gcc/testsuite/gcc.dg/pr80776-1.c b/gcc/testsuite/gcc.dg/pr80776-1.c
index b9bce62d982..bf0fcd86a65 100644
--- a/gcc/testsuite/gcc.dg/pr80776-1.c
+++ b/gcc/testsuite/gcc.dg/pr80776-1.c
@@ -18,14 +18,14 @@ Foo (void)
    if (! (0 <= i && i <= 999999))
      __builtin_unreachable ();
- /* Legacy evrp sets the range of i to [0, MAX] *before* the first conditional,
-     and to [0,999999] *before* the second conditional.  This is because both
-     evrp and VRP use trickery to set global ranges when this particular use of
+  /* vrp1 sets the range of i to [0, MAX] *before* the first conditional,
+     and to [0,999999] *before* the second conditional.  This is because
+     vrp use trickery to set global ranges when this particular use of
       a __builtin_unreachable is in play (see uses of
       assert_unreachable_fallthru_edge_p).
- Setting these ranges at the definition site, causes VRP to remove the
+     Setting these ranges at the definition site, causes other to remove the
       unreachable code altogether, leaving the following sprintf unguarded.  
This

And as a side note, These comments should not be true any more. no version of VRP does any trickery with regards to builtin_unreachable.

i_4 is VARYING until we get to BB4, at which point it is [0, +INF].  AFTER the conditional :)

=========== BB 2 ============
Imports: i_4
Exports: i_4
    <bb 2> :
    i_4 = somerandom ();
    if (i_4 < 0)
      goto <bb 3>; [INV]
    else
      goto <bb 4>; [INV]

2->3  (T) i_4 :         [irange] int [-INF, -1]
2->4  (F) i_4 :         [irange] int [0, +INF]

=========== BB 3 ============
    <bb 3> :
    __builtin_unreachable ();


=========== BB 4 ============
Imports: i_4
Exports: i.0_1  i_4
         i.0_1 : i_4(I)
i_4     [irange] int [0, +INF]
Partial equiv (i.0_1 pe32 i_4)
    <bb 4> :
    i.0_1 = (unsigned int) i_4;
    if (i.0_1 > 999999)
      goto <bb 5>; [INV]
    else
      goto <bb 6>; [INV]

i.0_1 : [irange] unsigned int [0, 2147483647] MASK 0x7fffffff VALUE 0x0
4->5  (T) i.0_1 :       [irange] unsigned int [1000000, 2147483647] MASK 0x7fffffff VALUE 0x0 4->5  (T) i_4 :         [irange] int [1000000, +INF] MASK 0x7fffffff VALUE 0x0 4->6  (F) i.0_1 :       [irange] unsigned int [0, 999999] MASK 0xfffff VALUE 0x0
4->6  (F) i_4 :         [irange] int [0, 999999] MASK 0xfffff VALUE 0x0

=========== BB 5 ============
    <bb 5> :
    __builtin_unreachable ();

=========== BB 6 ============
i_4     [irange] int [0, 999999] MASK 0xfffff VALUE 0x0
    <bb 6> :
    _7 = __builtin___sprintf_chk (&number, 1, 7, "%d", i_4);
    return;

Non-varying global ranges:
=========================:
i.0_1  : [irange] unsigned int [0, 2147483647] MASK 0x7fffffff VALUE 0x0


Likewise with i.0_1, its only in bb6 that it becomes  [0, 999999].

i_4 has a global range of VARYING, and as you can see, i.0_1 is set to [0, 0x7fffffff].  no trickery!


After VRP2 and the unreachable calls  are removed, well then things change and there is nothing but i_4 with  a global range of [0, 999999]

Andrew

Reply via email to