This adds the rest of the simple comparisons to combine_comparisons.
This should be make it easier to support a&~b for phiopt and ifcombine.
Since `a > b` for booleans is `a & !b`.

Bootstrapped and tested on x86_64-linux-gnu.

        PR tree-optimization/117193

gcc/ChangeLog:

        * fold-const.cc (combine_comparisons): Add support
        for LT, GT, LE, and GE.
        * match.pd (`(a CMP0 b) OP (a OP1 b)`): Change to use simple_comparison
        instead of eq/ne.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/cmple-1.c: New test.

Signed-off-by: Andrea Pinski <[email protected]>
---
 gcc/fold-const.cc                       | 20 +++++++++
 gcc/match.pd                            |  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/cmple-1.c | 54 +++++++++++++++++++++++++
 3 files changed, 75 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmple-1.c

diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index dd6ce48f89a..20a670b282a 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -2973,6 +2973,26 @@ combine_comparisons (enum tree_code code, enum tree_code 
lcode,
       compcode = (~(lcompcode ^ rcompcode)) & 0xf;
       break;
 
+    //`bool0 < bool1` is `!bool0 & bool1`
+    case LT_EXPR:
+      compcode = (((~lcompcode) & rcompcode)) & 0xf;
+      break;
+
+    //`bool0 > bool1` is `bool0 & !bool1`
+    case GT_EXPR:
+      compcode = ((lcompcode & (~rcompcode))) & 0xf;
+      break;
+
+    // `bool0 <= bool1` as !bool0 | bool1
+    case LE_EXPR:
+      compcode = (((~lcompcode) | rcompcode)) & 0xf;
+      break;
+
+    //`bool0 >= bool1` is `bool0 | !bool1`
+    case GE_EXPR:
+      compcode = ((lcompcode | (~rcompcode))) & 0xf;
+      break;
+
     default:
       return ERROR_MARK;
     }
diff --git a/gcc/match.pd b/gcc/match.pd
index f8251885a7c..374bce45269 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3621,7 +3621,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 
 /* Optimize (a CMP b) &| (a CMP b)
    using the helper combine_comparisons function.  */
-(for bitop (bit_and bit_ior bit_xor ne eq)
+(for bitop (bit_and bit_ior bit_xor simple_comparison)
  (for cmp1 (tcc_comparison)
   (for cmp2 (tcc_comparison)
    (for rcmp (tcc_comparison)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmple-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/cmple-1.c
new file mode 100644
index 00000000000..8c99180f360
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cmple-1.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* PR tree-optimization/117193 */
+
+_Bool ltgt_lt(int a, int b)
+{
+  _Bool c = a < b;
+  _Bool d = a > b;
+  return c < d; // a > b
+}
+/* { dg-final { scan-tree-dump "a_\[0-9\]+.D. > b_\[0-9\]+.D.|b_\[0-9\]+.D. < 
a_\[0-9\]+.D." "optimized" } } */
+
+_Bool lteq_lt(int x, int y)
+{
+  _Bool c = x < y;
+  _Bool d = x == y;
+  return c < d; // x == y
+}
+/* { dg-final { scan-tree-dump "x_\[0-9\]+.D. == y_\[0-9\]+.D.|y_\[0-9\]+.D. 
== x_\[0-9\]+.D." "optimized" } } */
+
+_Bool ltne_lt(int z, int w)
+{
+  _Bool c = z < w;
+  _Bool d = z != w;
+  return c < d; // z > w
+}
+/* { dg-final { scan-tree-dump "z_\[0-9\]+.D. > w_\[0-9\]+.D.|w_\[0-9\]+.D. < 
y_\[0-9\]+.D." "optimized" } } */
+
+_Bool lege_lt(int i, int j)
+{
+  _Bool c = i <= j;
+  _Bool d = i >= j;
+  return c < d; // i > j
+}
+/* { dg-final { scan-tree-dump "i_\[0-9\]+.D. > j_\[0-9\]+.D.|j_\[0-9\]+.D. < 
i_\[0-9\]+.D." "optimized" } } */
+
+_Bool leeq_lt(int k, int l)
+{
+  _Bool c = k <= l;
+  _Bool d = k == l;
+  return c < d; // 0
+}
+/* { dg-final { scan-tree-dump "return 0" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "k_\[0-9\]+.D." "optimized" } } */
+/* { dg-final { scan-tree-dump-not "l_\[0-9\]+.D." "optimized" } } */
+
+_Bool lene_lt(int m, int n)
+{
+  _Bool c = m <= n;
+  _Bool d = m != n;
+  return c < d; // m > n
+}
+/* { dg-final { scan-tree-dump "m_\[0-9\]+.D. > n_\[0-9\]+.D.|n_\[0-9\]+.D. < 
m_\[0-9\]+.D." "optimized" } } */
+
-- 
2.43.0

Reply via email to