aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2019-09-16 16:22:50 +0200
committerMartin Liska <marxin@gcc.gnu.org>2019-09-16 14:22:50 +0000
commit130c4034c732fae5196f02fe4248fb1a5a602276 (patch)
tree088f417550125e1cdfb40c14a47ae2d9cd696f73
parentae9c3507829ca139749ac3f9cf4a78707a036d3b (diff)
downloadgcc-130c4034c732fae5196f02fe4248fb1a5a602276.zip
gcc-130c4034c732fae5196f02fe4248fb1a5a602276.tar.gz
gcc-130c4034c732fae5196f02fe4248fb1a5a602276.tar.bz2
Rewrite first part of or_comparisons_1 into match.pd.
2019-09-16 Martin Liska <mliska@suse.cz> * gimple-fold.c (or_comparisons_1): Remove rules moved to ... * match.pd: ... here. From-SVN: r275751
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimple-fold.c87
-rw-r--r--gcc/match.pd28
3 files changed, 35 insertions, 86 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc3a397..e70e090 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
2019-09-16 Martin Liska <mliska@suse.cz>
+ * gimple-fold.c (or_comparisons_1): Remove rules
+ moved to ...
+ * match.pd: ... here.
+
+2019-09-16 Martin Liska <mliska@suse.cz>
+
* genmatch.c (dt_node::append_simplify): Do not print
warning when we have duplicate patterns belonging
to a same simplify rule.
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index f82bedc..694d2ee 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 ac80dd7..c465eab 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))