From 130c4034c732fae5196f02fe4248fb1a5a602276 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 16 Sep 2019 16:22:50 +0200 Subject: [PATCH] Rewrite first part of or_comparisons_1 into match.pd. 2019-09-16 Martin Liska * gimple-fold.c (or_comparisons_1): Remove rules moved to ... * match.pd: ... here. From-SVN: r275751 --- gcc/ChangeLog | 6 ++++ gcc/gimple-fold.c | 87 +---------------------------------------------- gcc/match.pd | 28 +++++++++++++++ 3 files changed, 35 insertions(+), 86 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc3a397d7c1..e70e09070c9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-09-16 Martin Liska + + * gimple-fold.c (or_comparisons_1): Remove rules + moved to ... + * match.pd: ... here. + 2019-09-16 Martin Liska * genmatch.c (dt_node::append_simplify): Do not print diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index f82bedc6593..694d2eeaae6 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -6050,93 +6050,8 @@ or_comparisons_1 (tree type, enum tree_code code1, tree op1a, tree op1b, { int cmp = tree_int_cst_compare (op1b, op2b); - /* If we have (op1a != op1b), we should either be able to - return that or TRUE, depending on whether the constant op1b - also satisfies the other comparison against op2b. */ - if (code1 == NE_EXPR) - { - bool done = true; - bool val; - switch (code2) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp < 0); break; - case GT_EXPR: val = (cmp > 0); break; - case LE_EXPR: val = (cmp <= 0); break; - case GE_EXPR: val = (cmp >= 0); break; - default: done = false; - } - if (done) - { - if (val) - return boolean_true_node; - else - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - } - /* Likewise if the second comparison is a != comparison. */ - else if (code2 == NE_EXPR) - { - bool done = true; - bool val; - switch (code1) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp > 0); break; - case GT_EXPR: val = (cmp < 0); break; - case LE_EXPR: val = (cmp >= 0); break; - case GE_EXPR: val = (cmp <= 0); break; - default: done = false; - } - if (done) - { - if (val) - return boolean_true_node; - else - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - } - - /* See if an equality test is redundant with the other comparison. */ - else if (code1 == EQ_EXPR) - { - bool val; - switch (code2) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp < 0); break; - case GT_EXPR: val = (cmp > 0); break; - case LE_EXPR: val = (cmp <= 0); break; - case GE_EXPR: val = (cmp >= 0); break; - default: - val = false; - } - if (val) - return fold_build2 (code2, boolean_type_node, op2a, op2b); - } - else if (code2 == EQ_EXPR) - { - bool val; - switch (code1) - { - case EQ_EXPR: val = (cmp == 0); break; - case NE_EXPR: val = (cmp != 0); break; - case LT_EXPR: val = (cmp > 0); break; - case GT_EXPR: val = (cmp < 0); break; - case LE_EXPR: val = (cmp >= 0); break; - case GE_EXPR: val = (cmp <= 0); break; - default: - val = false; - } - if (val) - return fold_build2 (code1, boolean_type_node, op1a, op1b); - } - /* Chose the less restrictive of two < or <= comparisons. */ - else if ((code1 == LT_EXPR || code1 == LE_EXPR) + if ((code1 == LT_EXPR || code1 == LE_EXPR) && (code2 == LT_EXPR || code2 == LE_EXPR)) { if ((cmp < 0) || (cmp == 0 && code1 == LT_EXPR)) diff --git a/gcc/match.pd b/gcc/match.pd index ac80dd7dd15..c465eabbb89 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2024,6 +2024,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) { constant_boolean_node (false, type); }) ))))) +/* Convert (X == CST1) || (X OP2 CST2) to a known value + based on CST1 OP2 CST2. Similarly for (X != CST1). */ + +(for code1 (eq ne) + (for code2 (eq ne lt gt le ge) + (simplify + (bit_ior:c (code1@3 @0 INTEGER_CST@1) (code2@4 @0 INTEGER_CST@2)) + (with + { + int cmp = tree_int_cst_compare (@1, @2); + bool val; + switch (code2) + { + case EQ_EXPR: val = (cmp == 0); break; + case NE_EXPR: val = (cmp != 0); break; + case LT_EXPR: val = (cmp < 0); break; + case GT_EXPR: val = (cmp > 0); break; + case LE_EXPR: val = (cmp <= 0); break; + case GE_EXPR: val = (cmp >= 0); break; + default: gcc_unreachable (); + } + } + (switch + (if (code1 == EQ_EXPR && val) @4) + (if (code1 == NE_EXPR && val) { constant_boolean_node (true, type); }) + (if (code1 == NE_EXPR && !val) @3)))))) + + /* We can't reassociate at all for saturating types. */ (if (!TYPE_SATURATING (type)) -- 2.30.2