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:
parent
cfed37a03b
commit
a8fc257951
7 changed files with 90 additions and 52 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
52
gcc/match.pd
52
gcc/match.pd
|
@ -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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue