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]>
---
If this patch is approved, could someone please commit it and update
PR126087 for me?

v2: Merged both patterns with a (for op (min bit_ior))

Bootstrapped and regression tested on x86_64-pc-linux-gnu with no
regressions.

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

diff --git a/gcc/match.pd b/gcc/match.pd
index cb8c68bd915..a5870dae46b 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 00000000000..308a5096c42
--- /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" } } */
-- 
2.55.0

Reply via email to