[PING][PATCH] match: 1 / X -> X == 1 for positive X [PR125735]

Kael Andrew Franco <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <CACAb0qdXjezi+RiiHzeN+y0DLSbBqfz9k7t=rBn-58_C2PxLDg@mail.gmail.com>
Ping of https://gcc.gnu.org/pipermail/gcc-patches/2026-July/724387.html.
Updated patch still works:

From a8dad89050597f075c197bba9b0da2703277671e Mon Sep 17 00:00:00 2001
From: Kael Andrew Alonzo Franco <[email protected]>
Date: Thu, 30 Jul 2026 21:59:35 -0400
Subject: [PATCH] match: 1 / X -> X == 1 for positive X [PR125735]

TYPE_UNSIGNED (type) doesn't cover positive signed types and
tree_expr_nonnegative_p () doesn't work so use vr0.nonnegative_p ().

Bootstrapped and tested on x86_64-pc-linux-gnu.

	PR tree-optimization/125735

gcc/ChangeLog:

	* match.pd: 1 / X -> X == 1 for positive X. [PR125735]

gcc/testsuite/ChangeLog:

	* gcc.dg/pr125735.c: New test.

Signed-off-by: Kael Andrew Franco <[email protected]>
---
 gcc/match.pd                    | 19 +++++++++++++++----
 gcc/testsuite/gcc.dg/pr125735.c | 11 +++++++++++
 2 files changed, 26 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr125735.c

diff --git a/gcc/match.pd b/gcc/match.pd
index dd223dc4553..9c022224bc5 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -628,8 +628,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && TYPE_UNSIGNED (type))
    (trunc_divmod @0 @1))))

-/* 1 / X -> X == 1 for unsigned integer X.
-   1 / X -> X >= -1 && X <= 1 ? X : 0 for signed integer X.
+/* 1 / X -> X == 1 for positive integer X.
+   1 / X -> X >= -1 && X <= 1 ? X : 0 for when X could be negative.
    But not for 1 / 0 so that we can get proper warnings and errors,
    and not for 1-bit integers as they are edge cases better handled
    elsewhere.  Delay the conversion of the signed division until late
@@ -640,13 +640,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       && TYPE_PRECISION (type) > 1
       && !integer_zerop (@1)
       && (!flag_non_call_exceptions || tree_expr_nonzero_p (@1)))
-  (if (TYPE_UNSIGNED (type))
+  (with {
+    bool positive_p = TYPE_UNSIGNED (type);
+#if GIMPLE
+    int_range_max vr0;
+    wide_int lower_bnd;
+    if (!positive_p
+        && gimple_match_range_of_expr (vr0, @1)
+        && vr0.nonnegative_p ())
+      positive_p = true;
+#endif
+  }
+  (if (positive_p)
    (convert (eq:boolean_type_node @1 @0))
    (if (fold_before_rtl_expansion_p ())
     (with { tree utype = unsigned_type_for (type); }
      (cond (le (plus (convert:utype @1) { build_one_cst (utype); })
 		{ build_int_cst (utype, 2); })
-      @1 { build_zero_cst (type); }))))))
+      @1 { build_zero_cst (type); })))))))

 /* Combine two successive divisions.  Note that combining ceil_div
    and floor_div is trickier and combining round_div even more so.  */
diff --git a/gcc/testsuite/gcc.dg/pr125735.c b/gcc/testsuite/gcc.dg/pr125735.c
new file mode 100644
index 00000000000..b94d95c0de7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr125735.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+_Bool
+one_div_positive (int b)
+{
+  if (b < 1) return 0;
+  return (1 / b);
+}
+
+/* { dg-final { scan-tree-dump "b_\[0-9\]+.D. == 1" "optimized" } } */
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.