Commit 044331a8 by Marek Polacek Committed by Marek Polacek

fold-const.c (fold_binary_loc): Add folding of (PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A.

	* fold-const.c (fold_binary_loc): Add folding of 
	(PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A.
c/
	* c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
testsuite/
	* gcc.dg/fold-reassoc-3.c: New test.

From-SVN: r213700
parent ce597aed
2014-08-07 Marek Polacek <polacek@redhat.com>
* fold-const.c (fold_binary_loc): Add folding of
(PTR0 - (PTR1 p+ A) -> (PTR0 - PTR1) - A.
2013-08-07 Ilya Enkovich <ilya.enkovich@intel.com> 2013-08-07 Ilya Enkovich <ilya.enkovich@intel.com>
* config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use decl size * config/elfos.h (ASM_DECLARE_OBJECT_NAME): Use decl size
......
2014-08-07 Marek Polacek <polacek@redhat.com>
* c-typeck.c (pointer_diff): Remove P - (P + CST) optimization.
2014-08-02 Trevor Saunders <tsaunders@mozilla.com> 2014-08-02 Trevor Saunders <tsaunders@mozilla.com>
* c-typeck.c: Use hash_map instead of pointer_map. * c-typeck.c: Use hash_map instead of pointer_map.
......
...@@ -3460,7 +3460,6 @@ pointer_diff (location_t loc, tree op0, tree op1) ...@@ -3460,7 +3460,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0))); addr_space_t as0 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op0)));
addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1))); addr_space_t as1 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (op1)));
tree target_type = TREE_TYPE (TREE_TYPE (op0)); tree target_type = TREE_TYPE (TREE_TYPE (op0));
tree con0, con1, lit0, lit1;
tree orig_op1 = op1; tree orig_op1 = op1;
/* If the operands point into different address spaces, we need to /* If the operands point into different address spaces, we need to
...@@ -3490,7 +3489,6 @@ pointer_diff (location_t loc, tree op0, tree op1) ...@@ -3490,7 +3489,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
else else
inttype = restype; inttype = restype;
if (TREE_CODE (target_type) == VOID_TYPE) if (TREE_CODE (target_type) == VOID_TYPE)
pedwarn (loc, OPT_Wpointer_arith, pedwarn (loc, OPT_Wpointer_arith,
"pointer of type %<void *%> used in subtraction"); "pointer of type %<void *%> used in subtraction");
...@@ -3498,50 +3496,6 @@ pointer_diff (location_t loc, tree op0, tree op1) ...@@ -3498,50 +3496,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
pedwarn (loc, OPT_Wpointer_arith, pedwarn (loc, OPT_Wpointer_arith,
"pointer to a function used in subtraction"); "pointer to a function used in subtraction");
/* If the conversion to ptrdiff_type does anything like widening or
converting a partial to an integral mode, we get a convert_expression
that is in the way to do any simplifications.
(fold-const.c doesn't know that the extra bits won't be needed.
split_tree uses STRIP_SIGN_NOPS, which leaves conversions to a
different mode in place.)
So first try to find a common term here 'by hand'; we want to cover
at least the cases that occur in legal static initializers. */
if (CONVERT_EXPR_P (op0)
&& (TYPE_PRECISION (TREE_TYPE (op0))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))))
con0 = TREE_OPERAND (op0, 0);
else
con0 = op0;
if (CONVERT_EXPR_P (op1)
&& (TYPE_PRECISION (TREE_TYPE (op1))
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))))
con1 = TREE_OPERAND (op1, 0);
else
con1 = op1;
if (TREE_CODE (con0) == POINTER_PLUS_EXPR)
{
lit0 = TREE_OPERAND (con0, 1);
con0 = TREE_OPERAND (con0, 0);
}
else
lit0 = integer_zero_node;
if (TREE_CODE (con1) == POINTER_PLUS_EXPR)
{
lit1 = TREE_OPERAND (con1, 1);
con1 = TREE_OPERAND (con1, 0);
}
else
lit1 = integer_zero_node;
if (operand_equal_p (con0, con1, 0))
{
op0 = lit0;
op1 = lit1;
}
/* First do the subtraction as integers; /* First do the subtraction as integers;
then drop through to build the divide operator. then drop through to build the divide operator.
Do not do default conversions on the minus operator Do not do default conversions on the minus operator
......
...@@ -10831,6 +10831,19 @@ fold_binary_loc (location_t loc, ...@@ -10831,6 +10831,19 @@ fold_binary_loc (location_t loc,
if (tmp) if (tmp)
return fold_build2_loc (loc, PLUS_EXPR, type, tmp, arg01); 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, arg0,
fold_convert_loc (loc, type, arg10));
if (tmp)
return fold_build2_loc (loc, MINUS_EXPR, type, tmp, arg11);
}
} }
/* A - (-B) -> A + B */ /* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR) if (TREE_CODE (arg1) == NEGATE_EXPR)
......
2014-08-07 Marek Polacek <polacek@redhat.com>
* gcc.dg/fold-reassoc-3.c: New test.
2013-08-07 Ilya Enkovich <ilya.enkovich@intel.com> 2013-08-07 Ilya Enkovich <ilya.enkovich@intel.com>
* gcc.target/i386/struct-size.c: New. * gcc.target/i386/struct-size.c: New.
......
/* { dg-do compile } */
/* { dg-options "-fdump-tree-original" } */
int i;
int *p = &i;
static __PTRDIFF_TYPE__ d = p - (p + 1);
void
foo (void)
{
int *q = &i;
static __PTRDIFF_TYPE__ e = q - (q + 1);
}
/* { dg-final { scan-tree-dump-not " - " "original" } } */
/* { dg-final { scan-tree-dump-not " \\\+ " "original" } } */
/* { dg-final { cleanup-tree-dump "orginal" } } */
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