[gcc r17-2487] match: Simplify sign tests for MIN and BIT_IOR [PR126087]

Richard Biener via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:f8eb22d8408b25f337fad514aa8f47fe24f051d9

commit r17-2487-gf8eb22d8408b25f337fad514aa8f47fe24f051d9
Author: Neal Patalay <[email protected]>
Date:   Fri Jul 17 04:02:39 2026 -0700

    match: Simplify sign tests for MIN and BIT_IOR [PR126087]
    
    When `b` is known to be non-negative, the sign of both `MIN (a, b)`
    and `a | b` depends only on the sign of `a`. Add patterns to match.pd
    to optimize `MIN (a, b) cmp 0` and `(a | b) cmp 0` into `a cmp 0`,
    where `cmp` is `<` or `>=`. Currently, `(a | b) cmp 0` is optimized
    at the RTL level for some targets, but simplifying earlier is
    preferable.
    
            PR tree-optimization/126087
    
    gcc/ChangeLog:
    
            * match.pd: Simplify MIN and BIT_IOR compared to 0 when
            one operand is non-negative.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/pr126087.c: New test.
    
    Signed-off-by: Neal Patalay <[email protected]>

Diff:
---
 gcc/match.pd                             | 11 ++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr126087.c | 36 ++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index cb8c68bd9150..a5870dae46b9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4840,6 +4840,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (cmp (bit_ior (convert:utype @0) (convert:utype @1))
         { build_zero_cst (utype); } ))))
 
+/* Optimize MIN (a, b) >= 0 to a >= 0 if b is non-negative.
+   Optimize MIN (a, b) < 0 to a < 0 if b is non-negative.
+   Optimize (a | b) >= 0 to a >= 0 if b is non-negative.
+   Optimize (a | b) < 0 to a < 0 if b is non-negative.  */
+(for op (min bit_ior)
+  (for cmp (ge lt)
+    (simplify
+      (cmp (op:c @0 @1) integer_zerop@2)
+      (if (tree_expr_nonnegative_p (@1))
+        (cmp @0 @2)))))
+
 /* Undo fancy ways of writing max/min or other ?: expressions, like
    a - ((a - b) & -(a < b))  and  a - (a - b) * (a < b) into (a < b) ? b : a.
    People normally use ?: and that is what we actually try to optimize.  */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126087.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126087.c
new file mode 100644
index 000000000000..308a5096c428
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126087.c
@@ -0,0 +1,36 @@
+/* PR tree-optimization/126087 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void use();
+
+void f2(int a, unsigned short bb) {
+    int b = bb;
+    int m = a < b ? a : b;
+    if (m >= 0)
+      use();
+}
+
+void f3(int a, unsigned short bb) {
+    int b = bb;
+    int m = a | b;
+    if (m >= 0)
+      use();
+}
+
+void f4(int a, unsigned short bb) {
+    int b = bb;
+    int m = a < b ? a : b;
+    if (m < 0)
+      use();
+}
+
+void f5(int a, unsigned short bb) {
+    int b = bb;
+    int m = a | b;
+    if (m < 0)
+      use();
+}
+
+/* { dg-final { scan-tree-dump-not "MIN_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\| " "optimized" } } */
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.