{
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))
{ 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))