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