https://gcc.gnu.org/g:1e13fb44f1474b7d57e7144d3fff38e9c769b92d

commit r16-4161-g1e13fb44f1474b7d57e7144d3fff38e9c769b92d
Author: Andrew MacLeod <[email protected]>
Date:   Tue Sep 30 15:59:38 2025 -0400

    Fix off by one in range_from_loop_direction.
    
    When bounds_of_var_in_loop was converted to range_from_loop_direction,
    the final check returned FALSE when the beginning and end bounds were
    the same...  The new code was using wi::gt_p, when it should have been
    wi::ge_p when checking for the fail condition.
    
            PR tree-optimization/120560
            gcc/
            * vr-values.cc (range_from_loop_direction): Use wi::ge_p rather
            than wi::gt_p.
    
            gcc/testsuite/
            * gcc.dg/pr120560.c: New.

Diff:
---
 gcc/testsuite/gcc.dg/pr120560.c | 13 +++++++++++++
 gcc/vr-values.cc                |  4 ++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/pr120560.c b/gcc/testsuite/gcc.dg/pr120560.c
new file mode 100644
index 000000000000..deb3c18f0b16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr120560.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-tree-ccp -fdump-tree-evrp" } */
+int main() {
+  int a = -1, b = 2, c = 1;
+  if (a >= 0)
+    c = 0;
+  while (1) {
+    if (-b + c - 7 >= 0)
+      return 0;
+    b = b - 1000 - 2147482648;
+  }
+}
+/* { dg-final { scan-tree-dump "return 0"  "evrp" } } */
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index ff11656559bf..44dff35bcf29 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -278,14 +278,14 @@ range_from_loop_direction (irange &r, tree type,
     r.set_varying (type);
   else if (dir == EV_DIR_GROWS)
     {
-      if (wi::gt_p (begin.lower_bound (), end.upper_bound (), sign))
+      if (wi::ge_p (begin.lower_bound (), end.upper_bound (), sign))
        r.set_varying (type);
       else
        r = int_range<1> (type, begin.lower_bound (), end.upper_bound ());
     }
   else
     {
-      if (wi::gt_p (end.lower_bound (), begin.upper_bound (), sign))
+      if (wi::ge_p (end.lower_bound (), begin.upper_bound (), sign))
        r.set_varying (type);
       else
        r = int_range<1> (type, end.lower_bound (), begin.upper_bound ());

Reply via email to