Commit 2ee05f1e by Richard Biener Committed by Richard Biener

fold-const.c (fold_comparison): Move X - Y CMP 0 -> X CMP Y...

2015-07-01  Richard Biener  <rguenther@suse.de>

	* fold-const.c (fold_comparison): Move X - Y CMP 0 -> X CMP Y,
	X * C1 CMP 0 -> X CMP 0, X CMP X, ~X CMP ~Y -> Y CMP X and
	~X CMP C -> X CMP' ~C to ...
	* match.pd: ... patterns here.

From-SVN: r225249
parent e09abfa4
2015-07-01 Richard Biener <rguenther@suse.de>
* fold-const.c (fold_comparison): Move X - Y CMP 0 -> X CMP Y,
X * C1 CMP 0 -> X CMP 0, X CMP X, ~X CMP ~Y -> Y CMP X and
~X CMP C -> X CMP' ~C to ...
* match.pd: ... patterns here.
2015-07-01 Nick Clifton <nickc@redhat.com> 2015-07-01 Nick Clifton <nickc@redhat.com>
* config/msp430/msp430.md (zero_extendhipsi2): Use MOVX.A to store * config/msp430/msp430.md (zero_extendhipsi2): Use MOVX.A to store
......
...@@ -8783,23 +8783,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -8783,23 +8783,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
} }
} }
/* 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 /* For comparisons of pointers we can decompose it to a compile time
comparison of the base objects and the offsets into the object. comparison of the base objects and the offsets into the object.
This requires at least one operand being an ADDR_EXPR or a This requires at least one operand being an ADDR_EXPR or a
...@@ -9088,38 +9071,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -9088,38 +9071,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
} }
} }
/* 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); tem = maybe_canonicalize_comparison (loc, code, type, arg0, arg1);
if (tem) if (tem)
return tem; return tem;
...@@ -9241,40 +9192,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -9241,40 +9192,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
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 /* If we are comparing an expression that just has comparisons
of two integer values, arithmetic expressions of those comparisons, of two integer values, arithmetic expressions of those comparisons,
and constants, we can simplify it. There are only three cases and constants, we can simplify it. There are only three cases
...@@ -9392,28 +9309,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type, ...@@ -9392,28 +9309,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
return tem; 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; return NULL_TREE;
} }
......
...@@ -1262,6 +1262,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -1262,6 +1262,7 @@ along with GCC; see the file COPYING3. If not see
== TYPE_MODE (TREE_TYPE (TREE_TYPE (@0))))) == TYPE_MODE (TREE_TYPE (TREE_TYPE (@0)))))
(plus @3 (view_convert @0)))) (plus @3 (view_convert @0))))
/* Simplifications of comparisons. */ /* Simplifications of comparisons. */
/* We can simplify a logical negation of a comparison to the /* We can simplify a logical negation of a comparison to the
...@@ -1299,6 +1300,68 @@ along with GCC; see the file COPYING3. If not see ...@@ -1299,6 +1300,68 @@ along with GCC; see the file COPYING3. If not see
(if (ic == ncmp) (if (ic == ncmp)
(ncmp @0 @1))))) (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. */ /* Unordered tests if either argument is a NaN. */
(simplify (simplify
(bit_ior (unordered @0 @0) (unordered @1 @1)) (bit_ior (unordered @0 @0) (unordered @1 @1))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment