}
}
- /* Transform comparisons of the form X - Y CMP 0 to X CMP Y. */
- if (TREE_CODE (arg0) == MINUS_EXPR
- && equality_code
- && integer_zerop (arg1))
- {
- /* ??? The transformation is valid for the other operators if overflow
- is undefined for the type, but performing it here badly interacts
- with the transformation in fold_cond_expr_with_comparison which
- attempts to synthetize ABS_EXPR. */
- if (!equality_code)
- fold_overflow_warning ("assuming signed overflow does not occur "
- "when changing X - Y cmp 0 to X cmp Y",
- WARN_STRICT_OVERFLOW_COMPARISON);
- return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg0, 1));
- }
-
/* For comparisons of pointers we can decompose it to a compile time
comparison of the base objects and the offsets into the object.
This requires at least one operand being an ADDR_EXPR or a
}
}
- /* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the
- signed arithmetic case. That form is created by the compiler
- often enough for folding it to be of value. One example is in
- computing loop trip counts after Operator Strength Reduction. */
- if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
- && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))
- && TREE_CODE (arg0) == MULT_EXPR
- && (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
- && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1)))
- && integer_zerop (arg1))
- {
- tree const1 = TREE_OPERAND (arg0, 1);
- tree const2 = arg1; /* zero */
- tree variable1 = TREE_OPERAND (arg0, 0);
- enum tree_code cmp_code = code;
-
- /* Handle unfolded multiplication by zero. */
- if (integer_zerop (const1))
- return fold_build2_loc (loc, cmp_code, type, const1, const2);
-
- fold_overflow_warning (("assuming signed overflow does not occur when "
- "eliminating multiplication in comparison "
- "with zero"),
- WARN_STRICT_OVERFLOW_COMPARISON);
-
- /* If const1 is negative we swap the sense of the comparison. */
- if (tree_int_cst_sgn (const1) < 0)
- cmp_code = swap_tree_comparison (cmp_code);
-
- return fold_build2_loc (loc, cmp_code, type, variable1, const2);
- }
-
tem = maybe_canonicalize_comparison (loc, code, type, arg0, arg1);
if (tem)
return tem;
return tem;
}
- /* Simplify comparison of something with itself. (For IEEE
- floating-point, we can only do some of these simplifications.) */
- if (operand_equal_p (arg0, arg1, 0))
- {
- switch (code)
- {
- case EQ_EXPR:
- if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
- || ! HONOR_NANS (arg0))
- return constant_boolean_node (1, type);
- break;
-
- case GE_EXPR:
- case LE_EXPR:
- if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
- || ! HONOR_NANS (arg0))
- return constant_boolean_node (1, type);
- return fold_build2_loc (loc, EQ_EXPR, type, arg0, arg1);
-
- case NE_EXPR:
- /* For NE, we can only do this simplification if integer
- or we don't honor IEEE floating point NaNs. */
- if (FLOAT_TYPE_P (TREE_TYPE (arg0))
- && HONOR_NANS (arg0))
- break;
- /* ... fall through ... */
- case GT_EXPR:
- case LT_EXPR:
- return constant_boolean_node (0, type);
- default:
- gcc_unreachable ();
- }
- }
-
/* If we are comparing an expression that just has comparisons
of two integer values, arithmetic expressions of those comparisons,
and constants, we can simplify it. There are only three cases
return tem;
}
- /* Fold ~X op ~Y as Y op X. */
- if (TREE_CODE (arg0) == BIT_NOT_EXPR
- && TREE_CODE (arg1) == BIT_NOT_EXPR)
- {
- tree cmp_type = TREE_TYPE (TREE_OPERAND (arg0, 0));
- return fold_build2_loc (loc, code, type,
- fold_convert_loc (loc, cmp_type,
- TREE_OPERAND (arg1, 0)),
- TREE_OPERAND (arg0, 0));
- }
-
- /* Fold ~X op C as X op' ~C, where op' is the swapped comparison. */
- if (TREE_CODE (arg0) == BIT_NOT_EXPR
- && (TREE_CODE (arg1) == INTEGER_CST || TREE_CODE (arg1) == VECTOR_CST))
- {
- tree cmp_type = TREE_TYPE (TREE_OPERAND (arg0, 0));
- return fold_build2_loc (loc, swap_tree_comparison (code), type,
- TREE_OPERAND (arg0, 0),
- fold_build1_loc (loc, BIT_NOT_EXPR, cmp_type,
- fold_convert_loc (loc, cmp_type, arg1)));
- }
-
return NULL_TREE;
}
== TYPE_MODE (TREE_TYPE (TREE_TYPE (@0)))))
(plus @3 (view_convert @0))))
+
/* Simplifications of comparisons. */
/* We can simplify a logical negation of a comparison to the
(if (ic == ncmp)
(ncmp @0 @1)))))
+/* Transform comparisons of the form X - Y CMP 0 to X CMP Y.
+ ??? The transformation is valid for the other operators if overflow
+ is undefined for the type, but performing it here badly interacts
+ with the transformation in fold_cond_expr_with_comparison which
+ attempts to synthetize ABS_EXPR. */
+(for cmp (eq ne)
+ (simplify
+ (cmp (minus @0 @1) integer_zerop)
+ (cmp @0 @1)))
+
+/* Transform comparisons of the form X * C1 CMP 0 to X CMP 0 in the
+ signed arithmetic case. That form is created by the compiler
+ often enough for folding it to be of value. One example is in
+ computing loop trip counts after Operator Strength Reduction. */
+(for cmp (tcc_comparison)
+ scmp (swapped_tcc_comparison)
+ (simplify
+ (cmp (mult @0 INTEGER_CST@1) integer_zerop@2)
+ /* Handle unfolded multiplication by zero. */
+ (if (integer_zerop (@1))
+ (cmp @1 @2))
+ (if (ANY_INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+ /* If @1 is negative we swap the sense of the comparison. */
+ (if (tree_int_cst_sgn (@1) < 0)
+ (scmp @0 @2))
+ (cmp @0 @2))))
+
+/* Simplify comparison of something with itself. For IEEE
+ floating-point, we can only do some of these simplifications. */
+(simplify
+ (eq @0 @0)
+ (if (! FLOAT_TYPE_P (TREE_TYPE (@0))
+ || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (@0))))
+ { constant_boolean_node (true, type); }))
+(for cmp (ge le)
+ (simplify
+ (cmp @0 @0)
+ (eq @0 @0)))
+(for cmp (ne gt lt)
+ (simplify
+ (cmp @0 @0)
+ (if (cmp != NE_EXPR
+ || ! FLOAT_TYPE_P (TREE_TYPE (@0))
+ || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (@0))))
+ { constant_boolean_node (false, type); })))
+
+/* Fold ~X op ~Y as Y op X. */
+(for cmp (tcc_comparison)
+ (simplify
+ (cmp (bit_not @0) (bit_not @1))
+ (cmp @1 @0)))
+
+/* Fold ~X op C as X op' ~C, where op' is the swapped comparison. */
+(for cmp (tcc_comparison)
+ scmp (swapped_tcc_comparison)
+ (simplify
+ (cmp (bit_not @0) CONSTANT_CLASS_P@1)
+ (if (TREE_CODE (@1) == INTEGER_CST || TREE_CODE (@1) == VECTOR_CST)
+ (scmp @0 (bit_not @1)))))
+
+
/* Unordered tests if either argument is a NaN. */
(simplify
(bit_ior (unordered @0 @0) (unordered @1 @1))