fold-const.c (fold_addr_of_array_ref_difference): Properly convert operands before folding a MINUS_EXPR.

2015-10-22  Richard Biener  <rguenther@suse.de>

	* fold-const.c (fold_addr_of_array_ref_difference): Properly
	convert operands before folding a MINUS_EXPR.
	(fold_binary_loc): Move simplification of MINUS_EXPR on
	converted POINTER_PLUS_EXPRs ...
	* match.pd: ... here.

	c/
	* c-typeck.c (c_finish_omp_clauses): Properly convert operands
	before folding a MINUS_EXPR.

	cp/
	* semantics.c (cp_finish_omp_clause_depend_sink): Properly convert
	before folding a MINUS_EXPR.
	(finish_omp_clauses): Likewise.

From-SVN: r229167
This commit is contained in:
Richard Biener 2015-10-22 08:38:15 +00:00 committed by Richard Biener
parent cfed37a03b
commit a8fc257951
7 changed files with 90 additions and 52 deletions

View File

@ -1,3 +1,11 @@
2015-10-22 Richard Biener <rguenther@suse.de>
* fold-const.c (fold_addr_of_array_ref_difference): Properly
convert operands before folding a MINUS_EXPR.
(fold_binary_loc): Move simplification of MINUS_EXPR on
converted POINTER_PLUS_EXPRs ...
* match.pd: ... here.
2015-10-22 Richard Sandiford <richard.sandiford@arm.com>
* builtins.c (fold_builtin_tan): Delete.

View File

@ -1,3 +1,8 @@
2015-10-22 Richard Biener <rguenther@suse.de>
* c-typeck.c (c_finish_omp_clauses): Properly convert operands
before folding a MINUS_EXPR.
2015-10-21 Marek Polacek <polacek@redhat.com>
PR c/68024

View File

@ -12547,7 +12547,9 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd)
s = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
OMP_CLAUSE_DECL (c), s);
s = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
sizetype, s, OMP_CLAUSE_DECL (c));
sizetype, fold_convert (sizetype, s),
fold_convert
(sizetype, OMP_CLAUSE_DECL (c)));
if (s == error_mark_node)
s = size_one_node;
OMP_CLAUSE_LINEAR_STEP (c) = s;
@ -12671,7 +12673,9 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd)
neg ? MINUS_EXPR : PLUS_EXPR,
decl, offset);
t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (c), MINUS_EXPR,
sizetype, t2, decl);
sizetype,
fold_convert (sizetype, t2),
fold_convert (sizetype, decl));
if (t2 == error_mark_node)
{
remove = true;

View File

@ -1,3 +1,9 @@
2015-10-22 Richard Biener <rguenther@suse.de>
* semantics.c (cp_finish_omp_clause_depend_sink): Properly convert
before folding a MINUS_EXPR.
(finish_omp_clauses): Likewise.
2015-10-21 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/66781

View File

@ -5632,8 +5632,9 @@ cp_finish_omp_clause_depend_sink (tree sink_clause)
neg ? MINUS_EXPR : PLUS_EXPR,
decl, offset);
t2 = fold_build2_loc (OMP_CLAUSE_LOCATION (sink_clause),
MINUS_EXPR, sizetype, t2,
decl);
MINUS_EXPR, sizetype,
fold_convert (sizetype, t2),
fold_convert (sizetype, decl));
if (t2 == error_mark_node)
return true;
TREE_PURPOSE (t) = t2;
@ -5783,7 +5784,9 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
d, t);
t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
MINUS_EXPR, sizetype, t, d);
MINUS_EXPR, sizetype,
fold_convert (sizetype, t),
fold_convert (sizetype, d));
if (t == error_mark_node)
{
remove = true;
@ -5804,7 +5807,9 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd)
t = pointer_int_sum (OMP_CLAUSE_LOCATION (c), PLUS_EXPR,
d, t);
t = fold_build2_loc (OMP_CLAUSE_LOCATION (c),
MINUS_EXPR, sizetype, t, d);
MINUS_EXPR, sizetype,
fold_convert (sizetype, t),
fold_convert (sizetype, d));
if (t == error_mark_node)
{
remove = true;

View File

@ -8841,9 +8841,11 @@ fold_addr_of_array_ref_difference (location_t loc, tree type,
= fold_addr_of_array_ref_difference (loc, type, base0, base1)))
|| (INDIRECT_REF_P (base0)
&& INDIRECT_REF_P (base1)
&& (base_offset = fold_binary_loc (loc, MINUS_EXPR, type,
TREE_OPERAND (base0, 0),
TREE_OPERAND (base1, 0))))
&& (base_offset
= fold_binary_loc (loc, MINUS_EXPR, type,
fold_convert (type, TREE_OPERAND (base0, 0)),
fold_convert (type,
TREE_OPERAND (base1, 0)))))
|| operand_equal_p (base0, base1, OEP_ADDRESS_OF))
{
tree op0 = fold_convert_loc (loc, type, TREE_OPERAND (aref0, 1));
@ -9637,48 +9639,6 @@ fold_binary_loc (location_t loc,
return NULL_TREE;
case MINUS_EXPR:
/* Pointer simplifications for subtraction, simple reassociations. */
if (POINTER_TYPE_P (TREE_TYPE (arg1)) && POINTER_TYPE_P (TREE_TYPE (arg0)))
{
/* (PTR0 p+ A) - (PTR1 p+ B) -> (PTR0 - PTR1) + (A - B) */
if (TREE_CODE (arg0) == POINTER_PLUS_EXPR
&& TREE_CODE (arg1) == POINTER_PLUS_EXPR)
{
tree arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
tree arg01 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
tree arg10 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
tree arg11 = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
return fold_build2_loc (loc, PLUS_EXPR, type,
fold_build2_loc (loc, MINUS_EXPR, type,
arg00, arg10),
fold_build2_loc (loc, MINUS_EXPR, type,
arg01, arg11));
}
/* (PTR0 p+ A) - PTR1 -> (PTR0 - PTR1) + A, assuming PTR0 - PTR1 simplifies. */
else if (TREE_CODE (arg0) == POINTER_PLUS_EXPR)
{
tree arg00 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
tree arg01 = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
tree tmp = fold_binary_loc (loc, MINUS_EXPR, type, arg00,
fold_convert_loc (loc, type, arg1));
if (tmp)
return fold_build2_loc (loc, PLUS_EXPR, type, tmp, arg01);
}
/* PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A, assuming PTR0 - PTR1
simplifies. */
else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
{
tree arg10 = fold_convert_loc (loc, type,
TREE_OPERAND (arg1, 0));
tree arg11 = fold_convert_loc (loc, type,
TREE_OPERAND (arg1, 1));
tree tmp = fold_binary_loc (loc, MINUS_EXPR, type,
fold_convert_loc (loc, type, arg0),
arg10);
if (tmp)
return fold_build2_loc (loc, MINUS_EXPR, type, tmp, arg11);
}
}
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& negate_expr_p (arg1)

View File

@ -1056,7 +1056,57 @@ along with GCC; see the file COPYING3. If not see
|| (POINTER_TYPE_P (TREE_TYPE (@0))
&& TREE_CODE (@1) == INTEGER_CST
&& tree_int_cst_sign_bit (@1) == 0))
(convert @1))))))
(convert @1))))
/* (T)P - (T)(P + A) -> -(T) A */
(for add (plus pointer_plus)
(simplify
(minus (convert @0)
(convert (add @0 @1)))
(if (element_precision (type) <= element_precision (TREE_TYPE (@1))
/* For integer types, if A has a smaller type
than T the result depends on the possible
overflow in P + A.
E.g. T=size_t, A=(unsigned)429497295, P>0.
However, if an overflow in P + A would cause
undefined behavior, we can assume that there
is no overflow. */
|| (INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
/* For pointer types, if the conversion of A to the
final type requires a sign- or zero-extension,
then we have to punt - it is not defined which
one is correct. */
|| (POINTER_TYPE_P (TREE_TYPE (@0))
&& TREE_CODE (@1) == INTEGER_CST
&& tree_int_cst_sign_bit (@1) == 0))
(negate (convert @1)))))
/* (T)(P + A) - (T)(P + B) -> (T)A - (T)B */
(for add (plus pointer_plus)
(simplify
(minus (convert (add @0 @1))
(convert (add @0 @2)))
(if (element_precision (type) <= element_precision (TREE_TYPE (@1))
/* For integer types, if A has a smaller type
than T the result depends on the possible
overflow in P + A.
E.g. T=size_t, A=(unsigned)429497295, P>0.
However, if an overflow in P + A would cause
undefined behavior, we can assume that there
is no overflow. */
|| (INTEGRAL_TYPE_P (TREE_TYPE (@0))
&& TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
/* For pointer types, if the conversion of A to the
final type requires a sign- or zero-extension,
then we have to punt - it is not defined which
one is correct. */
|| (POINTER_TYPE_P (TREE_TYPE (@0))
&& TREE_CODE (@1) == INTEGER_CST
&& tree_int_cst_sign_bit (@1) == 0
&& TREE_CODE (@2) == INTEGER_CST
&& tree_int_cst_sign_bit (@2) == 0))
(minus (convert @1) (convert @2)))))))
/* Simplifications of MIN_EXPR and MAX_EXPR. */