[PATCH 2/2] match/fold: Add LT/GT/LE/GE to combine_comparisons [PR117193]
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
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