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);
+ 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
causes the bogus warning below. */
- sprintf (number, "%d", i); /* { dg-bogus "writing" "" } */
+ sprintf (number, "%d", i); /* { dg-bogus "writing" "" { xfail *-*-* } } */
}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-44.c
b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-44.c
new file mode 100644
index 00000000000..50b74fa0753
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-44.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/111959 */
+
+int divbypow2(int a, int b)
+{
+ if (a & ~0xff) __builtin_unreachable();
+ return a / (1<<b);
+}
+
+/* divbypow2 should be able to optimize to just a/b as a is known to be always
positive. */
+/* { dg-final { scan-tree-dump-not " / " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " << " "optimized" } } */
+/* { dg-final { scan-tree-dump-times " >> " 1 "optimized" } } */
--
2.43.0