[PATCH 1/2] match/fold: Add support for NE, XOR, and EQ to combine_comparisons [PR107881]
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
This adds support for !=, ^ and == to combine_comparisons and uses combine_comparisons in match for those cases instead of what was previously there. This allows for floating point comparisons to be merged in some more cases. And simplifies the match code to read. Also moves up the match pattern that uses combine_comparisons to above the other comparisons combines so it is matched first. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/107881 gcc/ChangeLog: * fold-const.cc (combine_comparisons): Add support for NE/XOR and EQ. * match.pd (`(a CMP1 b) OP (a CMP2 b)`): Move above others and add NE, XOR and EQ to the list of OPs. (`(a CMP1 b) ^ (a CMP2 b)`): Remove. (`(a CMP1 b) == (a CMP2 b)`): Remove. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/cmpeq-5.c: New test. * gcc.dg/tree-ssa/cmpxor-2.c: New test. Signed-off-by: Andrea Pinski <[email protected]> --- gcc/fold-const.cc | 9 ++++ gcc/match.pd | 68 +++++++----------------- gcc/testsuite/gcc.dg/tree-ssa/cmpeq-5.c | 51 ++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/cmpxor-2.c | 51 ++++++++++++++++++ 4 files changed, 131 insertions(+), 48 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpeq-5.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpxor-2.c diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 420e3185a2a..dd6ce48f89a 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -2964,6 +2964,15 @@ combine_comparisons (enum tree_code code, enum tree_code lcode, compcode = lcompcode | rcompcode; break; + case BIT_XOR_EXPR: + case NE_EXPR: + compcode = lcompcode ^ rcompcode; + break; + + case EQ_EXPR: + compcode = (~(lcompcode ^ rcompcode)) & 0xf; + break; + default: return ERROR_MARK; } diff --git a/gcc/match.pd b/gcc/match.pd index 02684d8a302..f8251885a7c 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3619,6 +3619,26 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1))) (gt @0 (minus @1 { build_int_cst (TREE_TYPE (@1), 1); })))) +/* Optimize (a CMP b) &| (a CMP b) + using the helper combine_comparisons function. */ +(for bitop (bit_and bit_ior bit_xor ne eq) + (for cmp1 (tcc_comparison) + (for cmp2 (tcc_comparison) + (for rcmp (tcc_comparison) + (simplify + (bitop (cmp1 @0 @1) (cmp2 @0 @1)) + (with { + tree_code rescode; + tree res; + bool honor_nans = HONOR_NANS (@0); + rescode = combine_comparisons (bitop, cmp1, cmp2, + type, honor_nans, &res); + } + (if (rescode == INTEGER_CST) + { res; } + (if (rescode == rcmp) + (rcmp @0 @1))))))))) + /* Convert (X == CST1) && ((other)X OP2 CST2) to a known value based on CST1 OP2 CST2. Similarly for (X != CST1). */ /* Convert (X == Y) && (X OP2 Y) to a known value if X is an integral type. @@ -3904,54 +3924,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { constant_boolean_node (true, type); }) )))))) -/* Optimize (a CMP b) ^ (a CMP b) */ -/* Optimize (a CMP b) != (a CMP b) */ -(for op (bit_xor ne) - (for cmp1 (lt lt lt le le le) - cmp2 (gt eq ne ge eq ne) - rcmp (ne le gt ne lt ge) - (simplify - (op:c (cmp1:c @0 @1) (cmp2 @0 @1)) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) - || POINTER_TYPE_P (TREE_TYPE (@0)) - || ((VECTOR_INTEGER_TYPE_P (TREE_TYPE (@1)) - || VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (@1))) - && expand_vec_cmp_expr_p (TREE_TYPE (@0), type, rcmp))) - (rcmp @0 @1))))) - -/* Optimize (a CMP b) == (a CMP b) */ -(for cmp1 (lt lt lt le le le) - cmp2 (gt eq ne ge eq ne) - rcmp (eq gt le eq ge lt) - (simplify - (eq:c (cmp1:c @0 @1) (cmp2 @0 @1)) - (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) - || POINTER_TYPE_P (TREE_TYPE (@0)) - || ((VECTOR_INTEGER_TYPE_P (TREE_TYPE (@1)) - || VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (@1))) - && expand_vec_cmp_expr_p (TREE_TYPE (@0), type, rcmp))) - (rcmp @0 @1)))) - -/* Optimize (a CMP b) &| (a CMP b) - using the helper combine_comparisons function. */ -(for bitop (bit_and bit_ior) - (for cmp1 (tcc_comparison) - (for cmp2 (tcc_comparison) - (for rcmp (tcc_comparison) - (simplify - (bitop (cmp1 @0 @1) (cmp2 @0 @1)) - (with { - tree_code rescode; - tree res; - bool honor_nans = HONOR_NANS (@0); - rescode = combine_comparisons (bitop, cmp1, cmp2, - type, honor_nans, &res); - } - (if (rescode == INTEGER_CST) - { res; } - (if (rescode == rcmp) - (rcmp @0 @1))))))))) - /* (type)([0,1]@a != 0) -> (type)a (type)([0,1]@a == 1) -> (type)a (type)([0,1]@a == 0) -> a ^ 1 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpeq-5.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpeq-5.c new file mode 100644 index 00000000000..16dc35ca39e --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpeq-5.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fno-trapping-math" } */ +/* PR tree-optimization/107881 */ + +_Bool ltgt_eq(float a, float b) +{ + _Bool c = a < b; + _Bool d = a > b; + return c == d; // a u== b +} +/* { dg-final { scan-tree-dump "a_\[0-9\]+.D. u== b_\[0-9\]+.D.|b_\[0-9\]+.D. u== a_\[0-9\]+.D." "optimized" } } */ + +_Bool lteq_eq(float x, float y) +{ + _Bool c = x < y; + _Bool d = x == y; + return c == d; // x u> y +} +/* { dg-final { scan-tree-dump "x_\[0-9\]+.D. u> y_\[0-9\]+.D.|y_\[0-9\]+.D. u< x_\[0-9\]+.D." "optimized" } } */ + +_Bool ltne_eq(float z, float 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_eq(float i, float j) +{ + _Bool c = i <= j; + _Bool d = i >= j; + return c == d; // i u== j +} +/* { dg-final { scan-tree-dump "i_\[0-9\]+.D. u== j_\[0-9\]+.D.|j_\[0-9\]+.D. u== i_\[0-9\]+.D." "optimized" } } */ + +_Bool leeq_eq(float k, float l) +{ + _Bool c = k <= l; + _Bool d = k == l; + return c == d; // k u>= l +} +/* { dg-final { scan-tree-dump "k_\[0-9\]+.D. u>= l_\[0-9\]+.D.|l_\[0-9\]+.D. u<= k_\[0-9\]+.D." "optimized" } } */ + +_Bool lene_eq(float m, float 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" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpxor-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpxor-2.c new file mode 100644 index 00000000000..00fa7120237 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpxor-2.c @@ -0,0 +1,51 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fno-trapping-math" } */ +/* PR tree-optimization/107881 */ + +_Bool ltgtxor(float a, float 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 lteqxor(float x, float y) +{ + _Bool c = x < y; + _Bool d = x == y; + return c ^ d; // x <= y (basically | here) +} +/* { dg-final { scan-tree-dump "x_\[0-9\]+.D. <= y_\[0-9\]+.D.|y_\[0-9\]+.D. >= x_\[0-9\]+.D." "optimized" } } */ + +_Bool ltnexor(float z, float w) +{ + _Bool c = z < w; + _Bool d = z != w; + return c ^ d; // z u> w +} +/* { dg-final { scan-tree-dump "z_\[0-9\]+.D. u> w_\[0-9\]+.D.|w_\[0-9\]+.D. u< y_\[0-9\]+.D." "optimized" } } */ + +_Bool legexor(float i, float 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 leeqxor(float k, float l) +{ + _Bool c = k <= l; + _Bool d = k == l; + return c ^ d; // k < l +} +/* { dg-final { scan-tree-dump "k_\[0-9\]+.D. < l_\[0-9\]+.D.|l_\[0-9\]+.D. > k_\[0-9\]+.D." "optimized" } } */ + +_Bool lenexor(float m, float n) +{ + _Bool c = m <= n; + _Bool d = m != n; + return c ^ d; // m u>= n +} +/* { dg-final { scan-tree-dump "m_\[0-9\]+.D. u>= n_\[0-9\]+.D.|n_\[0-9\]+.D. u<= m_\[0-9\]+.D." "optimized" } } */ -- 2.43.0