mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-25 10:30:45 +08:00
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
This commit is contained in:
parent
ae9c350782
commit
130c4034c7
@ -1,3 +1,9 @@
|
||||
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
|
||||
|
@ -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))
|
||||
|
28
gcc/match.pd
28
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))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user